From 3a0041b2cb0ac93493b0d09028fd7a6aa000ce25 Mon Sep 17 00:00:00 2001 From: "jk7744.park" Date: Sun, 1 Feb 2015 13:07:33 +0900 Subject: [PATCH] tizen 2.3 release --- CMakeLists.txt | 95 +- TC/testcase/Makefile | 27 - TC/testcase/tslist | 2 - TC/testcase/utc_livebox_viewer | Bin 247137 -> 0 bytes TC/testcase/utc_livebox_viewer.c | 2456 ---------- doc/livebox-viewer_doc.h | 125 - dynamicbox_viewer/CMakeLists.txt | 98 + LICENSE => dynamicbox_viewer/LICENSE | 0 dynamicbox_viewer/doc/dynamicbox_viewer_doc.h | 197 + {doc => dynamicbox_viewer/doc}/image/PD.png | Bin .../doc}/image/download_folder.png | Bin {doc => dynamicbox_viewer/doc}/image/front.jpg | Bin .../doc}/image/image_format.png | Bin {doc => dynamicbox_viewer/doc}/image/message.png | Bin .../doc}/image/preload_folder.png | Bin .../doc}/image/script_format.png | Bin {doc => dynamicbox_viewer/doc}/image/stock.png | Bin .../doc}/image/text_format.png | Bin {doc => dynamicbox_viewer/doc}/image/twitter.png | Bin {doc => dynamicbox_viewer/doc}/image/weather.png | Bin dynamicbox_viewer/dynamicbox_viewer.pc.in | 12 + {include => dynamicbox_viewer/include}/client.h | 2 + {include => dynamicbox_viewer/include}/conf.h | 14 +- {include => dynamicbox_viewer/include}/debug.h | 4 +- .../include}/desc_parser.h | 2 +- {live.viewer => dynamicbox_viewer}/include/dlist.h | 14 +- dynamicbox_viewer/include/dynamicbox.h | 1675 +++++++ dynamicbox_viewer/include/dynamicbox_internal.h | 270 ++ {include => dynamicbox_viewer/include}/fb.h | 9 +- .../include}/file_service.h | 0 .../include}/master_rpc.h | 4 +- {include => dynamicbox_viewer/include}/util.h | 7 +- dynamicbox_viewer/src/client.c | 2296 +++++++++ dynamicbox_viewer/src/conf.c | 82 + dynamicbox_viewer/src/desc_parser.c | 698 +++ dynamicbox_viewer/src/dlist.c | 189 + dynamicbox_viewer/src/dynamicbox.c | 4115 +++++++++++++++++ dynamicbox_viewer/src/dynamicbox_internal.c | 1058 +++++ dynamicbox_viewer/src/fb.c | 674 +++ dynamicbox_viewer/src/fb_wayland.c | 451 ++ dynamicbox_viewer/src/file_service.c | 715 +++ dynamicbox_viewer/src/master_rpc.c | 318 ++ dynamicbox_viewer/src/util.c | 150 + include/dlist.h | 43 - include/livebox.h | 1753 ------- include/livebox_internal.h | 255 - live.viewer/CMakeLists.txt | 48 - live.viewer/image/folder | 0 live.viewer/include/debug.h | 27 - live.viewer/include/lb.h | 21 - live.viewer/include/live_scroller.h | 57 - live.viewer/include/main.h | 17 - live.viewer/include/scroller.h | 44 - live.viewer/include/util.h | 19 - live.viewer/live.viewer.xml | 12 - live.viewer/packaging/live.viewer.spec | 41 - live.viewer/res/CMakeLists.txt | 7 - live.viewer/res/live-viewer.edc | 175 - live.viewer/src/dlist.c | 180 - live.viewer/src/lb.c | 966 ---- live.viewer/src/live_scroller.c | 1457 ------ live.viewer/src/main.c | 189 - live.viewer/src/scroller.c | 524 --- live.viewer/src/util.c | 43 - livebox-viewer/CMakeLists.txt | 55 + livebox-viewer/LICENSE | 206 + livebox-viewer/include/livebox.h | 1471 ++++++ .../livebox-viewer.pc.in | 1 + livebox-viewer/src/livebox.c | 595 +++ ...ewer.manifest => libdynamicbox_viewer.manifest} | 0 packaging/libdynamicbox_viewer.spec | 123 + packaging/liblivebox-viewer.spec | 91 - src/client.c | 1770 ------- src/conf.c | 57 - src/desc_parser.c | 697 --- src/dlist.c | 189 - src/fb.c | 622 --- src/fb_wayland.c | 447 -- src/file_service.c | 715 --- src/livebox.c | 4885 -------------------- src/master_rpc.c | 317 -- src/util.c | 214 - 82 files changed, 15480 insertions(+), 18612 deletions(-) delete mode 100644 TC/testcase/Makefile delete mode 100644 TC/testcase/tslist delete mode 100755 TC/testcase/utc_livebox_viewer delete mode 100644 TC/testcase/utc_livebox_viewer.c delete mode 100644 doc/livebox-viewer_doc.h create mode 100644 dynamicbox_viewer/CMakeLists.txt rename LICENSE => dynamicbox_viewer/LICENSE (100%) create mode 100644 dynamicbox_viewer/doc/dynamicbox_viewer_doc.h rename {doc => dynamicbox_viewer/doc}/image/PD.png (100%) rename {doc => dynamicbox_viewer/doc}/image/download_folder.png (100%) rename {doc => dynamicbox_viewer/doc}/image/front.jpg (100%) rename {doc => dynamicbox_viewer/doc}/image/image_format.png (100%) rename {doc => dynamicbox_viewer/doc}/image/message.png (100%) rename {doc => dynamicbox_viewer/doc}/image/preload_folder.png (100%) rename {doc => dynamicbox_viewer/doc}/image/script_format.png (100%) rename {doc => dynamicbox_viewer/doc}/image/stock.png (100%) rename {doc => dynamicbox_viewer/doc}/image/text_format.png (100%) rename {doc => dynamicbox_viewer/doc}/image/twitter.png (100%) rename {doc => dynamicbox_viewer/doc}/image/weather.png (100%) create mode 100644 dynamicbox_viewer/dynamicbox_viewer.pc.in rename {include => dynamicbox_viewer/include}/client.h (90%) rename {include => dynamicbox_viewer/include}/conf.h (71%) rename {include => dynamicbox_viewer/include}/debug.h (89%) rename {include => dynamicbox_viewer/include}/desc_parser.h (87%) rename {live.viewer => dynamicbox_viewer}/include/dlist.h (81%) create mode 100644 dynamicbox_viewer/include/dynamicbox.h create mode 100644 dynamicbox_viewer/include/dynamicbox_internal.h rename {include => dynamicbox_viewer/include}/fb.h (85%) rename {include => dynamicbox_viewer/include}/file_service.h (100%) rename {include => dynamicbox_viewer/include}/master_rpc.h (74%) rename {include => dynamicbox_viewer/include}/util.h (87%) create mode 100644 dynamicbox_viewer/src/client.c create mode 100644 dynamicbox_viewer/src/conf.c create mode 100644 dynamicbox_viewer/src/desc_parser.c create mode 100644 dynamicbox_viewer/src/dlist.c create mode 100644 dynamicbox_viewer/src/dynamicbox.c create mode 100644 dynamicbox_viewer/src/dynamicbox_internal.c create mode 100644 dynamicbox_viewer/src/fb.c create mode 100644 dynamicbox_viewer/src/fb_wayland.c create mode 100644 dynamicbox_viewer/src/file_service.c create mode 100644 dynamicbox_viewer/src/master_rpc.c create mode 100644 dynamicbox_viewer/src/util.c delete mode 100644 include/dlist.h delete mode 100644 include/livebox.h delete mode 100644 include/livebox_internal.h delete mode 100644 live.viewer/CMakeLists.txt delete mode 100644 live.viewer/image/folder delete mode 100644 live.viewer/include/debug.h delete mode 100644 live.viewer/include/lb.h delete mode 100644 live.viewer/include/live_scroller.h delete mode 100644 live.viewer/include/main.h delete mode 100644 live.viewer/include/scroller.h delete mode 100644 live.viewer/include/util.h delete mode 100644 live.viewer/live.viewer.xml delete mode 100644 live.viewer/packaging/live.viewer.spec delete mode 100644 live.viewer/res/CMakeLists.txt delete mode 100644 live.viewer/res/live-viewer.edc delete mode 100644 live.viewer/src/dlist.c delete mode 100644 live.viewer/src/lb.c delete mode 100644 live.viewer/src/live_scroller.c delete mode 100644 live.viewer/src/main.c delete mode 100644 live.viewer/src/scroller.c delete mode 100644 live.viewer/src/util.c create mode 100644 livebox-viewer/CMakeLists.txt create mode 100644 livebox-viewer/LICENSE create mode 100644 livebox-viewer/include/livebox.h rename livebox-viewer.pc.in => livebox-viewer/livebox-viewer.pc.in (87%) create mode 100644 livebox-viewer/src/livebox.c rename packaging/{liblivebox-viewer.manifest => libdynamicbox_viewer.manifest} (100%) create mode 100644 packaging/libdynamicbox_viewer.spec delete mode 100644 packaging/liblivebox-viewer.spec delete mode 100644 src/client.c delete mode 100644 src/conf.c delete mode 100644 src/desc_parser.c delete mode 100644 src/dlist.c delete mode 100644 src/fb.c delete mode 100644 src/fb_wayland.c delete mode 100644 src/file_service.c delete mode 100644 src/livebox.c delete mode 100644 src/master_rpc.c delete mode 100644 src/util.c diff --git a/CMakeLists.txt b/CMakeLists.txt index e12dbc0..954b639 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,95 +1,6 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -PROJECT(livebox-viewer 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") +ADD_SUBDIRECTORY(dynamicbox_viewer) +ADD_SUBDIRECTORY(livebox-viewer) -SET(CMAKE_SKIP_BUILD_RPATH true) - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) - -INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED - dlog - aul - glib-2.0 - gio-2.0 - com-core - sqlite3 - db-util - livebox-service - vconf -) - -SET(BUILD_SOURCE - src/dlist.c - src/livebox.c - src/util.c - src/desc_parser.c - src/master_rpc.c - src/client.c - src/file_service.c - src/conf.c -) - -IF (X11_SUPPORT) -pkg_check_modules(pkgs_extra REQUIRED - x11 - xext -) - -SET(BUILD_SOURCE - ${BUILD_SOURCE} - src/fb.c -) -ADD_DEFINITIONS("-DHAVE_X11") -ENDIF (X11_SUPPORT) - -IF (WAYLAND_SUPPORT) -SET(BUILD_SOURCE - ${BUILD_SOURCE} - src/fb_wayland.c -) -ADD_DEFINITIONS("-DHAVE_WAYLAND") -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 -Wall -Werror -Winline -g") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") - -ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") -ADD_DEFINITIONS("-DLOG_TAG=\"LIVEBOX_VIEWER\"") -ADD_DEFINITIONS("-DNDEBUG") -ADD_DEFINITIONS("-D_USE_ECORE_TIME_GET") -#ADD_DEFINITIONS("-DFLOG") -ADD_DEFINITIONS("-DMASTER_PKGNAME=\"data-provider-master\"") -ADD_DEFINITIONS("-DINFO_SOCKET=\"/opt/usr/share/live_magazine/.live.socket\"") -ADD_DEFINITIONS("-DCLIENT_SOCKET=\"/opt/usr/share/live_magazine/.client.socket\"") -ADD_DEFINITIONS("-DSLAVE_SOCKET=\"/opt/usr/share/live_magazine/.slave.socket\"") -ADD_DEFINITIONS("-DSERVICE_SOCKET=\"/opt/usr/share/live_magazine/.service.socket\"") -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_DEPENDENCIES(livebox-viewer dynamicbox_viewer) diff --git a/TC/testcase/Makefile b/TC/testcase/Makefile deleted file mode 100644 index 79b2c02..0000000 --- a/TC/testcase/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -include ../config - -CC ?= gcc - -C_FILES = $(shell ls *.c) - -PKGS = $(PKG_NAME) -PKGS += glib-2.0 -PKGS += livebox-service -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 += -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 deleted file mode 100644 index 51eca81..0000000 --- a/TC/testcase/tslist +++ /dev/null @@ -1,2 +0,0 @@ -/testcase/utc_livebox_viewer - diff --git a/TC/testcase/utc_livebox_viewer b/TC/testcase/utc_livebox_viewer deleted file mode 100755 index 1f2437903f18a889bc6a4410e84ef7062c98c782..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 247137 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 z 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%0DcO{H=-ojqnt^L|#tn_g;7raxLG7 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 diff --git a/TC/testcase/utc_livebox_viewer.c b/TC/testcase/utc_livebox_viewer.c deleted file mode 100644 index 160cb38..0000000 --- a/TC/testcase/utc_livebox_viewer.c +++ /dev/null @@ -1,2456 +0,0 @@ -/* - * 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 -#include - -#include -#include -#include - -#define MUSIC_APP "org.tizen.music-player" -#define EMAIL_APP "org.tizen.email" -#define EMAIL_LIVEBOX EMAIL_APP ".livebox" -#define MUSIC_LIVEBOX MUSIC_APP ".livebox" -#define MUSIC_EASYBOX "org.tizen.music-player.easymode.livebox" - -enum { - POSITIVE_TC_IDX = 0x01, - NEGATIVE_TC_IDX, -}; - -static void startup(void) -{ - int ret; - /* start of TC */ - ret = livebox_init_with_options(NULL, 1, 0.01, 1); - tet_printf("\n TC start: ret = %d", ret); -} - - -static void cleanup(void) -{ - /* end of TC */ - tet_printf("\n TC end"); - livebox_fini(); -} - -void (*tet_startup)(void) = startup; -void (*tet_cleanup)(void) = cleanup; - -static void utc_livebox_client_paused_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_client_paused", "skip negative test"); -} - -static void utc_livebox_client_paused_p(void) -{ - int ret; - - ret = livebox_client_paused(); - dts_check_eq("livebox_client_paused", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void utc_livebox_client_resumed_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_client_resumed", "skip negative test"); -} - -static void utc_livebox_client_resumed_p(void) -{ - int ret; - - ret = livebox_client_resumed(); - dts_check_eq("livebox_client_resumed", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void create_ret_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_add", ret, LB_STATUS_SUCCESS, "Request to add a new box"); -} - -static void utc_livebox_add_p(void) -{ - struct livebox *handle; - - handle = livebox_add(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, create_ret_cb, NULL); - if (!handle) { - dts_check_ne("livebox_add", handle, NULL, "handle must not be NULL"); - } -} - -static void utc_livebox_add_n(void) -{ - struct livebox *handle; - - handle = livebox_add(NULL, NULL, NULL, NULL, -1.0f, create_ret_cb, NULL); - if (handle == NULL) { - dts_check_eq("livebox_add", handle, NULL, "Handle is NULL"); - } -} - -static void create_ret_with_size_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_add_with_size", ret, LB_STATUS_SUCCESS, "Request to add a new box with size"); -} - -static void utc_livebox_add_with_size_n(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(NULL, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, create_ret_with_size_cb, NULL); - dts_check_eq("livebox_add_with_size", handle, NULL, "Error"); -} - -static void utc_livebox_add_with_size_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, create_ret_with_size_cb, NULL); - if (!handle) { - dts_check_ne("livebox_add_with_size", handle, NULL, "Error"); - } -} - -static void utc_livebox_del_n(void) -{ - int ret; - - ret = livebox_del(NULL, NULL, NULL); - dts_check_ne("livebox_del", ret, LB_STATUS_SUCCESS, "Failed"); -} - -static void del_ret_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_del", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void create_cb_for_testing_del(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_del", ret, LB_STATUS_SUCCESS, "create failed"); - return; - } - - ret = livebox_del(handle, del_ret_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_del", ret, LB_STATUS_SUCCESS, "Success"); - } -} - -static void utc_livebox_del_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, create_cb_for_testing_del, NULL); - if (!handle) { - dts_check_ne("livebox_del", handle, NULL, "Failed to create a box"); - } -} - -static void utc_livebox_del_NEW_n(void) -{ - int ret; - - ret = livebox_del_NEW(NULL, LB_DELETE_PERMANENTLY, NULL, NULL); - dts_check_eq("livebox_del_NEW", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void del_NEW_ret_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_del_NEW", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void create_cb_for_testing_del_NEW(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_del_NEW", ret, LB_STATUS_SUCCESS, "Create failed"); - return; - } - - ret = livebox_del_NEW(handle, LB_DELETE_PERMANENTLY, del_NEW_ret_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_del_NEW", ret, LB_STATUS_SUCCESS, "Success"); - } -} - -static void utc_livebox_del_NEW_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, create_cb_for_testing_del_NEW, NULL); - if (!handle) { - dts_check_ne("livebox_del_NEW", handle, NULL, "Failed to add a new box\n"); - } -} - -static int event_handler(struct livebox *handler, enum livebox_event_type event, void *data) -{ - return 0; -} - -static void utc_livebox_set_event_handler_n(void) -{ - int ret; - - ret = livebox_set_event_handler(NULL, NULL); - dts_check_eq("livebox_set_event_handler", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void utc_livebox_set_event_handler_p(void) -{ - int ret; - - ret = livebox_set_event_handler(event_handler, (void *)123); - dts_check_eq("livebox_set_event_handler", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void utc_livebox_unset_event_handler_n(void) -{ - /*! - * \note - * Unable to unset event handler - */ - dts_pass("livebox_unset_event_handler", "skip negative test"); -} - -static void utc_livebox_unset_event_handler_p(void) -{ - void *data; - - data = livebox_unset_event_handler(event_handler); - dts_check_eq("livebox_unset_event_handler", data, (void *)123, "Unset"); -} - -static int fault_handler(enum livebox_fault_type type, const char *pkgname, const char *id, const char *func_name, void *data) -{ - return 0; -} - -static void utc_livebox_set_fault_handler_n(void) -{ - int ret; - ret = livebox_set_fault_handler(NULL, NULL); - dts_check_eq("livebox_set_fault_handler", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void utc_livebox_set_fault_handler_p(void) -{ - int ret; - ret = livebox_set_fault_handler(fault_handler, (void *)123); - dts_check_eq("livebox_set_fault_handler", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void utc_livebox_unset_fault_handler_n(void) -{ - /*! - * Unable to test negative case - */ - dts_pass("livebox_unset_fault_handler", "skip negative test"); -} - -static void utc_livebox_unset_fault_handler_p(void) -{ - void *data; - - data = livebox_unset_fault_handler(fault_handler); - dts_check_eq("livebox_unset_fault_handler", data, (void *)123, "Unset success"); -} - -static void utc_livebox_activate_n(void) -{ - int ret; - - ret = livebox_activate(NULL, NULL, NULL); - dts_check_eq("livebox_activate", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void activate_ret_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_activate", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void utc_livebox_activate_p(void) -{ - int ret; - - ret = livebox_activate(MUSIC_LIVEBOX, activate_ret_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_activate", ret, LB_STATUS_SUCCESS, "Success"); - } -} - -static void resize_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_resize", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void resize_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret == LB_STATUS_SUCCESS) { - ret = livebox_resize(handle, LB_SIZE_TYPE_2x2, resize_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_resize", ret, LB_STATUS_SUCCESS, "Success"); - } - } else { - dts_check_eq("livebox_resize", ret, LB_STATUS_SUCCESS, "resize,create,callback"); - } -} - -static void utc_livebox_resize_n(void) -{ - int ret; - ret = livebox_resize(NULL, LB_SIZE_TYPE_2x2, NULL, NULL); - dts_check_eq("livebox_resize", ret, LB_STATUS_ERROR_INVALID, "resize"); -} - -static void utc_livebox_resize_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, resize_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_resize", handle, NULL, "Resize"); - } -} - -static void utc_livebox_click_n(void) -{ - int ret; - - ret = livebox_click(NULL, 0.5f, 0.5f); - dts_check_eq("livebox_click", ret, LB_STATUS_ERROR_INVALID, "Success"); -} - -static void click_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_click", ret, LB_STATUS_SUCCESS, "click,create"); - } else { - ret = livebox_click(handle, 0.5f, 0.5f); - dts_check_eq("livebox_click", ret, LB_STATUS_SUCCESS, "click"); - } -} - -static void utc_livebox_click_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, click_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_click", handle, NULL, "click,create"); - } -} - -static void utc_livebox_set_group_n(void) -{ - int ret; - - ret = livebox_set_group(NULL, NULL, NULL, NULL, NULL); - dts_check_eq("livebox_set_group", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void set_group_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_set_group", ret, LB_STATUS_SUCCESS, "Success"); -} - -static void set_group_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_set_group", ret, LB_STATUS_SUCCESS, "set_group,create_cb"); - } else { - ret = livebox_set_group(handle, "my,cluster", "my,category", set_group_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_set_group", ret, LB_STATUS_SUCCESS, "set_group,request"); - } - } -} - -static void utc_livebox_set_group_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, set_group_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_group", handle, NULL, "create,set,group"); - } -} - -static void utc_livebox_get_group_n(void) -{ - int ret; - - ret = livebox_get_group(NULL, NULL, NULL); - dts_check_eq("livebox_get_group", ret, LB_STATUS_ERROR_INVALID, "Success"); -} - -static void get_group_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_get_group", ret, LB_STATUS_SUCCESS, "get_group,create"); - } else { - const char *cluster; - const char *category; - - ret = livebox_get_group(handle, &cluster, &category); - dts_check_eq("livebox_get_group", ret, LB_STATUS_SUCCESS, "Success"); - } -} - -static void utc_livebox_get_group_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, get_group_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_get_group", handle, NULL, "get_group,create"); - } -} - -static void utc_livebox_period_n(void) -{ - double period; - - period = livebox_period(NULL); - dts_check_eq("livebox_period", period, 0.0f, "Success"); -} - -static void period_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_period", ret, LB_STATUS_SUCCESS, "period,create"); - } else { - double period; - - period = livebox_period(handle); - dts_check_ge("livebox_period", period, 0.0f, "Success"); - } -} - -static void utc_livebox_period_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, period_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_add_with_size", handle, NULL, "livebox_add_with_size"); - } -} - -static void utc_livebox_set_period_n(void) -{ - int ret; - - ret = livebox_set_period(NULL, 20.0f, NULL, NULL); - dts_check_gt("livebox_period", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void set_period_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_period", ret, LB_STATUS_SUCCESS, "Success"); - } else { - ret = livebox_set_period(handle, 20.0f, NULL, NULL); - dts_check_eq("livebox_period", ret, LB_STATUS_SUCCESS, "Success"); - } -} - -static void utc_livebox_set_period_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, set_period_create_cb, NULL); - if (!handle) { - dts_check_eq("livebox_set_period", handle, NULL, "set_period,create"); - } -} - -static void utc_livebox_lb_type_n(void) -{ - int ret; - - ret = livebox_lb_type(NULL); - dts_check_eq("livebox_lb_type", ret, LB_TYPE_INVALID, "Success"); -} - -static void lb_type_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_lb_type", ret, LB_STATUS_SUCCESS, "lb_type,create"); - } else { - ret = livebox_lb_type(handle); - dts_check_ne("livebox_lb_type", ret, LB_TYPE_INVALID, "Success"); - } -} - -static void utc_livebox_lb_type_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, lb_type_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_lb_type", handle, NULL, "lb,type,create"); - } -} - -static void utc_livebox_is_user_n(void) -{ - int ret; - - ret = livebox_is_user(NULL); - dts_check_eq("livebox_is_user", ret, LB_STATUS_ERROR_INVALID, "Success"); -} - -static void livebox_is_user_create_cb(struct livebox *handle, int ret, void *data) -{ - return; -} - -static void utc_livebox_is_user_p(void) -{ - struct livebox *handle; - int ret; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, livebox_is_user_create_cb, NULL); - if (handle == NULL) { - dts_check_ne("livebox_is_user", handle, NULL, "handle is NULL"); - return; - } - - ret = livebox_is_user(handle); - dts_check_eq("livebox_is_user", ret, 1, "Success"); -} - -static void utc_livebox_content_n(void) -{ - const char *content; - - content = livebox_content(NULL); - dts_check_eq("livebox_content", content, NULL, "Success"); -} - -static void content_create_cb(struct livebox *handle, int ret, void *data) -{ - const char *content; - - content = livebox_content(handle); - dts_check_ne("livebox_content", content, NULL, "Success"); -} - -static void utc_livebox_content_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, content_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_content", handle, NULL, "Create for content\n"); - } -} - -static void utc_livebox_category_title_n(void) -{ - const char *title; - title = livebox_category_title(NULL); - dts_check_eq("livebox_category_title", title, NULL, "Success"); -} - -static void category_create_cb(struct livebox *handle, int ret, void *data) -{ - const char *title; - title = livebox_category_title(handle); - dts_check_ne("livebox_category_title", title, NULL, "Success"); -} - -static void utc_livebox_category_title_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, category_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_category_title", handle, NULL, "Create for category_title"); - } -} - -static void utc_livebox_filename_n(void) -{ - const char *filename; - filename = livebox_filename(NULL); - dts_check_eq("livebox_filename", filename, NULL, "Success"); -} - -static void filename_create_cb(struct livebox *handle, int ret, void *data) -{ - const char *filename; - filename = livebox_filename(handle); - dts_check_ne("livebox_filename", filename, NULL, "Success"); -} - -static void utc_livebox_filename_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, filename_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_category_title", handle, NULL, "Create for category_title"); - } -} - -static void utc_livebox_pkgname_n(void) -{ - const char *pkgname; - pkgname = livebox_pkgname(NULL); - dts_check_eq("livebox_pkgname", pkgname, NULL, "Success"); -} - -static void utc_livebox_pkgname_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, NULL, NULL); - if (!handle) { - dts_check_ne("livebox_pkgname", handle, NULL, "Create for pkgname"); - } else { - const char *pkgname; - - pkgname = livebox_pkgname(handle); - dts_check_ne("livebox_pkgname", pkgname, NULL, "pkgname"); - } -} - -static void utc_livebox_priority_n(void) -{ - double priority; - - priority = livebox_priority(NULL); - dts_check_eq("livebox_priority", priority, 0.0f, "Success"); -} - -static void priority_create_cb(struct livebox *handle, int ret, void *data) -{ - double priority; - - priority = livebox_priority(handle); - dts_check_ge("livebox_priority", priority, 0.0f, "Success"); -} - -static void utc_livebox_priority_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, priority_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_priority", handle, NULL, "Create for priority"); - } -} - -static void utc_livebox_acquire_fb_n(void) -{ - void *data; - - data = livebox_acquire_fb(NULL); - dts_check_eq("livebox_acquire_fb", data, NULL, "Success"); -} - -static void acquire_fb_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_fb", ret, LB_STATUS_SUCCESS, "acquire_fb"); - } else { - void *data; - data = livebox_acquire_fb(handle); - dts_check_ne("livebox_acquire_fb", data, NULL, "acquire_fb"); - livebox_release_fb(data); - } -} - -static void utc_livebox_acquire_fb_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, acquire_fb_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_priority", handle, NULL, "Create for priority"); - } -} - -static void utc_livebox_release_fb_n(void) -{ - int ret; - - ret = livebox_release_fb(NULL); - dts_check_eq("livebox_release_fb", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void release_fb_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_fb", ret, LB_STATUS_SUCCESS, "release_fb"); - } else { - void *data; - - data = livebox_acquire_fb(handle); - - ret = livebox_release_fb(data); - dts_check_eq("livebox_release_fb", ret, LB_STATUS_SUCCESS, "release_fb"); - } -} - -static void utc_livebox_release_fb_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, release_fb_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_priority", handle, NULL, "Create for priority"); - } -} - -static void refcnt_fb_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_fb_refcnt", ret, LB_STATUS_SUCCESS, "refcnt"); - } else { - void *data; - - data = livebox_acquire_fb(handle); - - ret = livebox_fb_refcnt(data); - dts_check_ge("livebox_fb_refcnt", ret, 0, "refcnt"); - - (void)livebox_release_fb(data); - } -} - -static void utc_livebox_fb_refcnt_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, refcnt_fb_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_priority", handle, NULL, "Create for priority"); - } -} - -static void utc_livebox_fb_refcnt_n(void) -{ - int ret; - - ret = livebox_fb_refcnt(NULL); - dts_check_eq("livebox_fb_refcnt", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void acquire_pdfb_pd_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pdfb", ret, LB_STATUS_SUCCESS, "create pd failed"); - return; - } - - data = livebox_acquire_pdfb(handle); - dts_check_ne("livebox_acquire_pdfb", data, NULL, "acquire_pdfb"); - (void)livebox_release_pdfb(data); -} - -static void acquire_pdfb_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pdfb", ret, LB_STATUS_SUCCESS, "refcnt"); - } else { - ret = livebox_create_pd(handle, acquire_pdfb_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pdfb", ret, LB_STATUS_SUCCESS, "refcnt"); - } - } -} - -static void utc_livebox_acquire_pdfb_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, acquire_pdfb_cb, NULL); - if (!handle) { - dts_check_ne("livebox_priority", handle, NULL, "Create for priority"); - } -} - -static void utc_livebox_acquire_pdfb_n(void) -{ - void *data; - - data = livebox_acquire_pdfb(NULL); - dts_check_eq("livebox_acquire_pdfb", data, NULL, "invalid"); -} - -static void release_pdfb_pd_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_pdfb", ret, LB_STATUS_SUCCESS, "create pd"); - return; - } - - data = livebox_acquire_pdfb(handle); - ret = livebox_release_pdfb(data); - dts_check_eq("livebox_release_pdfb", ret, LB_STATUS_SUCCESS, "release_pdfb"); -} - -static void release_pdfb_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pdfb", ret, LB_STATUS_SUCCESS, "refcnt"); - } else { - ret = livebox_create_pd(handle, release_pdfb_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pdfb", ret, LB_STATUS_SUCCESS, "refcnt"); - } - } -} - -static void utc_livebox_release_pdfb_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, release_pdfb_cb, NULL); - if (!handle) { - dts_check_ne("livebox_priority", handle, NULL, "Create for priority"); - } -} - -static void utc_livebox_release_pdfb_n(void) -{ - int ret; - ret = livebox_release_pdfb(NULL); - dts_check_eq("livebox_release_pdfb", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void utc_livebox_pdfb_refcnt_n(void) -{ - int ret; - ret = livebox_pdfb_refcnt(NULL); - dts_check_eq("livebox_pdfb_refcnt", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void refcnt_pdfb_pd_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pdfb_refcnt", ret, LB_STATUS_SUCCESS, "create pd"); - return; - } - - data = livebox_acquire_pdfb(handle); - ret = livebox_pdfb_refcnt(data); - dts_check_ge("livebox_pdfb_refcnt", ret, 0, "refcnt_pdfb"); - (void)livebox_release_pdfb(data); -} - -static void refcnt_pdfb_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pdfb_refcnt", ret, LB_STATUS_SUCCESS, "refcnt"); - } else { - ret = livebox_create_pd(handle, refcnt_pdfb_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pdfb_refcnt", ret, LB_STATUS_SUCCESS, "refcnt"); - } - } -} - -static void utc_livebox_pdfb_refcnt_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, refcnt_pdfb_cb, NULL); - if (!handle) { - dts_check_ne("livebox_pdfb_refcnt", handle, NULL, "Create for pdfb refcnt"); - } -} - -static void size_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_size", ret, LB_STATUS_SUCCESS, "size"); - } else { - int size; - size = livebox_size(handle); - dts_check_eq("livebox_size", size, LB_SIZE_TYPE_1x1, "size"); - } -} - -static void utc_livebox_size_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, size_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_size", handle, NULL, "Create for size"); - } -} - -static void utc_livebox_size_n(void) -{ - int ret; - ret = livebox_size(NULL); - dts_check_eq("livebox_size", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void utc_livebox_get_pdsize_n(void) -{ - int ret; - ret = livebox_get_pdsize(NULL, NULL, NULL); - dts_check_eq("livebox_get_pdsize", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void pdsize_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_get_pdsize", ret, LB_STATUS_SUCCESS, "pdsize"); - } else { - int w; - int h; - - ret = livebox_get_pdsize(handle, &w, &h); - dts_check_eq("livebox_get_pdsize", ret, LB_STATUS_SUCCESS, "pdsize"); - } -} - -static void utc_livebox_get_pdsize_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pdsize_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_get_pdsize", handle, NULL, "Create for priority"); - } -} - -static void utc_livebox_get_supported_sizes_n(void) -{ - int ret; - - ret = livebox_get_supported_sizes(NULL, NULL, NULL); - dts_check_eq("livebox_get_supported_sizes", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void size_list_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_get_supported_sizes", ret, LB_STATUS_SUCCESS, "size_list"); - } else { - int cnt = 20; - int size_list[20]; - - ret = livebox_get_supported_sizes(handle, &cnt, size_list); - dts_check_eq("livebox_get_supported_sizes", ret, LB_STATUS_SUCCESS, "size_list"); - } -} - -static void utc_livebox_get_supported_sizes_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, size_list_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_get_supported_sizes", handle, NULL, "Create for supported_sizes"); - } -} - -static void utc_livebox_lbfb_bufsz_n(void) -{ - int ret; - ret = livebox_lbfb_bufsz(NULL); - dts_check_eq("livebox_lbfb_bufsz", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void lbfb_bufsz_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_lbfb_bufsz", ret, LB_STATUS_SUCCESS, "size_list"); - } else { - int bufsz; - bufsz = livebox_lbfb_bufsz(handle); - dts_check_gt("livebox_lbfb_bufsz", bufsz, 0, "lbfb_bufsz"); - } -} - -static void utc_livebox_lbfb_bufsz_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, lbfb_bufsz_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_lbfb_bufsz", handle, NULL, "Create for supported_sizes"); - } -} - -static void utc_livebox_pdfb_bufsz_n(void) -{ - int ret; - ret = livebox_pdfb_bufsz(NULL); - dts_check_eq("livebox_pdfb_bufsz", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void pdfb_bufsz_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pdfb_bufsz", ret, LB_STATUS_SUCCESS, "size_list"); - } else { - int bufsz; - bufsz = livebox_pdfb_bufsz(handle); - dts_check_gt("livebox_pdfb_bufsz", bufsz, 0, "pdfb_bufsz"); - } -} - -static void utc_livebox_pdfb_bufsz_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pdfb_bufsz_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_pdfb_bufsz", handle, NULL, "Create for supported_sizes"); - } -} - -static void utc_livebox_content_event_n(void) -{ - int ret; - - ret = livebox_content_event(NULL, PD_MOUSE_DOWN, 0.0f, 0.0f); - dts_check_eq("livebox_content_event", ret, LB_STATUS_ERROR_INVALID, "Invalid"); -} - -static void content_event_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_content_event", ret, LB_STATUS_SUCCESS, "content_event"); - } else { - ret = livebox_content_event(handle, PD_MOUSE_DOWN, 0.0f, 0.0f); - dts_check_eq("livebox_content_event", ret, LB_STATUS_SUCCESS, "content_event"); - } -} - -static void utc_livebox_content_event_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, content_event_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_content_event", handle, NULL, "Create for content_event"); - } -} - -static void utc_livebox_mouse_event_n(void) -{ - int ret; - ret = livebox_mouse_event(NULL, PD_MOUSE_DOWN, 0.0f, 0.0f); - dts_check_eq("livebox_mouse_event", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void mouse_event_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_content_event", ret, LB_STATUS_SUCCESS, "content_event"); - } else { - ret = livebox_content_event(handle, PD_MOUSE_DOWN, 0.0f, 0.0f); - dts_check_eq("livebox_content_event", ret, LB_STATUS_SUCCESS, "content_event"); - } -} - -static void utc_livebox_mouse_event_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, mouse_event_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_content_event", handle, NULL, "Create for content_event"); - } -} - -static void utc_livebox_access_event_n(void) -{ - int ret; - ret = livebox_access_event(NULL, ACCESS_EVENT_ACTION_DOWN, 0.0f, 0.0f, NULL, NULL); - dts_check_eq("livebox_mouse_event", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void access_event_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_access_event", ret, LB_STATUS_SUCCESS, "access_event"); - } else { - ret = livebox_access_event(handle, ACCESS_EVENT_ACTION_DOWN, 0.0f, 0.0f, NULL, NULL); - dts_check_eq("livebox_access_event", ret, LB_STATUS_SUCCESS, "access_event"); - } -} - -static void utc_livebox_access_event_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, access_event_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_access_event", handle, NULL, "Create for access_event"); - } -} - -static void utc_livebox_key_event_n(void) -{ - int ret; - ret = livebox_key_event(NULL, PD_KEY_DOWN, 13, NULL, NULL); - dts_check_eq("livebox_key_event", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void key_event_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_key_event", ret, LB_STATUS_SUCCESS, "key_event"); - } else { - ret = livebox_key_event(handle, LB_KEY_DOWN, 13, NULL, NULL); - dts_check_eq("livebox_key_event", ret, LB_STATUS_SUCCESS, "key_event"); - } -} - -static void utc_livebox_key_event_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, key_event_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_key_event", handle, NULL, "Create for key_event"); - } -} - -static void utc_livebox_set_pinup_n(void) -{ - int ret; - ret = livebox_set_pinup(NULL, 0, NULL, NULL); - dts_check_eq("livebox_set_pinup", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void pinup_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_set_pinup", ret, LB_STATUS_SUCCESS, "key_event"); - } else { - ret = livebox_set_pinup(handle, 0, NULL, NULL); - dts_check_eq("livebox_set_pinup", ret, LB_STATUS_ERROR_ALREADY, "already"); - } -} - -static void utc_livebox_set_pinup_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pinup_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_pinup", handle, NULL, "Create for pinup"); - } -} - -static void utc_livebox_is_pinned_up_n(void) -{ - int ret; - ret = livebox_is_pinned_up(NULL); - dts_check_eq("livebox_is_pinned_up", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void is_pinup_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_is_pinned_up", ret, LB_STATUS_SUCCESS, "key_event"); - } else { - ret = livebox_is_pinned_up(handle); - dts_check_eq("livebox_is_pinned_up", ret, LB_STATUS_ERROR_ALREADY, "already"); - } -} - -static void utc_livebox_is_pinned_up_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, is_pinup_cb, NULL); - if (!handle) { - dts_check_ne("livebox_is_pinned_up", handle, NULL, "Create for is_pinned_up"); - } -} - -static void utc_livebox_has_pinup_n(void) -{ - int ret; - ret = livebox_has_pinup(NULL); - dts_check_eq("livebox_has_pinup", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void has_pinup_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_has_pinup", ret, LB_STATUS_SUCCESS, "has_pinup"); - } else { - ret = livebox_has_pinup(handle); - dts_check_eq("livebox_has_pinup", ret, 0, "not supported"); - } -} - -static void utc_livebox_has_pinup_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, has_pinup_cb, NULL); - if (!handle) { - dts_check_ne("livebox_has_pinup", handle, NULL, "Create for has_pinup"); - } -} - -static void has_pd_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_has_pd", ret, LB_STATUS_SUCCESS, "has_pd"); - } else { - ret = livebox_has_pd(handle); - dts_check_eq("livebox_has_pd", ret, 1, "PD supported"); - } -} - -static void utc_livebox_has_pd_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, has_pd_cb, NULL); - if (!handle) { - dts_check_ne("livebox_has_pinup", handle, NULL, "Create for has_pinup"); - } -} - -static void utc_livebox_has_pd_n(void) -{ - int ret; - ret = livebox_has_pd(NULL); - dts_check_eq("livebox_has_pd", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void utc_livebox_create_pd_n(void) -{ - int ret; - ret = livebox_create_pd(NULL, NULL, NULL); - dts_check_eq("livebox_create_pd", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void create_pd_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_create_pd", ret, LB_STATUS_SUCCESS, "create_pd"); - (void)livebox_destroy_pd(handle, NULL, NULL); -} - -static void create_pd_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_create_pd", ret, LB_STATUS_SUCCESS, "create_pd"); - } else { - ret = livebox_create_pd(handle, create_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_create_pd", ret, LB_STATUS_SUCCESS, "create_pd"); - } - } -} - -static void utc_livebox_create_pd_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, create_pd_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_has_pinup", handle, NULL, "Create for has_pinup"); - } -} - -static void utc_livebox_create_pd_with_position_n(void) -{ - int ret; - ret = livebox_create_pd_with_position(NULL, 0.0f, 0.0f, NULL, NULL); - dts_check_eq("livebox_create_pd_with_position", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void create_pd_pos_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_create_pd_with_position", ret, LB_STATUS_SUCCESS, "PD,create"); - (void)livebox_destroy_pd(handle, NULL, NULL); -} - -static void create_pd_pos_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_create_pd_with_position", ret, LB_STATUS_SUCCESS, "create_pd_w/h_position"); - } else { - ret = livebox_create_pd_with_position(handle, 0.0f, 0.0f, create_pd_pos_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_create_pd_with_position", ret, LB_STATUS_SUCCESS, "create_pd_w/h_position"); - } - } -} - -static void utc_livebox_create_pd_with_position_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, create_pd_pos_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_create_pd_with_position", handle, NULL, "Create for create_pd_with_position"); - } -} - -static void utc_livebox_move_pd_n(void) -{ - int ret; - ret = livebox_move_pd(NULL, 0.0f, 0.0f); - dts_check_eq("livebox_move_pd", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void create_move_pd_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_move_pd", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_move_pd(handle, 0.5f, 0.5f); - dts_check_eq("livebox_move_pd", ret, LB_STATUS_SUCCESS, "invalid"); - } -} - -static void move_pd_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_move_pd", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_create_pd_with_position(handle, 0.0f, 0.0f, create_move_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_move_pd", ret, LB_STATUS_SUCCESS, "invalid"); - } - } -} - -static void utc_livebox_move_pd_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, move_pd_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_move_pd", handle, NULL, "Create for move_pd"); - } -} - -static void utc_livebox_destroy_pd_n(void) -{ - int ret; - ret = livebox_destroy_pd(NULL, NULL, NULL); - dts_check_eq("livebox_destroy_pd", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void destroy_pd_cb(struct livebox *handle, int ret, void *data) -{ - dts_check_eq("livebox_destroy_pd", ret, LB_STATUS_SUCCESS, "destroy_pd"); -} - -static void destroy_pd_create_pd_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_destroy_pd", ret, LB_STATUS_SUCCESS, "destroy_pd"); - } else { - ret = livebox_destroy_pd(handle, destroy_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_destroy_pd", ret, LB_STATUS_SUCCESS, "destroy_pd"); - } - } -} - -static void destroy_pd_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_destroy_pd", ret, LB_STATUS_SUCCESS, "destroy_pd"); - } else { - ret = livebox_create_pd_with_position(handle, 0.0f, 0.0f, destroy_pd_create_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_destroy_pd", ret, LB_STATUS_SUCCESS, "invalid"); - } - } -} - -static void utc_livebox_destroy_pd_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, destroy_pd_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_destroy_pd", handle, NULL, "Create for destroy_pd"); - } -} - -static void utc_livebox_pd_is_created_n(void) -{ - int ret; - ret = livebox_pd_is_created(NULL); - dts_check_eq("livebox_pd_is_created", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void pd_is_created_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pd_is_created", ret, LB_STATUS_SUCCESS, "pd_is_created"); - } else { - ret = livebox_pd_is_created(handle); - dts_check_eq("livebox_pd_is_created", ret, 0, "pd_is_created"); - (void)livebox_del(handle, NULL, NULL); - } -} - -static void utc_livebox_pd_is_created_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pd_is_created_cb, NULL); - if (!handle) { - dts_check_ne("livebox_pd_is_created", handle, NULL, "create for pd_is_created"); - } -} - -static void utc_livebox_pd_type_n(void) -{ - int type; - type = livebox_pd_type(NULL); - dts_check_eq("livebox_pd_type", type, PD_TYPE_INVALID, "invalid"); -} - -static void pd_type_created_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pd_type", ret, LB_STATUS_SUCCESS, "pd_type"); - } else { - ret = livebox_pd_type(handle); - dts_check_ne("livebox_pd_type", ret, PD_TYPE_INVALID, "pd_type"); - } -} - -static void utc_livebox_pd_type_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pd_type_created_cb, NULL); - if (!handle) { - dts_check_ne("livebox_pd_type", handle, NULL, "create for pd_is_created"); - } -} - -static void utc_livebox_is_exists_n(void) -{ - int ret; - ret = livebox_is_exists(NULL); - dts_check_eq("livebox_is_exists", ret, 0, "not exists"); -} - -static void utc_livebox_is_exists_p(void) -{ - int ret; - ret = livebox_is_exists(MUSIC_APP); - dts_check_eq("livebox_is_exists", ret, 1, "exists"); -} - -static void utc_livebox_set_text_handler_n(void) -{ - int ret; - ret = livebox_set_text_handler(NULL, NULL); - dts_check_eq("livebox_set_text_handler", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void set_text_handler_created_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_set_text_handler", ret, LB_STATUS_SUCCESS, "set_text_handler"); - } else { - struct livebox_script_operators ops = { - .update_begin = NULL, - .update_end = NULL, - .update_text = NULL, - .update_image = NULL, - .update_script = NULL, - .update_signal = NULL, - .update_drag = NULL, - .update_info_size = NULL, - .update_info_category = NULL, - .update_access = NULL, - .operate_access = NULL, - }; - - ret = livebox_set_text_handler(handle, &ops); - dts_check_eq("livebox_set_text_handler", ret, LB_STATUS_SUCCESS, "set_text_handler"); - } -} - -static void utc_livebox_set_text_handler_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, set_text_handler_created_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_text_handler", handle, NULL, "create for pd_is_created"); - } -} - -static void utc_livebox_set_pd_text_handler_n(void) -{ - int ret; - ret = livebox_set_pd_text_handler(NULL, NULL); - dts_check_eq("livebox_set_pd_text_handler", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void set_pd_text_handler_created_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_set_pd_text_handler", ret, LB_STATUS_SUCCESS, "set_text_handler"); - } else { - struct livebox_script_operators ops = { - .update_begin = NULL, - .update_end = NULL, - .update_text = NULL, - .update_image = NULL, - .update_script = NULL, - .update_signal = NULL, - .update_drag = NULL, - .update_info_size = NULL, - .update_info_category = NULL, - .update_access = NULL, - .operate_access = NULL, - }; - - ret = livebox_set_pd_text_handler(handle, &ops); - dts_check_eq("livebox_set_pd_text_handler", ret, LB_STATUS_SUCCESS, "set_text_handler"); - } -} - -static void utc_livebox_set_pd_text_handler_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, set_pd_text_handler_created_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_pd_text_handler", handle, NULL, "create for pd_is_created"); - } -} - -static void utc_livebox_emit_text_signal_n(void) -{ - int ret; - ret = livebox_emit_text_signal(NULL, NULL, NULL, 0.0f, 0.0f, 0.0f, 0.0f, NULL, NULL); - dts_check_eq("livebox_emit_text_signal", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void emit_signal_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_emit_text_signal", ret, LB_STATUS_SUCCESS, "set_text_handler"); - } else { - ret = livebox_emit_text_signal(handle, NULL, NULL, 0.0f, 0.0f, 0.0f, 0.0f, NULL, NULL); - dts_check_eq("livebox_emit_text_signal", ret, LB_STATUS_ERROR_INVALID, "text_handler"); - } -} - -static void utc_livebox_emit_text_signal_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, emit_signal_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_emit_text_signal", handle, NULL, "create for pd_is_created"); - } -} - -static void utc_livebox_set_data_n(void) -{ - int ret; - ret = livebox_set_data(NULL, NULL); - dts_check_eq("livebox_set_data", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void utc_livebox_set_data_p(void) -{ - struct livebox *handle; - int ret; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, emit_signal_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_data", handle, NULL, "create for pd_is_created"); - return; - } - - ret = livebox_set_data(handle, (void *)123); - dts_check_eq("livebox_set_data", ret, LB_STATUS_SUCCESS, "set_data"); -} - -static void utc_livebox_get_data_p(void) -{ - struct livebox *handle; - void *data; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, emit_signal_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_data", handle, NULL, "create for pd_is_created"); - return; - } - - data = livebox_get_data(handle); - dts_check_eq("livebox_get_data", data, NULL, "get_data"); -} - -static void utc_livebox_get_data_n(void) -{ - void *data; - data = livebox_get_data(NULL); - dts_check_eq("livebox_get_data", data, NULL, "data"); -} - -static void utc_livebox_subscribe_group_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_subscribe_group", "pass negative test"); -} - -static void utc_livebox_subscribe_group_p(void) -{ - int ret; - ret = livebox_subscribe_group("my,cluster", "my,category"); - dts_check_eq("livebox_subscribe_group", ret, LB_STATUS_SUCCESS, "subscribe"); -} - -static void utc_livebox_unsubscribe_group_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_unsubscribe_group", "pass negative test"); -} - -static void utc_livebox_unsubscribe_group_p(void) -{ - int ret; - ret = livebox_unsubscribe_group("my,cluster", "my,category"); - dts_check_eq("livebox_unsubscribe_group", ret, LB_STATUS_SUCCESS, "unsubscribe"); -} - -static void utc_livebox_refresh_group_n(void) -{ - int ret; - ret = livebox_refresh_group(NULL, NULL, 0); - dts_check_eq("livebox_refresh_group", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void utc_livebox_refresh_group_p(void) -{ - int ret; - ret = livebox_refresh_group("my,cluster", "my,category", 0); - dts_check_eq("livebox_refresh_group", ret, LB_STATUS_SUCCESS, "refresh_group"); -} - -static void refresh_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_refresh", ret, LB_STATUS_SUCCESS, "refresh"); - } else { - ret = livebox_refresh(handle, 0); - dts_check_eq("livebox_refresh", ret, LB_STATUS_SUCCESS, "refresh"); - } -} - -static void utc_livebox_refresh_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, refresh_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_data", handle, NULL, "create for pd_is_created"); - return; - } -} - -static void utc_livebox_refresh_n(void) -{ - int ret; - ret = livebox_refresh(NULL, 0); - dts_check_eq("livebox_refresh", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - - -static void utc_livebox_lb_pixmap_n(void) -{ - int ret; - ret = livebox_lb_pixmap(NULL); - dts_check_eq("livebox_lb_pixmap", ret, 0, "invalid"); -} - -static void lb_pixmap_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_lb_pixmap", ret, LB_STATUS_SUCCESS, "lb_pixmap"); - } else { - ret = livebox_lb_pixmap(handle); - dts_check_ne("livebox_lb_pixmap", ret, 0, "lb_pixmap"); - } -} - -static void utc_livebox_lb_pixmap_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, lb_pixmap_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_lb_pixmap", handle, NULL, "create for lb_pixmap"); - return; - } -} - -static void pd_pixmap_create_pd_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pd_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_pd_pixmap(handle); - dts_check_ne("livebox_pd_pixmap", ret, 0, "pd_pixmap"); - } -} - -static void pd_pixmap_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pd_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_create_pd(handle, pd_pixmap_create_pd_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_pd_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } - } -} - -static void utc_livebox_pd_pixmap_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pd_pixmap_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_pd_pixmap", handle, NULL, "create for pd_pixmap"); - } -} - -static void utc_livebox_pd_pixmap_n(void) -{ - int ret; - ret = livebox_pd_pixmap(NULL); - dts_check_eq("livebox_pd_pixmap", ret, 0, "invalid"); -} - -static void utc_livebox_acquire_pd_pixmap_n(void) -{ - int ret; - ret = livebox_acquire_pd_pixmap(NULL, NULL, NULL); - dts_check_eq("livebox_acquire_pd_pixmap", ret, 0, "invalid"); -} - -static void acquire_pd_pixmap_cb(struct livebox *handle, int pixmap, void *data) -{ - dts_check_ne("livebox_acquire_pd_pixmap", pixmap, 0, "acquire_pd_pixmap"); - (void)livebox_release_pd_pixmap(handle, pixmap); -} - -static void pd_acquire_pixmap_pd_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pd_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_acquire_pd_pixmap(handle, acquire_pd_pixmap_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pd_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } - } -} - -static void pd_acquire_pixmap_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pd_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_create_pd(handle, pd_acquire_pixmap_pd_create_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_pd_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } - } -} - -static void utc_livebox_acquire_pd_pixmap_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pd_acquire_pixmap_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_pd_pixmap", handle, NULL, "create for pd_pixmap"); - } -} - -static void utc_livebox_release_pd_pixmap_n(void) -{ - int ret; - ret = livebox_release_pd_pixmap(NULL, 0); - dts_check_eq("livebox_release_pd_pixmap", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void release_pd_pixmap_cb(struct livebox *handle, int pixmap, void *data) -{ - int ret; - - if (pixmap == 0) { - dts_check_ne("livebox_release_pd_pixmap", pixmap, 0, "release_pd_pixmap"); - return; - } - - ret = livebox_release_pd_pixmap(handle, pixmap); - dts_check_eq("livebox_release_pd_pixmap", ret, LB_STATUS_SUCCESS, "release_pd_pixmap"); -} - -static void pd_release_pixmap_pd_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_pd_pixmap", ret, LB_STATUS_SUCCESS, "release_pd_pixmap"); - } else { - ret = livebox_acquire_pd_pixmap(handle, release_pd_pixmap_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_pd_pixmap", ret, LB_STATUS_SUCCESS, "release_pd_pixmap"); - } - } -} - -static void pd_release_pixmap_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_pd_pixmap", ret, LB_STATUS_SUCCESS, "release_pd_pixmap"); - } else { - ret = livebox_create_pd(handle, pd_release_pixmap_pd_create_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_pd_pixmap", ret, LB_STATUS_SUCCESS, "release_pd_pixmap"); - } - } -} - -static void utc_livebox_release_pd_pixmap_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, pd_release_pixmap_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_release_pd_pixmap", handle, NULL, "create for release_pd_pixmap"); - } -} - -static void acquire_lb_pixmap_cb(struct livebox *handle, int pixmap, void *data) -{ - dts_check_ne("livebox_acquire_lb_pixmap", pixmap, 0, "acquire_lb_pixmap"); - (void)livebox_release_lb_pixmap(handle, pixmap); -} - -static void lb_acquire_pixmap_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_lb_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_acquire_lb_pixmap(handle, acquire_lb_pixmap_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_lb_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } - } -} - -static void utc_livebox_acquire_lb_pixmap_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, lb_acquire_pixmap_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_acquire_lb_pixmap", handle, NULL, "create for lb_pixmap"); - } -} - -static void utc_livebox_acquire_lb_pixmap_n(void) -{ - int ret; - ret = livebox_acquire_lb_pixmap(NULL, NULL, NULL); - dts_check_eq("livebox_acquire_lb_pixmap", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void release_lb_pixmap_cb(struct livebox *handle, int pixmap, void *data) -{ - if (pixmap == 0) { - dts_check_ne("livebox_release_lb_pixmap", pixmap, 0, "release_lb_pixmap"); - } else { - int ret; - ret = livebox_release_lb_pixmap(handle, pixmap); - dts_check_eq("livebox_release_lb_pixmap", ret, LB_STATUS_SUCCESS, "release_lb_pixmap"); - } -} - -static void lb_release_pixmap_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_lb_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } else { - ret = livebox_acquire_lb_pixmap(handle, release_lb_pixmap_cb, NULL); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_lb_pixmap", ret, LB_STATUS_SUCCESS, "invalid"); - } - } -} - -static void utc_livebox_release_lb_pixmap_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, lb_release_pixmap_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_release_lb_pixmap", handle, NULL, "create for lb_pixmap"); - } -} - -static void utc_livebox_release_lb_pixmap_n(void) -{ - int ret; - ret = livebox_release_lb_pixmap(NULL, 0); - dts_check_eq("livebox_release_lb_pixmap", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void set_visibility_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_ne("livebox_set_visibility", ret, LB_STATUS_SUCCESS, "visibility_set"); - } else { - ret = livebox_set_visibility(handle, LB_SHOW); - dts_check_eq("livebox_set_visibility", ret, LB_STATUS_SUCCESS, "visibility_set"); - } -} - -static void utc_livebox_set_visibility_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, set_visibility_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_visibility", handle, NULL, "create for set_visibility"); - } -} - -static void utc_livebox_set_visibility_n(void) -{ - int ret; - ret = livebox_set_visibility(NULL, LB_SHOW); - dts_check_eq("livebox_set_visibility", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void visibility_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_ne("livebox_visibility", ret, LB_STATUS_SUCCESS, "visibility"); - } else { - ret = livebox_visibility(handle); - dts_check_eq("livebox_visibility", ret, LB_HIDE_WITH_PAUSE, "visibility_set"); - } -} - -static void utc_livebox_visibility_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, visibility_cb, NULL); - if (!handle) { - dts_check_ne("livebox_visibility", handle, NULL, "create for visibility"); - } -} - -static void utc_livebox_visibility_n(void) -{ - int ret; - - ret = livebox_visibility(NULL); - dts_check_eq("livebox_visibility", ret, LB_VISIBLE_ERROR, "invalid"); -} - -static void utc_livebox_set_update_mode_n(void) -{ - int ret; - - ret = livebox_set_update_mode(NULL, 0, NULL, NULL); - dts_check_eq("livebox_set_update_mode", ret,LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void set_update_mode_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_set_update_mode", ret, LB_STATUS_SUCCESS, "set_update_mode"); - } else { - ret = livebox_set_update_mode(handle, 0, NULL, NULL); - dts_check_eq("livebox_set_update_mode", ret, LB_STATUS_ERROR_ALREADY, "set_update_mode"); - } -} - -static void utc_livebox_set_update_mode_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, set_update_mode_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_set_update_mode", handle, NULL, "create for set_update_mode"); - } -} - -static void utc_livebox_is_active_update_n(void) -{ - int ret; - ret = livebox_is_active_update(NULL); - dts_check_eq("livebox_is_active_update", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void is_active_update_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_is_active_update", ret, LB_STATUS_SUCCESS, "is_activate_update"); - } else { - ret = livebox_is_active_update(handle); - dts_check_eq("livebox_is_active_update", ret, 0, "is_activate_update"); - } -} - -static void utc_livebox_is_active_update_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, is_active_update_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_is_active_update", handle, NULL, "create for is_active_update"); - } -} - -static void utc_livebox_set_manual_sync_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_set_manual_sync", "negative pass"); -} - -static void utc_livebox_set_manual_sync_p(void) -{ - livebox_set_option(LB_OPTION_MANUAL_SYNC, 0); - dts_pass("livebox_set_manual_sync", "Pass!"); -} - -static void utc_livebox_manual_sync_p(void) -{ - int ret; - - ret = livebox_option(LB_OPTION_MANUAL_SYNC); - dts_check_eq("livebox_manual_sync", ret, 0, "ok"); -} - -static void utc_livebox_manual_sync_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_manual_sync", "negative Pass"); -} - -static void utc_livebox_set_frame_drop_for_resizing_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_set_frame_drop_for_resizing", "pass"); -} - -static void utc_livebox_set_frame_drop_for_resizing_p(void) -{ - livebox_set_option(LB_OPTION_FRAME_DROP_FOR_RESIZE, 1); - dts_pass("livebox_set_frame_drop_for_resizing", "pass"); -} - -static void utc_livebox_frame_drop_for_resizing_n(void) -{ - /*! - * \note - * Unable to test negative case - */ - dts_pass("livebox_frame_drop_for_resizing", "pass"); -} - -static void utc_livebox_frame_drop_for_resizing_p(void) -{ - int ret; - - ret = livebox_option(LB_OPTION_FRAME_DROP_FOR_RESIZE); - dts_check_eq("livebox_frame_drop_for_resizing", ret, 1, "drop_for_resizing"); -} - -static void utc_livebox_sync_pd_fb_n(void) -{ - int ret; - ret = livebox_sync_pd_fb(NULL); - dts_check_eq("livebox_sync_pd_fb", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void sync_pd_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_sync_pd_fb", ret, LB_STATUS_SUCCESS, "sync_pd_fb"); - } else { - ret = livebox_sync_pd_fb(handle); - dts_check_eq("livebox_sync_pd_fb", ret, LB_STATUS_SUCCESS, "sync_pd_fb"); - } -} - -static void utc_livebox_sync_pd_fb_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, sync_pd_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_sync_pd_fb", handle, NULL, "create for sync_pd_fb"); - } -} - -static void sync_lb_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_sync_lb_fb", ret, LB_STATUS_SUCCESS, "sync_lb_fb"); - } else { - ret = livebox_sync_lb_fb(handle); - dts_check_eq("livebox_sync_lb_fb", ret, LB_STATUS_SUCCESS, "sync_lb_fb"); - } -} - -static void utc_livebox_sync_lb_fb_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, sync_lb_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_sync_pd_fb", handle, NULL, "create for sync_pd_fb"); - } -} - -static void utc_livebox_sync_lb_fb_n(void) -{ - int ret; - ret = livebox_sync_lb_fb(NULL); - dts_check_eq("livebox_sync_lb_fb", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void alt_icon_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_alt_name", ret, LB_STATUS_SUCCESS, "alt_name"); - } else { - const char *alt_icon; - - alt_icon = livebox_alt_icon(handle); - dts_check_ne("livebox_alt_icon", alt_icon, NULL, "alt_icon"); - } -} - -static void utc_livebox_alt_icon_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, alt_icon_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_alt_icon", handle, NULL, "alt_icon"); - } -} - -static void utc_livebox_alt_icon_n(void) -{ - const char *alt_icon; - - alt_icon = livebox_alt_icon(NULL); - dts_check_eq("livebox_alt_icon", alt_icon, NULL, "invalid"); -} - -static void alt_name_create_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_alt_name", ret, LB_STATUS_SUCCESS, "alt_name"); - } else { - const char *alt_name; - - alt_name = livebox_alt_name(handle); - dts_check_ne("livebox_alt_name", alt_name, NULL, "alt_name"); - } -} - -static void utc_livebox_alt_name_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(MUSIC_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, alt_name_create_cb, NULL); - if (!handle) { - dts_check_ne("livebox_alt_name", handle, NULL, "alt_name"); - } -} - -static void utc_livebox_alt_name_n(void) -{ - const char *alt_name; - alt_name = livebox_alt_name(NULL); - dts_check_eq("livebox_alt_icon", alt_name, NULL, "invalid"); -} - -static void utc_livebox_acquire_fb_lock_n(void) -{ - int ret; - ret = livebox_acquire_fb_lock(NULL, 0); - dts_check_eq("livebox_acquire_fb_lock", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void acquire_fb_lock_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_acquire_fb_lock", ret, LB_STATUS_SUCCESS, "acquire_fb_lock"); - } else { - ret = livebox_acquire_fb_lock(handle, 0); - dts_check_eq("livebox_acquire_fb_lock", ret, LB_STATUS_SUCCESS, "acquire_fb_lock"); - (void)livebox_release_fb_lock(handle, 0); - } -} - -static void utc_livebox_acquire_fb_lock_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, acquire_fb_lock_cb, NULL); - if (!handle) { - dts_check_ne("livebox_acquire_fb_lock", handle, NULL, "create for acquire_fb_lock"); - } -} - -static void utc_livebox_release_fb_lock_n(void) -{ - int ret; - ret = livebox_release_fb_lock(NULL, 0); - dts_check_eq("livebox_release_fb_lock", ret, LB_STATUS_ERROR_INVALID, "invalid"); -} - -static void release_fb_lock_cb(struct livebox *handle, int ret, void *data) -{ - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_fb_lock", ret, LB_STATUS_SUCCESS, "release_fb_lock"); - } else { - ret = livebox_acquire_fb_lock(handle, 0); - if (ret != LB_STATUS_SUCCESS) { - dts_check_eq("livebox_release_fb_lock", ret, LB_STATUS_SUCCESS, "release_fb_lock"); - return; - } - - ret = livebox_release_fb_lock(handle, 0); - dts_check_eq("livebox_acquire_fb_lock", ret, LB_STATUS_SUCCESS, "release_fb_lock"); - } -} - -static void utc_livebox_release_fb_lock_p(void) -{ - struct livebox *handle; - - handle = livebox_add_with_size(EMAIL_LIVEBOX, NULL, NULL, NULL, -1.0f, LB_SIZE_TYPE_1x1, release_fb_lock_cb, NULL); - if (!handle) { - dts_check_ne("livebox_release_fb_lock", handle, NULL, "create for release_fb_lock"); - } -} - -struct tet_testlist tet_testlist[] = { - { utc_livebox_client_paused_n, NEGATIVE_TC_IDX }, - { utc_livebox_client_paused_p, POSITIVE_TC_IDX }, - { utc_livebox_client_resumed_n, NEGATIVE_TC_IDX }, - { utc_livebox_client_resumed_p, POSITIVE_TC_IDX }, - { utc_livebox_add_p, POSITIVE_TC_IDX }, - { utc_livebox_add_n, NEGATIVE_TC_IDX }, - { utc_livebox_add_with_size_n, NEGATIVE_TC_IDX }, - { utc_livebox_add_with_size_p, POSITIVE_TC_IDX }, - { utc_livebox_del_n, NEGATIVE_TC_IDX }, - { utc_livebox_del_p, POSITIVE_TC_IDX }, - { utc_livebox_del_NEW_n, NEGATIVE_TC_IDX }, - { utc_livebox_del_NEW_p, POSITIVE_TC_IDX }, - { utc_livebox_set_event_handler_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_event_handler_p, POSITIVE_TC_IDX }, - { utc_livebox_unset_event_handler_n, NEGATIVE_TC_IDX }, - { utc_livebox_unset_event_handler_p, POSITIVE_TC_IDX }, - { utc_livebox_set_fault_handler_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_fault_handler_p, POSITIVE_TC_IDX }, - { utc_livebox_unset_fault_handler_n, NEGATIVE_TC_IDX }, - { utc_livebox_unset_fault_handler_p, POSITIVE_TC_IDX }, - { utc_livebox_activate_n, NEGATIVE_TC_IDX }, - { utc_livebox_activate_p, POSITIVE_TC_IDX }, - { utc_livebox_resize_n, NEGATIVE_TC_IDX }, - { utc_livebox_resize_p, POSITIVE_TC_IDX }, - { utc_livebox_click_n, NEGATIVE_TC_IDX }, - { utc_livebox_click_p, POSITIVE_TC_IDX }, - { utc_livebox_set_group_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_group_p, POSITIVE_TC_IDX }, - { utc_livebox_get_group_n, NEGATIVE_TC_IDX }, - { utc_livebox_get_group_p, POSITIVE_TC_IDX }, - { utc_livebox_period_n, NEGATIVE_TC_IDX }, - { utc_livebox_period_p, POSITIVE_TC_IDX }, - { utc_livebox_set_period_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_period_p, POSITIVE_TC_IDX }, - { utc_livebox_lb_type_n, NEGATIVE_TC_IDX }, - { utc_livebox_lb_type_p, POSITIVE_TC_IDX }, - { utc_livebox_is_user_n, NEGATIVE_TC_IDX }, - { utc_livebox_is_user_p, POSITIVE_TC_IDX }, - { utc_livebox_content_n, NEGATIVE_TC_IDX }, - { utc_livebox_content_p, POSITIVE_TC_IDX }, - { utc_livebox_category_title_n, NEGATIVE_TC_IDX }, - { utc_livebox_category_title_p, POSITIVE_TC_IDX }, - { utc_livebox_filename_n, NEGATIVE_TC_IDX }, - { utc_livebox_filename_p, POSITIVE_TC_IDX }, - { utc_livebox_pkgname_n, NEGATIVE_TC_IDX }, - { utc_livebox_pkgname_p, POSITIVE_TC_IDX }, - { utc_livebox_priority_n, NEGATIVE_TC_IDX }, - { utc_livebox_priority_p, POSITIVE_TC_IDX }, - { utc_livebox_acquire_fb_n, NEGATIVE_TC_IDX }, - { utc_livebox_acquire_fb_p, POSITIVE_TC_IDX }, - { utc_livebox_release_fb_n, NEGATIVE_TC_IDX }, - { utc_livebox_release_fb_p, POSITIVE_TC_IDX }, - { utc_livebox_fb_refcnt_p, POSITIVE_TC_IDX }, - { utc_livebox_fb_refcnt_n, NEGATIVE_TC_IDX }, - { utc_livebox_acquire_pdfb_p, POSITIVE_TC_IDX }, - { utc_livebox_acquire_pdfb_n, NEGATIVE_TC_IDX }, - { utc_livebox_release_pdfb_p, POSITIVE_TC_IDX }, - { utc_livebox_release_pdfb_n, NEGATIVE_TC_IDX }, - { utc_livebox_pdfb_refcnt_n, NEGATIVE_TC_IDX }, - { utc_livebox_pdfb_refcnt_p, POSITIVE_TC_IDX }, - { utc_livebox_size_p, POSITIVE_TC_IDX }, - { utc_livebox_size_n, NEGATIVE_TC_IDX }, - { utc_livebox_get_pdsize_n, NEGATIVE_TC_IDX }, - { utc_livebox_get_pdsize_p, POSITIVE_TC_IDX }, - { utc_livebox_get_supported_sizes_n, NEGATIVE_TC_IDX }, - { utc_livebox_get_supported_sizes_p, POSITIVE_TC_IDX }, - { utc_livebox_lbfb_bufsz_n, NEGATIVE_TC_IDX }, - { utc_livebox_lbfb_bufsz_p, POSITIVE_TC_IDX }, - { utc_livebox_pdfb_bufsz_n, NEGATIVE_TC_IDX }, - { utc_livebox_pdfb_bufsz_p, POSITIVE_TC_IDX }, - { utc_livebox_content_event_n, NEGATIVE_TC_IDX }, - { utc_livebox_content_event_p, POSITIVE_TC_IDX }, - { utc_livebox_mouse_event_n, NEGATIVE_TC_IDX }, - { utc_livebox_mouse_event_p, POSITIVE_TC_IDX }, - { utc_livebox_access_event_n, NEGATIVE_TC_IDX }, - { utc_livebox_access_event_p, POSITIVE_TC_IDX }, - { utc_livebox_key_event_n, NEGATIVE_TC_IDX }, - { utc_livebox_key_event_p, POSITIVE_TC_IDX }, - { utc_livebox_set_pinup_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_pinup_p, POSITIVE_TC_IDX }, - { utc_livebox_is_pinned_up_n, NEGATIVE_TC_IDX }, - { utc_livebox_is_pinned_up_p, POSITIVE_TC_IDX }, - { utc_livebox_has_pinup_n, NEGATIVE_TC_IDX }, - { utc_livebox_has_pinup_p, POSITIVE_TC_IDX }, - { utc_livebox_has_pd_p, POSITIVE_TC_IDX }, - { utc_livebox_has_pd_n, NEGATIVE_TC_IDX }, - { utc_livebox_create_pd_n, NEGATIVE_TC_IDX }, - { utc_livebox_create_pd_p, POSITIVE_TC_IDX }, - { utc_livebox_create_pd_with_position_n, NEGATIVE_TC_IDX }, - { utc_livebox_create_pd_with_position_p, POSITIVE_TC_IDX }, - { utc_livebox_move_pd_n, NEGATIVE_TC_IDX }, - { utc_livebox_move_pd_p, POSITIVE_TC_IDX }, - { utc_livebox_destroy_pd_n, NEGATIVE_TC_IDX }, - { utc_livebox_destroy_pd_p, POSITIVE_TC_IDX }, - { utc_livebox_pd_is_created_n, NEGATIVE_TC_IDX }, - { utc_livebox_pd_is_created_p, POSITIVE_TC_IDX }, - { utc_livebox_pd_type_n, NEGATIVE_TC_IDX }, - { utc_livebox_pd_type_p, POSITIVE_TC_IDX }, - { utc_livebox_is_exists_n, NEGATIVE_TC_IDX }, - { utc_livebox_is_exists_p, POSITIVE_TC_IDX }, - { utc_livebox_set_text_handler_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_text_handler_p, POSITIVE_TC_IDX }, - { utc_livebox_set_pd_text_handler_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_pd_text_handler_p, POSITIVE_TC_IDX }, - { utc_livebox_emit_text_signal_n, NEGATIVE_TC_IDX }, - { utc_livebox_emit_text_signal_p, POSITIVE_TC_IDX }, - { utc_livebox_set_data_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_data_p, POSITIVE_TC_IDX }, - { utc_livebox_get_data_p, POSITIVE_TC_IDX }, - { utc_livebox_get_data_n, NEGATIVE_TC_IDX }, - { utc_livebox_subscribe_group_n, NEGATIVE_TC_IDX }, - { utc_livebox_subscribe_group_p, POSITIVE_TC_IDX }, - { utc_livebox_unsubscribe_group_n, NEGATIVE_TC_IDX }, - { utc_livebox_unsubscribe_group_p, POSITIVE_TC_IDX }, - { utc_livebox_refresh_group_n, NEGATIVE_TC_IDX }, - { utc_livebox_refresh_group_p, POSITIVE_TC_IDX }, - { utc_livebox_refresh_p, POSITIVE_TC_IDX }, - { utc_livebox_refresh_n, NEGATIVE_TC_IDX }, - { utc_livebox_lb_pixmap_n, NEGATIVE_TC_IDX }, - { utc_livebox_lb_pixmap_p, POSITIVE_TC_IDX }, - { utc_livebox_pd_pixmap_p, POSITIVE_TC_IDX }, - { utc_livebox_pd_pixmap_n, NEGATIVE_TC_IDX }, - { utc_livebox_acquire_pd_pixmap_n, NEGATIVE_TC_IDX }, - { utc_livebox_acquire_pd_pixmap_p, POSITIVE_TC_IDX }, - { utc_livebox_release_pd_pixmap_n, NEGATIVE_TC_IDX }, - { utc_livebox_release_pd_pixmap_p, POSITIVE_TC_IDX }, - { utc_livebox_acquire_lb_pixmap_p, POSITIVE_TC_IDX }, - { utc_livebox_acquire_lb_pixmap_n, NEGATIVE_TC_IDX }, - { utc_livebox_release_lb_pixmap_p, POSITIVE_TC_IDX }, - { utc_livebox_release_lb_pixmap_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_visibility_p, POSITIVE_TC_IDX }, - { utc_livebox_set_visibility_n, NEGATIVE_TC_IDX }, - { utc_livebox_visibility_p, POSITIVE_TC_IDX }, - { utc_livebox_visibility_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_update_mode_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_update_mode_p, POSITIVE_TC_IDX }, - { utc_livebox_is_active_update_n, NEGATIVE_TC_IDX }, - { utc_livebox_is_active_update_p, POSITIVE_TC_IDX }, - { utc_livebox_set_manual_sync_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_manual_sync_p, POSITIVE_TC_IDX }, - { utc_livebox_manual_sync_p, POSITIVE_TC_IDX }, - { utc_livebox_manual_sync_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_frame_drop_for_resizing_n, NEGATIVE_TC_IDX }, - { utc_livebox_set_frame_drop_for_resizing_p, POSITIVE_TC_IDX }, - { utc_livebox_frame_drop_for_resizing_n, NEGATIVE_TC_IDX }, - { utc_livebox_frame_drop_for_resizing_p, POSITIVE_TC_IDX }, - { utc_livebox_sync_pd_fb_n, NEGATIVE_TC_IDX }, - { utc_livebox_sync_pd_fb_p, POSITIVE_TC_IDX }, - { utc_livebox_sync_lb_fb_p, POSITIVE_TC_IDX }, - { utc_livebox_sync_lb_fb_n, NEGATIVE_TC_IDX }, - { utc_livebox_alt_icon_p, POSITIVE_TC_IDX }, - { utc_livebox_alt_icon_n, NEGATIVE_TC_IDX }, - { utc_livebox_alt_name_p, POSITIVE_TC_IDX }, - { utc_livebox_alt_name_n, NEGATIVE_TC_IDX }, - { utc_livebox_acquire_fb_lock_n, NEGATIVE_TC_IDX }, - { utc_livebox_acquire_fb_lock_p, POSITIVE_TC_IDX }, - { utc_livebox_release_fb_lock_n, NEGATIVE_TC_IDX }, - { utc_livebox_release_fb_lock_p, POSITIVE_TC_IDX }, - { NULL, 0 }, -}; - diff --git a/doc/livebox-viewer_doc.h b/doc/livebox-viewer_doc.h deleted file mode 100644 index 850d08d..0000000 --- a/doc/livebox-viewer_doc.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * 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 CAPI_LIVEBOX_FRAMEWORK - * \defgroup CAPI_LIVEBOX_VIEWER_MODULE Livebox Viewer - * \brief API for livebox viewer (widget screen, home screen, ...) - * \section CAPI_LIVEBOX_VIEWER_MODULE_HEADER Required Header - * \#include - * \section CAPI_LIVEBOX_VIEWER_MODULE_OVERVIEW Overview - * Tizen(SLP) homescreen S/W framework is supporing the live box. (aka widget which is similiar with the android widget) - * - * \image html front.jpg - * - * \subsection WhatIsTheLivebox 1. What is the Livebox - * The live box is the widget of the TIZEN. - * - * It works as a small application displayed on other applications' (such as homescreen, lockscreen, etc ...) view. - * Each live box can have (not a mandatory option) a PD (progressive disclosure) in which more detailed information can be found. - * The content of PD can be exposed when a certain gesture (e.g., flick-down) has been applied to the live box. - * If you are interested in developing a livebox, there are things you should know prior to making any source code for the box. - * To make your live box added to any live box viewer application (e.g., live panel in our case), then you need to create and prepare - * controller(SO file), layout script (EDJE for a PD if necessary), configuration files. - * - * A livebox is managed by data provider, since each SO file of a livebox is loaded on and controlled by data provider using predefined ABI. - * A viewer will receive any livebox's content in forms of "image file", "buffer" or "text" and display the content in various formats on its window. - * A livebox developer needs to make sure that your live box generates desirable content in-time on a explicit update-request or periodic update. - * - * After a data provider loads a livebox's SO file, it then assigns a specific "file name" for the livebox via an argument of a livebox function. - * Since then the livebox just generates content using then given file name. - * Passing an image file (whose name is the previously given name) is the basic method for providing contents to the viewer. - * But if you want play animation or handles user event in real-time, you can use the buffer type. - * - * And you should prepare the content of the Progressive Disclosure. - * The Progressive Dislcosure is only updated by the "buffer" type. so you should prepare the layout script for it. - * If you didn't install any script file for progressive disclosure, the viewer will ignore the "flick down" event from your livebox. - * - * \subsubsection Livebox 1.1 Livebox - * Live box is a default content of your widget. It always displays on the screen and updated periodically. - * It looks like below captured images. - * \image html weather.png Weather Livebox - * \image html stock.png Stock Livebox - * \image html twitter.png Twitter Livebox - * - * \subsubsection ProgressiveDisclosure 1.2 Progressive Disclosure - * \image html PD.png Progressive Disclosure - * Progressive disclosure will be displayed when a user flicks down a livebox. (basically it depends on the implementation of the view applications) - * To supports this, a developer should prepare the layout script (EDJE only for the moment) of the livebox's PD. (or you can use the buffer directly) - * Data provider supports EDJE script but the developer can use various scripts if (which is BIG IF) their interpreters can be implemented based on evas & ecore. - * - * When a layout script has been installed, data provider can load and rendering the given layout on the buffer. - * The content on the buffer can be shared between applications that need to display the content on their window. - * Description data file is necessary to place proper content components in rendered layout. - * Check this page Description Data. - * - * \subsubsection ClusterCategory 1.3 What is the "cluster" and "category" - * The cluster and the sub-cluster is just like the grouping concept. - * It is used for creating/destorying your livebox instance when the data provider receives any context event from the context engine. - * You will only get "user,created" cluster and "default" category(sub cluster) info. - * - * \subsection LiveboxContent 2. How the livebox can draw contents for viewer? - * There are several ways to update the content of a livebox. - * - * \li Image file based content updating - * \li Description file based content updating (with the layout script file) - * \li Buffer based content updating - * - * Each method has specific benefit for implementing the livebox. - * - * \subsubsection ImageFormat 2.1 Via image file - * This is the basic method for providing content of a livebox to the viewer application. - * But this can be used only for the livebox. (Unavailable for the progressive disclosure). - * When your livebox is created, the provider will assign an unique ID for your livebox(it would be a filename). - * You should keep that ID until your livebox is running. The ID will be passed to you via livebox_create function. - * \image html image_format.png - * - * When you need to update the output of your livebox, you should generate the image file using given ID(filename). - * Then the data provider will recognize the event of updated output of a livebox and it will send that event to the viewer to reload it on the screen. - * - * \subsubsection ScriptFormat 2.2 Via layout script - * \image html script_format.png - * This method is supported for static layout & various contents (text & image) - * When you develop your livebox, first design the layout of box content using script (edje is default) - * Then the provider will load it to the content buffer and start rendering. - * After the sciprt is loaded, you can fill it using description data format. - * liblivebox defines description data handling functions. - * - * \subsubsection TextFormat 2.3 Via text data - * \image html text_format.png - * This is the simplified method to update the content of livebox. - * So your box only need to update the text data using description data format. - * Then the viewer will parse it to fill its screen. - * So there is no buffer area, just viewer decide how handles it. - * - * \subsubsection BufferFormat 2.4 Via buffer - * This method is very complex to implement. - * The provider will give a content buffer to you, then your box should render its contents on this buffer. - * This type is only supported for 3rd party livebox such as OSP and WEB. - * Inhouse(EFL) livebox is not able to use this buffer type for the box content. - * - * \subsection PackageNTools 3. How can I get the development packages or tools? - * - * \subsection DevelopLivebox 4. How can I write a new livebox - * - * \subsection TestLivebox 5. How can I test my livebox - * - * \subsection LiveboxDirectory 6. Livebox directory hierachy - * \image html preload_folder.png - * \image html download_folder.png - * - */ - diff --git a/dynamicbox_viewer/CMakeLists.txt b/dynamicbox_viewer/CMakeLists.txt new file mode 100644 index 0000000..ed8efa1 --- /dev/null +++ b/dynamicbox_viewer/CMakeLists.txt @@ -0,0 +1,98 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(dynamicbox_viewer 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 1) +SET(VERSION "${VERSION_MAJOR}.0.0") + +SET(CMAKE_SKIP_BUILD_RPATH true) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED + dlog + aul + glib-2.0 + gio-2.0 + com-core + sqlite3 + db-util + dynamicbox_service + vconf +) + +SET(BUILD_SOURCE + src/client.c + src/conf.c + src/desc_parser.c + src/dlist.c + src/dynamicbox.c + src/dynamicbox_internal.c + src/file_service.c + src/master_rpc.c + src/util.c +) + +IF (X11_SUPPORT) +pkg_check_modules(pkgs_extra REQUIRED + x11 + xext +) + +SET(BUILD_SOURCE + ${BUILD_SOURCE} + src/fb.c +) +ADD_DEFINITIONS("-DHAVE_X11") +ENDIF (X11_SUPPORT) + +IF (WAYLAND_SUPPORT) +SET(BUILD_SOURCE + ${BUILD_SOURCE} + src/fb_wayland.c +) +ADD_DEFINITIONS("-DHAVE_WAYLAND") +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 -Wall -Werror -Winline -g") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") +ADD_DEFINITIONS("-DLOG_TAG=\"DYNAMICBOX_VIEWER\"") +ADD_DEFINITIONS("-DNDEBUG") +ADD_DEFINITIONS("-D_USE_ECORE_TIME_GET") +#ADD_DEFINITIONS("-DFLOG") +ADD_DEFINITIONS("-DMASTER_PKGNAME=\"data-provider-master\"") +ADD_DEFINITIONS("-DINFO_SOCKET=\"/opt/usr/share/live_magazine/.live.socket\"") +ADD_DEFINITIONS("-DCLIENT_SOCKET=\"/opt/usr/share/live_magazine/.client.socket\"") +ADD_DEFINITIONS("-DSLAVE_SOCKET=\"/opt/usr/share/live_magazine/.slave.socket\"") +ADD_DEFINITIONS("-DSERVICE_SOCKET=\"/opt/usr/share/live_magazine/.service.socket\"") +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_CURRENT_SOURCE_DIR}/include/dynamicbox.h DESTINATION include/${PROJECT_NAME}) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}") diff --git a/LICENSE b/dynamicbox_viewer/LICENSE similarity index 100% rename from LICENSE rename to dynamicbox_viewer/LICENSE diff --git a/dynamicbox_viewer/doc/dynamicbox_viewer_doc.h b/dynamicbox_viewer/doc/dynamicbox_viewer_doc.h new file mode 100644 index 0000000..bc13a86 --- /dev/null +++ b/dynamicbox_viewer/doc/dynamicbox_viewer_doc.h @@ -0,0 +1,197 @@ +/* + * 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 CAPI_DYNAMICBOX_FRAMEWORK + * @defgroup DYNAMICBOX_VIEWER_MODULE Dynamic Box Viewer + * @brief API for dynamic box viewer (widget screen, home screen, ...) + * @section DYNAMICBOX_VIEWER_MODULE_HEADER Required Header + * \#include + * @section DYNAMICBOX_VIEWER_MODULE_OVERVIEW Overview + * Tizen homescreen S/W framework is supporing the Dynamic Box. (aka widget which is similiar with the android widget) + * + * @image html front.jpg + * + * @subsection WhatIsTheDynamicBox 1. What is the Dynamic Box + * The Dynamic Box is the widget of the TIZEN. + * + * It works as a small application displayed on other applications' (such as homescreen, lockscreen, etc ...) view. + * Each Dynamic Box can have (not a mandatory option) a Glance Bar (Glance Bar) in which more detailed information can be found. + * The content of Glance Bar can be exposed when a certain gesture (e.g., flick-down) has been applied to the Dynamic Box. + * If you are interested in developing a dynamic box, there are things you should know prior to making any source code for the box. + * To make your Dynamic Box added to any Dynamic Box viewer application (e.g., live panel in our case), then you need to create and prepare + * controller(SO file), layout script (EDJE for a Glance Bar if necessary), configuration files. + * + * A dynamic box is managed by data provider, since each SO file of a dynamic box is loaded on and controlled by data provider using predefined ABI. + * A viewer will receive any dynamic box's content in forms of "image file", "buffer" or "text" and display the content in various formats on its window. + * A dynamic box developer needs to make sure that your Dynamic Box generates desirable content in-time on a explicit update-request or periodic update. + * + * After a data provider loads a dynamic box's SO file, it then assigns a specific "file name" for the dynamic box via an argument of a dynamic box function. + * Since then the dynamic box just generates content using then given file name. + * Passing an image file (whose name is the previously given name) is the basic method for providing contents to the viewer. + * But if you want play animation or handles user event in real-time, you can use the buffer type. + * + * And you should prepare the content of the Glance Bar. + * The Glance Bar is only updated by the "buffer" type. so you should prepare the layout script for it. + * If you didn't install any script file for Glance Bar, the viewer will ignore the "flick down" event from your dynamic box. + * + * @subsubsection DynamicBox 1.1 Dynamic Box + * Live box is a default content of your widget. It always displays on the screen and updated periodically. + * It looks like below captured images. + * @image html weather.png Weather Dynamic Box + * @image html stock.png Stock Dynamic Box + * @image html twitter.png Twitter Dynamic Box + * + * @subsubsection GlanceBar 1.2 Glance Bar + * @image html PD.png Glance Bar + * Glance Bar will be displayed when a user flicks down a dynamic box. (basically it depends on the implementation of the viewer applications) + * To supports this, a developer should prepare the layout script (EDJE only for the moment) of the dynamic box's Glance Bar. (or you can use the buffer directly) + * Data provider supports EDJE script but the developer can use various scripts if (which is BIG IF) their interpreters can be implemented based on evas & ecore. + * + * When a layout script has been installed, data provider can load and rendering the given layout on the buffer. + * The content on the buffer can be shared between applications that need to display the content on their window. + * Description data file is necessary to place proper content components in rendered layout. + * Check this page Description Data. + * + * @subsubsection ClusterCategory 1.3 What is the "cluster" and "category" + * The cluster and the sub-cluster is just like the grouping concept. + * It is used for creating/destorying your dynamic box instance when the data provider receives any context event from the context engine. + * You will only get "user,created" cluster and "default" category(sub cluster) info. + * + * @subsection DynamicBoxContent 2. How the dynamic box can draw contents for viewer? + * There are several ways to update the content of a dynamic box. + * + * @li Image file based content updating + * @li Description file based content updating (with the layout script file) + * @li Buffer based content updating + * + * Each method has specific benefit for implementing the dynamic box. + * + * @subsubsection ImageFormat 2.1 Via image file + * This is the basic method for providing content of a dynamic box to the viewer application. + * But this can be used only for the dynamic box. (Unavailable for the Glance Bar). + * When your dynamic box is created, the provider will assign an unique ID for your dynamic box(it would be a filename). + * You should keep that ID until your dynamic box is running. The ID will be passed to you via dynamicbox_create function. + * \image html image_format.png + * + * When you need to update the output of your dynamic box, you should generate the image file using given ID(filename). + * Then the data provider will recognize the event of updated output of a dynamic box and it will send that event to the viewer to reload it on the screen. + * + * @subsubsection ScriptFormat 2.2 Via layout script + * @image html script_format.png + * This method is supported for static layout & various contents (text & image) + * When you develop your dynamic box, first design the layout of box content using script (edje is default) + * Then the provider will load it to the content buffer and start rendering. + * After the sciprt is loaded, you can fill it using description data format. + * libdynamicbox defines description data handling functions. + * + * @subsubsection TextFormat 2.3 Via text data + * @image html text_format.png + * This is the simplified method to update the content of dynamic box. + * So your box only need to update the text data using description data format. + * Then the viewer will parse it to fill its screen. + * So there is no buffer area, just viewer decide how handles it. + * + * @subsubsection BufferFormat 2.4 Via buffer + * This method is very complex to implement. + * The provider will give a content buffer to you, then your box should render its contents on this buffer. + * This type is only supported for 3rd party dynamic box such as OSP and WEB. + * Inhouse(EFL) dynamic box is not able to use this buffer type for the box content. + * + * @subsection DynamicBoxDirectory 3. Dynamic Box directory hierachy + * @image html preload_folder.png + * @image html download_folder.png + * + * @subsection WritingViewerApp 4. Writing a new application for displaying Dynamic Boxes + * If you want install dynamic boxes on your application screen, you should initialize the viewer system first. + * + * @code + * extern int dynamicbox_init(void *disp, int prevent_overwrite, double event_filter, int use_thread); + * @endcode + * + * @a disp should be current display object. if we are on X11 based windowing system, it will give you a Display Object, when you connect to X Server. + * Viewer application also needs it to preparing rendering buffer to display contents of dynamic boxes. + * + * @a prevent_overwirte flag is used for image or script type dynamic boxes. + * If this option is turn on, the viewer library will copy the image file of dyanmic box content to "reader" folder. + * To prevent from overwriting content image file. + * + * @a event_filter is used for feeding events. + * Basically, the dynamic box can be feed touch event by viewer application or master widget controller. (aka, data-provider-master). + * If a viewer feeds event to the dynamic box, it could more slow than data-provider-master's direct feeding. + * But sometimes, the viewer requires to feeds event by itself. + * In that case, we should choose the feeding option. feeding every events can be slow down. + * To save it, this event_filter will be used. if the event is generated in this time-gap, it will be ignored. + * + * @a use_thread if this flag is turned on, the viewer library will create a new thread for handling the IPC packets only. + * It will helps to increase the throughput of main thread. because it will not be interrupted to handles IPC packets. + * + * After the viewer is initiated, you can create a new box and locate it in your screen. + * + * Opposite function is "dynamicbox_fini" + * + * @code + * extern int dynamicbox_fini(void); + * @endcode + * + * Here is a sample code + * + * @code + * #include + * #include + * #include + * #include + * + * #include + * + * int errno; + * + * static bool _create_cb(void *data) + * { + * int ret; + * ret = dynamicbox_init(NULL, 1, 0.0f, 1); + * if (ret != DBOX_STATUS_ERROR_NONE) { + * LOGE("Failed to initialize the dynamic box viewer"); + * } + * return true; + * } + * + * static void _terminate_cb(void *data) + * { + * dynamicbox_fini(); + * } + * + * int main(int argc, char *argv[]) + * { + * app_event_callback_s event_callback; + * event_callback.create = _create_cb; + * event_callback.terminate = _terminate_cb; + * event_callback.pause = _pause_cb; + * event_callback.resume = _resume_cb; + * event_callback.app_control = _app_control; + * event_callback.low_memory = NULL; + * event_callback.low_battery = NULL; + * event_callback.device_orientation = NULL; + * event_callback.language_changed = _language_changed; + * event_callback.region_format_changed = NULL; + * + * return app_efl_main(&argc, &argv, &event_callback, &main_info); + * } + * @endocde + * + * If you want add a new dynamic box, you can call "dynamicbox_add()" function. + * + */ diff --git a/doc/image/PD.png b/dynamicbox_viewer/doc/image/PD.png similarity index 100% rename from doc/image/PD.png rename to dynamicbox_viewer/doc/image/PD.png diff --git a/doc/image/download_folder.png b/dynamicbox_viewer/doc/image/download_folder.png similarity index 100% rename from doc/image/download_folder.png rename to dynamicbox_viewer/doc/image/download_folder.png diff --git a/doc/image/front.jpg b/dynamicbox_viewer/doc/image/front.jpg similarity index 100% rename from doc/image/front.jpg rename to dynamicbox_viewer/doc/image/front.jpg diff --git a/doc/image/image_format.png b/dynamicbox_viewer/doc/image/image_format.png similarity index 100% rename from doc/image/image_format.png rename to dynamicbox_viewer/doc/image/image_format.png diff --git a/doc/image/message.png b/dynamicbox_viewer/doc/image/message.png similarity index 100% rename from doc/image/message.png rename to dynamicbox_viewer/doc/image/message.png diff --git a/doc/image/preload_folder.png b/dynamicbox_viewer/doc/image/preload_folder.png similarity index 100% rename from doc/image/preload_folder.png rename to dynamicbox_viewer/doc/image/preload_folder.png diff --git a/doc/image/script_format.png b/dynamicbox_viewer/doc/image/script_format.png similarity index 100% rename from doc/image/script_format.png rename to dynamicbox_viewer/doc/image/script_format.png diff --git a/doc/image/stock.png b/dynamicbox_viewer/doc/image/stock.png similarity index 100% rename from doc/image/stock.png rename to dynamicbox_viewer/doc/image/stock.png diff --git a/doc/image/text_format.png b/dynamicbox_viewer/doc/image/text_format.png similarity index 100% rename from doc/image/text_format.png rename to dynamicbox_viewer/doc/image/text_format.png diff --git a/doc/image/twitter.png b/dynamicbox_viewer/doc/image/twitter.png similarity index 100% rename from doc/image/twitter.png rename to dynamicbox_viewer/doc/image/twitter.png diff --git a/doc/image/weather.png b/dynamicbox_viewer/doc/image/weather.png similarity index 100% rename from doc/image/weather.png rename to dynamicbox_viewer/doc/image/weather.png diff --git a/dynamicbox_viewer/dynamicbox_viewer.pc.in b/dynamicbox_viewer/dynamicbox_viewer.pc.in new file mode 100644 index 0000000..8d1c185 --- /dev/null +++ b/dynamicbox_viewer/dynamicbox_viewer.pc.in @@ -0,0 +1,12 @@ +prefix=@PREFIX@ +exec_prefix=@EXEC_PREFIX@ +libdir=@LIBDIR@ +includedir=@INCLUDEDIR@ + +Name: dynamicbox-viewer +Description: Support development of the Dynamic Box Viewer +Version: @VERSION@ +Requires.private: dynamicbox_service +Libs: -L${libdir} -ldynamicbox_viewer +Cflags: -I${includedir} +cppflags: -I${includedir} diff --git a/include/client.h b/dynamicbox_viewer/include/client.h similarity index 90% rename from include/client.h rename to dynamicbox_viewer/include/client.h index db8a931..dc7a744 100644 --- a/include/client.h +++ b/dynamicbox_viewer/include/client.h @@ -17,6 +17,8 @@ extern int client_init(int use_thread); extern int client_fd(void); extern const char *client_addr(void); +extern const char *client_direct_addr(void); +extern int client_direct_fd(void); extern int client_fini(void); /* End of a file */ diff --git a/include/conf.h b/dynamicbox_viewer/include/conf.h similarity index 71% rename from include/conf.h rename to dynamicbox_viewer/include/conf.h index 83f2ff4..de5375a 100644 --- a/include/conf.h +++ b/dynamicbox_viewer/include/conf.h @@ -18,12 +18,12 @@ * \note * milli seconds */ -#define MAX_LOG_FILE 3 -#define MAX_LOG_LINE 1000 -#define SLAVE_LOG_PATH "/tmp/.dbox.service/log/" +#define MAX_LOG_FILE 3 +#define MAX_LOG_LINE 1000 +#define SLAVE_LOG_PATH "/tmp/.dbox.service/log/" #if !defined(VCONFKEY_MASTER_STARTED) -#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started" +#define VCONFKEY_MASTER_STARTED "memory/data-provider-master/started" #endif #if !defined(VCONFKEY_MASTER_CLIENT_ADDR) @@ -38,5 +38,11 @@ extern void conf_set_shared_content(int flag); extern int conf_shared_content(void); extern double conf_event_filter(void); extern void conf_set_event_filter(double filter); +extern void conf_set_direct_update(int flag); +extern int conf_direct_update(void); +extern int conf_extra_buffer_count(void); +extern void conf_set_extra_buffer_count(int buffer_count); +extern dynamicbox_status_e conf_last_status(void); +extern void conf_set_last_status(dynamicbox_status_e status); /* End of a file */ diff --git a/include/debug.h b/dynamicbox_viewer/include/debug.h similarity index 89% rename from include/debug.h rename to dynamicbox_viewer/include/debug.h index d06862c..a6563ee 100644 --- a/include/debug.h +++ b/dynamicbox_viewer/include/debug.h @@ -15,8 +15,8 @@ */ #if !defined(FLOG) -#define DbgPrint(format, arg...) SECURE_LOGD(format, ##arg) -#define ErrPrint(format, arg...) SECURE_LOGE(format, ##arg) +#define DbgPrint(format, arg...) SECURE_LOGD(format, ##arg) +#define ErrPrint(format, arg...) SECURE_LOGE(format, ##arg) #else extern FILE *__file_log_fp; #define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) diff --git a/include/desc_parser.h b/dynamicbox_viewer/include/desc_parser.h similarity index 87% rename from include/desc_parser.h rename to dynamicbox_viewer/include/desc_parser.h index a7e0092..ccc7800 100644 --- a/include/desc_parser.h +++ b/dynamicbox_viewer/include/desc_parser.h @@ -14,6 +14,6 @@ * limitations under the License. */ -extern int parse_desc(struct livebox_common *common, const char *filename, int is_pd); +extern int parse_desc(struct dynamicbox_common *common, const char *filename, int is_pd); /* End of a file */ diff --git a/live.viewer/include/dlist.h b/dynamicbox_viewer/include/dlist.h similarity index 81% rename from live.viewer/include/dlist.h rename to dynamicbox_viewer/include/dlist.h index cd1a421..3f19827 100644 --- a/live.viewer/include/dlist.h +++ b/dynamicbox_viewer/include/dlist.h @@ -15,18 +15,18 @@ */ #define dlist_remove_data(list, data) do { \ - struct dlist *l; \ - l = dlist_find_data(list, data); \ - list = dlist_remove(list, l); \ + 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); (l) && ((data) = dlist_data(l)); (l) = dlist_next(l)) + for ((l) = (list); (l) && ((data) = dlist_data(l)); (l) = dlist_next(l)) #define dlist_foreach_safe(list, l, n, data) \ - for ((l) = (list), (n) = dlist_next(l); \ - (l) && ((data) = dlist_data(l)); \ - (l) = (n), (n) = dlist_next(l)) + for ((l) = (list), (n) = dlist_next(l); \ + (l) && ((data) = dlist_data(l)); \ + (l) = (n), (n) = dlist_next(l)) struct dlist; diff --git a/dynamicbox_viewer/include/dynamicbox.h b/dynamicbox_viewer/include/dynamicbox.h new file mode 100644 index 0000000..703a760 --- /dev/null +++ b/dynamicbox_viewer/include/dynamicbox.h @@ -0,0 +1,1675 @@ +/* + * 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 + +#ifndef __DYNAMICBOX_VIEWER_H +#define __DYNAMICBOX_VIEWER_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file dynamicbox.h + * @brief This file declares API of libdynamicbox-viewer library + * @since_tizen 2.3 + */ + +/** + * @addtogroup CAPI_DYNAMICBOX_VIEWER_MODULE + * @{ + */ + +/** + * @internal + * @brief Structure definition for a Dynamic Box instance. + * @since_tizen 2.3 + */ +typedef struct dynamicbox *dynamicbox_h; + +/** + * @internal + * @brief Definition for a default update period for Dynamicbox (defined in the package manifest file). + * @since_tizen 2.3 + */ +#define DBOX_DEFAULT_PERIOD -1.0f + +/** + * @internal + * @brief Enumeration for Mouse & Key event for buffer type Dynamic Box or Glance Bar. + * @details Viewer should send these events to dynamicbox. + * @since_tizen 2.3 + */ +typedef enum dynamicbox_mouse_event_type { + DBOX_MOUSE_EVENT_MASK = 0x20000000, /**< Mask value for mouse event */ + DBOX_MOUSE_EVENT_GBAR_MASK = 0x10000000, /**< Mask value for Glance Bar event */ + DBOX_MOUSE_EVENT_DBOX_MASK = 0x40000000, /**< Mask value for Dynamic Box event */ + + DBOX_MOUSE_EVENT_DOWN = 0x00000001, /**< Dynamic Box mouse down event for dynamicbox */ + DBOX_MOUSE_EVENT_UP = 0x00000002, /**< Dynamic Box mouse up event for dynamicbox */ + DBOX_MOUSE_EVENT_MOVE = 0x00000004, /**< Dynamic Box mouse move event for dynamicbox */ + DBOX_MOUSE_EVENT_ENTER = 0x00000008, /**< Dynamic Box mouse enter event for dynamicbox */ + DBOX_MOUSE_EVENT_LEAVE = 0x00000010, /**< Dynamic Box mouse leave event for dynamicbox */ + DBOX_MOUSE_EVENT_SET = 0x00000020, /**< Dynamic Box mouse set auto event for dynamicbox */ + DBOX_MOUSE_EVENT_UNSET = 0x00000040, /**< Dynamic Box mouse unset auto event for dynamicbox */ + + DBOX_MOUSE_EVENT_ON_SCROLL = 0x00000080, /**< Dynamic Box On scrolling */ + DBOX_MOUSE_EVENT_ON_HOLD = 0x00000100, /**< Dynamic Box On holding */ + DBOX_MOUSE_EVENT_OFF_SCROLL = 0x00000200, /**< Dynamic Box Stop scrolling */ + DBOX_MOUSE_EVENT_OFF_HOLD = 0x00000400, /**< Dynamic Box Stop holding */ + + DBOX_MOUSE_ON_SCROLL = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_ON_SCROLL, /**< Mouse event occurs while scrolling */ + DBOX_MOUSE_ON_HOLD = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_ON_HOLD, /**< Mouse event occurs on holding */ + DBOX_MOUSE_OFF_SCROLL = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_OFF_SCROLL, /**< Scrolling stopped */ + DBOX_MOUSE_OFF_HOLD = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_OFF_HOLD, /**< Holding stopped */ + + DBOX_MOUSE_DOWN = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_DOWN, /**< Mouse down on the dynamicbox */ + DBOX_MOUSE_UP = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_UP, /**< Mouse up on the dynamicbox */ + DBOX_MOUSE_MOVE = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_MOVE, /**< Move move on the dynamicbox */ + DBOX_MOUSE_ENTER = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_ENTER, /**< Mouse enter to the dynamicbox */ + DBOX_MOUSE_LEAVE = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_LEAVE, /**< Mouse leave from the dynamicbox */ + DBOX_MOUSE_SET = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_SET, /**< Mouse event, start feeding event by master */ + DBOX_MOUSE_UNSET = DBOX_MOUSE_EVENT_DBOX_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_UNSET, /**< Mouse event, stop feeding event by master */ + + DBOX_GBAR_MOUSE_ON_SCROLL = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_ON_SCROLL, /**< Mouse event occurs while scrolling */ + DBOX_GBAR_MOUSE_ON_HOLD = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_ON_HOLD, /**< Mouse event occurs on holding */ + DBOX_GBAR_MOUSE_OFF_SCROLL = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_OFF_SCROLL, /**< Scrolling stopped */ + DBOX_GBAR_MOUSE_OFF_HOLD = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_OFF_HOLD, /**< Holding stopped */ + + DBOX_GBAR_MOUSE_DOWN = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_DOWN, /**< Mouse down on the Glance Bar */ + DBOX_GBAR_MOUSE_UP = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_UP, /**< Mouse up on the Glance Bar */ + DBOX_GBAR_MOUSE_MOVE = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_MOVE, /**< Mouse move on the Glance Bar */ + DBOX_GBAR_MOUSE_ENTER = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_ENTER, /**< Mouse enter to the Glance Bar */ + DBOX_GBAR_MOUSE_LEAVE = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_LEAVE, /**< Mouse leave from the Glance Bar */ + DBOX_GBAR_MOUSE_SET = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_SET, /**< Mouse event, start feeding event by master */ + DBOX_GBAR_MOUSE_UNSET = DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_MASK | DBOX_MOUSE_EVENT_UNSET, /**< Mouse event, stop feeding event by master */ + + DBOX_MOUSE_EVENT_MAX = 0xFFFFFFFF /**< Unknown event */ +} dynamicbox_mouse_event_type_e; + +typedef enum dynamicbox_key_event_type { + DBOX_KEY_EVENT_MASK = 0x80000000, /**< Mask value for key event */ + DBOX_KEY_EVENT_GBAR_MASK = 0x10000000, /**< Mask value for Glance Bar event */ + DBOX_KEY_EVENT_DBOX_MASK = 0x40000000, /**< Mask value for Dynamic Box event */ + + DBOX_KEY_EVENT_DOWN = 0x00000001, /**< Dynamic Box key press */ + DBOX_KEY_EVENT_UP = 0x00000002, /**< Dynamic Box key release */ + DBOX_KEY_EVENT_FOCUS_IN = 0x00000008, /**< Dynamic Box key focused in */ + DBOX_KEY_EVENT_FOCUS_OUT = 0x00000010, /**< Dynamic Box key focused out */ + DBOX_KEY_EVENT_SET = 0x00000020, /**< Dynamic Box Key, start feeding event by master */ + DBOX_KEY_EVENT_UNSET = 0x00000040, /**< Dynamic Box key, stop feeding event by master */ + + DBOX_KEY_DOWN = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_DBOX_MASK | DBOX_KEY_EVENT_DOWN, /**< Key down on the dynamicbox */ + DBOX_KEY_UP = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_DBOX_MASK | DBOX_KEY_EVENT_UP, /**< Key up on the dynamicbox */ + DBOX_KEY_SET = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_DBOX_MASK | DBOX_KEY_EVENT_SET, /**< Key event, start feeding event by master */ + DBOX_KEY_UNSET = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_DBOX_MASK | DBOX_KEY_EVENT_UNSET, /**< Key event, stop feeding event by master */ + DBOX_KEY_FOCUS_IN = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_DBOX_MASK | DBOX_KEY_EVENT_FOCUS_IN, /**< Key event, focus in */ + DBOX_KEY_FOCUS_OUT = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_DBOX_MASK | DBOX_KEY_EVENT_FOCUS_OUT, /**< Key event, foucs out */ + + DBOX_GBAR_KEY_DOWN = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_GBAR_MASK | DBOX_KEY_EVENT_DOWN, /**< Key down on the dynamicbox */ + DBOX_GBAR_KEY_UP = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_GBAR_MASK | DBOX_KEY_EVENT_UP, /**< Key up on the dynamicbox */ + DBOX_GBAR_KEY_SET = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_GBAR_MASK | DBOX_KEY_EVENT_SET, /**< Key event, start feeding event by master */ + DBOX_GBAR_KEY_UNSET = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_GBAR_MASK | DBOX_KEY_EVENT_UNSET, /**< Key event, stop feeding event by master */ + DBOX_GBAR_KEY_FOCUS_IN = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_GBAR_MASK | DBOX_KEY_EVENT_FOCUS_IN, /**< Key event, focus in */ + DBOX_GBAR_KEY_FOCUS_OUT = DBOX_KEY_EVENT_MASK | DBOX_KEY_EVENT_GBAR_MASK | DBOX_KEY_EVENT_FOCUS_OUT, /**< Key event, focus out */ + + DBOX_KEY_EVENT_MAX = 0xFFFFFFFF /**< Unknown event */ +} dynamicbox_key_event_type_e; + +/** + * @internal + * @brief Enumeration for Accessibility event for buffer type Dynamic Box or Glance Bar. + * @details These events are sync'd with Tizen accessibility event set. + * @since_tizen 2.3 + */ +typedef enum dynamicbox_access_event_type { + DBOX_ACCESS_EVENT_GBAR_MASK = 0x10000000, /**< Glance Bar Accessibilivent mask */ + DBOX_ACCESS_EVENT_DBOX_MASK = 0x20000000, /**< Dynamic Box Accessibility event mask */ + + DBOX_ACCESS_EVENT_HIGHLIGHT = 0x00000100, /**< Dynamic Box accessibility: Hightlight a object, Next, Prev,Unhighlight */ + DBOX_ACCESS_EVENT_ACTIVATE = 0x00000200, /**< Dynamic Box accessibility activate */ + DBOX_ACCESS_EVENT_ACTION = 0x00000400, /**< Dynamic Box accessibility value changed, Up, Down */ + DBOX_ACCESS_EVENT_SCROLL = 0x00000800, /**< Dynamic Box accessibility scroll down, move, up */ + DBOX_ACCESS_EVENT_VALUE_CHANGE = 0x00001000, /**< LB accessibility value change */ + DBOX_ACCESS_EVENT_MOUSE = 0x00002000, /**< Give mouse event to highlight object, down, move, up */ + DBOX_ACCESS_EVENT_BACK = 0x00004000, /**< Go back to a previous view ex: pop naviframe item */ + DBOX_ACCESS_EVENT_OVER = 0x00008000, /**< Mouse over an object */ + DBOX_ACCESS_EVENT_READ = 0x00010000, /**< Highlight an object */ + DBOX_ACCESS_EVENT_ENABLE = 0x00020000, /**< Disable highlight and read ability, disable, enable */ + + DBOX_ACCESS_HIGHLIGHT = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_HIGHLIGHT, /**< Access event - Highlight an object in the dynamicbox */ + DBOX_ACCESS_ACTIVATE = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_ACTIVATE, /**< Access event - Launch or activate the highlighted object */ + DBOX_ACCESS_ACTION = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_ACTION, /**< Access event - down */ + DBOX_ACCESS_SCROLL = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_SCROLL, /**< Access event - scroll down */ + DBOX_ACCESS_VALUE_CHANGE = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_VALUE_CHANGE, /**< LB accessibility value change */ + DBOX_ACCESS_MOUSE = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_MOUSE, /**< Give mouse event to highlight object */ + DBOX_ACCESS_BACK = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_BACK, /**< Go back to a previous view ex: pop naviframe item */ + DBOX_ACCESS_OVER = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_OVER, /**< Mouse over an object */ + DBOX_ACCESS_READ = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_READ, /**< Highlight an object */ + DBOX_ACCESS_ENABLE = DBOX_ACCESS_EVENT_DBOX_MASK | DBOX_ACCESS_EVENT_ENABLE, /**< Enable highlight and read ability */ + + DBOX_GBAR_ACCESS_HIGHLIGHT = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_HIGHLIGHT, /**< Access event - Highlight an object in the Glance Bar */ + DBOX_GBAR_ACCESS_ACTIVATE = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_ACTIVATE, /**< Access event - Launch or activate the highlighted object */ + DBOX_GBAR_ACCESS_ACTION = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_ACTION, /**< Access event - down */ + DBOX_GBAR_ACCESS_SCROLL = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_SCROLL, /**< Access event - scroll down */ + DBOX_GBAR_ACCESS_VALUE_CHANGE = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_VALUE_CHANGE, /**< LB accessibility value change */ + DBOX_GBAR_ACCESS_MOUSE = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_MOUSE, /**< Give mouse event to highlight object */ + DBOX_GBAR_ACCESS_BACK = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_BACK, /**< Go back to a previous view ex: pop naviframe item */ + DBOX_GBAR_ACCESS_OVER = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_OVER, /**< Mouse over an object */ + DBOX_GBAR_ACCESS_READ = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_READ, /**< Highlight an object */ + DBOX_GBAR_ACCESS_ENABLE = DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_ENABLE, /**< Enable highlight and read ability */ + DBOX_GBAR_ACCESS_EVENT_MAX = 0xFFFFFFFF +} dynamicbox_access_event_type_e; + +/** + * @internal + * @brief Enumeration for Dynamic Box content type. + * @since_tizen 2.3 + */ +typedef enum dynamicbox_type { + DBOX_CONTENT_TYPE_IMAGE = 0x01, /**< Contents of a dynamicbox is based on the image file */ + DBOX_CONTENT_TYPE_BUFFER = 0x02, /**< Contents of a dynamicbox is based on canvas buffer(shared) */ + DBOX_CONTENT_TYPE_TEXT = 0x04, /**< Contents of a dynamicbox is based on formatted text file */ + DBOX_CONTENT_TYPE_RESOURCE_ID = 0x08, /**< Contens of a dynamicbox is shared by the resource id(depends on window system) */ + DBOX_CONTENT_TYPE_UIFW = 0x10, /**< Using UI F/W resource for sharing content & event */ + DBOX_CONTENT_TYPE_INVALID = 0xFF /**< Unknown Dynamic Box type */ +} dynamicbox_type_e; + +/** + * @internal + * @brief Enumeration for Dynamicbox event type. + * @details These events will be sent from the provider. + * @since_tizen 2.3 + */ +typedef enum dynamicbox_event_type { /**< dynamicbox_event_handler_set Event list */ + DBOX_EVENT_DBOX_UPDATED, /**< Contents of the given dynamicbox is updated */ + DBOX_EVENT_DBOX_EXTRA_UPDATED, + DBOX_EVENT_GBAR_UPDATED, /**< Contents of the given pd is updated */ + DBOX_EVENT_GBAR_EXTRA_UPDATED, + + DBOX_EVENT_CREATED, /**< A new dynamicbox is created */ + DBOX_EVENT_DELETED, /**< A dynamicbox is deleted */ + + DBOX_EVENT_GROUP_CHANGED, /**< Group (Cluster/Sub-cluster) information is changed */ + DBOX_EVENT_PINUP_CHANGED, /**< PINUP status is changed */ + DBOX_EVENT_PERIOD_CHANGED, /**< Update period is changed */ + + DBOX_EVENT_DBOX_SIZE_CHANGED, /**< Dynamicbox size is changed */ + DBOX_EVENT_GBAR_SIZE_CHANGED, /**< Glance Bar size is changed */ + + DBOX_EVENT_GBAR_CREATED, /**< If a Glance Bar is created even if you didn't call the dynamicbox_create_glance_bar API */ + DBOX_EVENT_GBAR_DESTROYED, /**< If a Glance Bar is destroyed even if you didn't call the dynamicbox_destroy_glance_bar API */ + + DBOX_EVENT_HOLD_SCROLL, /**< If the screen should be freezed */ + DBOX_EVENT_RELEASE_SCROLL, /**< If the screen can be scrolled */ + + DBOX_EVENT_DBOX_UPDATE_BEGIN, /**< Dynamic Box content update is started */ + DBOX_EVENT_DBOX_UPDATE_END, /**< Dynamic Box content update is finished */ + + DBOX_EVENT_GBAR_UPDATE_BEGIN, /**< Glance Bar content update is started */ + DBOX_EVENT_GBAR_UPDATE_END, /**< Glance Bar content update is finished */ + + DBOX_EVENT_UPDATE_MODE_CHANGED, /**< Dynamic Box Update mode is changed */ + + DBOX_EVENT_REQUEST_CLOSE_GBAR, /**< Dynamic Box requests to close the Glance Bar */ + + DBOX_EVENT_EXTRA_INFO_UPDATED, /**< Extra information is updated */ + + DBOX_EVENT_DBOX_EXTRA_BUFFER_CREATED, /**< DBOX Extra Buffer created event */ + DBOX_EVENT_GBAR_EXTRA_BUFFER_CREATED, /**< GBAR Extra Buffer created event */ + + DBOX_EVENT_DBOX_EXTRA_BUFFER_DESTROYED, /**< DBOX Extra Buffer destroyed event */ + DBOX_EVENT_GBAR_EXTRA_BUFFER_DESTROYED, /**< DBOX Extra Buffer destroyed event */ + + DBOX_EVENT_IGNORED = 0xFF /**< Request is ignored */ +} dynamicbox_event_type_e; + +/** + * @internal + * @brief Enumeration for Dynamicbox option types. + * @since_tizen 2.3 + */ +typedef enum dynamicbox_option_type { + DBOX_OPTION_MANUAL_SYNC, /**< Sync frame manually */ + DBOX_OPTION_FRAME_DROP_FOR_RESIZE, /**< Drop frames while resizing */ + DBOX_OPTION_SHARED_CONTENT, /**< Use only one real instance for multiple fake instances if user creates dbox for same content */ + DBOX_OPTION_DIRECT_UPDATE, /**< Use the private socket for receiving updated event */ + DBOX_OPTION_EXTRA_BUFFER_CNT, /**< Extra buffer count, ReadOnly value */ + + DBOX_OPTION_ERROR = 0xFFFFFFFF /**< To specify the size of this enumeration type */ +} dynamicbox_option_type_e; + +/** + * @internal + * @brief Reason of faults + * @since_tizen 2.3 + */ +typedef enum dynamicbox_fault_type { + DBOX_FAULT_DEACTIVATED, /**< Dynamicbox is deactivated by its fault operation */ + DBOX_FAULT_PROVIDER_DISCONNECTED, /**< Provider is disconnected */ + DBOX_FAULT_MAX = 0xFF /**< To specify the size of this enumeration type, some compiler enjoy of this kind of notation */ +} dynamicbox_fault_type_e; + +/** + * @internal + * @brief Enumeration for Dynamicbox visible states. + * @details Must be sync'd with a provider. + * @since_tizen 2.3 + */ +typedef enum dynamicbox_visible_state { + DBOX_SHOW = 0x00, /**< Dynamicbox is shown. Default state */ + DBOX_HIDE = 0x01, /**< Dynamicbox is hidden, Update timer will not be freezed. but you cannot receive any updates events. */ + + DBOX_HIDE_WITH_PAUSE = 0x02, /**< Dynamicbox is hidden, it will pause the update timer, but if a dynamicbox updates its contents, update event will be triggered */ + + DBOX_VISIBLE_ERROR = 0xFF /**< To specify the size of this enumeration type */ +} dynamicbox_visible_state_e; + +/** + * @internal + * @brief Accessibility Event type + * @since_tizen 2.3 + * @see dynamicbox_feed_access_event() + */ +typedef enum dynamicbox_access_info_type { + DBOX_ACCESS_TYPE_NONE = 0x00, /**< Initialized */ + + DBOX_ACCESS_TYPE_DOWN = 0x00, /**< Mouse down */ + DBOX_ACCESS_TYPE_MOVE = 0x01, /**< Mouse move */ + DBOX_ACCESS_TYPE_UP = 0x02, /**< Mouse up */ + + DBOX_ACCESS_TYPE_HIGHLIGHT = 0x00, /**< Highlight */ + DBOX_ACCESS_TYPE_HIGHLIGHT_NEXT = 0x01, /**< Highlight next */ + DBOX_ACCESS_TYPE_HIGHLIGHT_PREV = 0x02, /**< Highlight prev */ + DBOX_ACCESS_TYPE_UNHIGHLIGHT = 0x03, /**< Unhighlight */ + + DBOX_ACCESS_TYPE_DISABLE = 0x00, /**< Disable */ + DBOX_ACCESS_TYPE_ENABLE = 0x01 /**< Enable */ +} dynamicbox_access_info_type_e; + +/** + * @internal + * @brief Accessibility Event Information + * @since_tizen 2.3 + */ +typedef struct dynamicbox_access_event_info { + double x; /**< X Coordinates that the event occurred */ + double y; /**< Y Coordinates that the event occurred */ + dynamicbox_access_info_type_e type; /**< Accessibility event type */ + int info; /**< Extra information for this event */ +} *dynamicbox_access_event_info_t; + +/** + * @internal + * @brief Damaged Region representation + * @since_tizen 2.3 + */ +typedef struct dynamicbox_damage_region { + int x; /**< Coordinates X of Left-Top corner */ + int y; /**< Coordinates Y of Left-Top corner */ + int w; /**< Damage'd Width */ + int h; /**< Damage'd Height */ +} dynamicbox_damage_region_t; + +/** + * @internal + * @brief Mouse Event Information + * @since_tizen 2.3 + */ +typedef struct dynamicbox_mouse_event_info { + double x; /**< X coordinates of Mouse Event */ + double y; /**< Y coordinates of Mouse Event */ +} *dynamicbox_mouse_event_info_t; + +/** + * @internal + * @brief Key Event Information + * @since_tizen 2.3 + */ +typedef struct dynamicbox_key_event_info { + unsigned int keycode; /**< Key code */ +} *dynamicbox_key_event_info_t; + +/** + * @internal + * @brief Text Event Information + * @since_tizen 2.3 + */ +typedef struct dynamicbox_text_event { + const char *emission; + const char *source; + struct { + double sx; + double sy; + double ex; + double ey; + } geometry; +} *dynamicbox_text_event_t; + +/** + * @internal + * @brief Structure for TEXT type dynamicbox contents handling opertators. + * @since_tizen 2.3 + */ +typedef struct dynamicbox_script_operators { + int (*update_begin)(dynamicbox_h handle); /**< Content parser is started */ + int (*update_end)(dynamicbox_h handle); /**< Content parser is finished */ + + /* Listed functions will be called when parser meets each typed content */ + int (*update_text)(dynamicbox_h handle, const char *id, const char *part, const char *data); /**< Update text content */ + int (*update_image)(dynamicbox_h handle, const char *id, const char *part, const char *data, const char *option); /**< Update image content */ + int (*update_script)(dynamicbox_h handle, const char *id, const char *new_id, const char *part, const char *file, const char *group); /**< Update script content */ + int (*update_signal)(dynamicbox_h handle, const char *id, const char *emission, const char *signal); /**< Update signal */ + int (*update_drag)(dynamicbox_h handle, const char *id, const char *part, double dx, double dy); /**< Update drag info */ + int (*update_info_size)(dynamicbox_h handle, const char *id, int w, int h); /**< Update content size */ + int (*update_info_category)(dynamicbox_h handle, const char *id, const char *category); /**< Update content category info */ + int (*update_access)(dynamicbox_h handle, const char *id, const char *part, const char *text, const char *option); /**< Update access information */ + int (*operate_access)(dynamicbox_h handle, const char *id, const char *part, const char *operation, const char *option); /**< Update access operation */ + int (*update_color)(dynamicbox_h handle, const char *id, const char *part, const char *data); /**< Update color */ +} *dynamicbox_script_operator_t; + +/** + * @internal + * @brief Called for every async function. + * @details Prototype of the return callback of every async functions. + * @since_tizen 2.3 + * @param[in] handle Handle of the dynamicbox instance + * @param[in] ret Result status of operation (DBOX_STATUS_XXX defined from libdynamicbox-service) + * @param[in] data Data for result callback + * @return void + * @see dynamicbox_add() + * @see dynamicbox_del() + * @see dynamicbox_activate() + * @see dynamicbox_resize() + * @see dynamicbox_set_group() + * @see dynamicbox_set_period() + * @see dynamicbox_access_event() + * @see dynamicbox_set_pinup() + * @see dynamicbox_create_glance_bar() + * @see dynamicbox_destroy_glance_bar() + * @see dynamicbox_emit_text_signal() + * @see dynamicbox_acquire_resource_id() + * @see dynamicbox_set_update_mode() + */ +typedef void (*dynamicbox_ret_cb)(dynamicbox_h handle, int ret, void *data); + +/** + * @internal + * @brief Fault event handler + * @param[in] type Type of fault event. + * @param[in] dbox_id Faulted DynamicBox Id + * @param[in] file faulted filename (implementation file if it is supported) + * @param[in] func faulted function name (if it is supported) + * @param[in] data Callback data + * @return int status + * @retval @c EXIT_FAILURE delete this event callback from the event callback list + * @retval @c EXIT_SUCCESS successfully handled, keep this callback in the event callback list + */ +typedef int (*dynamicbox_fault_handler_cb)(enum dynamicbox_fault_type type, const char *dbox_id, const char *file, const char *func, void *data); + +/** + * @internal + * @brief Event handler + * @since_tizen 2.3 + * @param[in] handler Dynamic Box Event handler + * @param[in] event Event type for Dynamic Box + * @param[in] data Callback Data + * @return int status + * @return @c EXIT_FAILURE delete this event callback from the event callback list + * @return @c EXIT_SUCCESS successfully handled, keep this callback in the event callback list + */ +typedef int (*dynamicbox_event_handler_cb)(dynamicbox_h handler, dynamicbox_event_type_e event, void *data); + +/** + * @internal + * @brief Auto launch handler + * @since_tizen 2.3 + * @param[in] handler DynamicBox Handler + * @param[in] appid UI Application Id, which should be launched + * @param[in] data callback data + */ +typedef int (*dynamicbox_auto_launch_handler_cb)(dynamicbox_h handler, const char *appid, void *data); + +/** + * @internal + * @brief Initializes the dynamicbox system with some options. + * @details dynamicbox_init function uses environment value to initiate some configurable values. + * But some applications do not want to use the env value. + * For them, this API will give a chance to set default options using given arguments. + * @a disp is a Display object which is used to hold a connection with a display server (eg, Xorg) + * @since_tizen 2.3 + * @param[in] disp Display, If @a disp is @c NULL, the library will try to acquire a new connection to display server + * @param[in] prevent_overwrite Overwrite flag (when the content of an image type dynamicbox is updated, it will be overwriten (0) or not (1)) + * @param[in] event_filter If the dynamicbox_feed_mouse_event() is called again in this secs, it will be ignored and the dynamicbox_feed_mouse_event() will returns DBOX_STATUS_ERROR_BUSY status code + * @param[in] use_thread If this value has true, the viewer library will create a new thread to communicate with master service + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int Integer, Dynamicbox status code + * @retval #DBOX_STATUS_ERROR_NONE if successfully initialized. + * @retval #DBOX_STATUS_ERROR_OUT_OF_MEMORY If a memory is not enough to do this operation. + * @retval #DBOX_STATUS_ERROR_IO_ERROR If fails to access dynamicbox database. + * @see dynamicbox_fini() + * @see dynamicbox_feed_mouse_event() + */ +extern int dynamicbox_init(void *disp, int prevent_overwrite, double event_filter, int use_thread); + +/** + * @internal + * @brief Finalizes the dynamicbox system. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_SUCCES if success + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER if dynamicbox_init is not called + * @see dynamicbox_init() + */ +extern int dynamicbox_fini(void); + +/** + * @internal + * @brief Notifies the status of a client ("it is paused") to the provider. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE if success + * @retval #DBOX_STATUS_ERROR_FAULT if it failed to send state (paused) info + * @see dynamicbox_client_set_resumed() + */ +extern int dynamicbox_viewer_set_paused(void); + +/** + * @internal + * @brief Notifies the status of client ("it is resumed") to the provider. + * @since_tizen 2.3 + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE if success + * @retval #DBOX_STATUS_ERROR_FAULT if it failed to send state (resumed) info + * @see dynamicbox_client_set_paused() + */ +extern int dynamicbox_viewer_set_resumed(void); + +/** + * @internal + * @brief Adds a new dynamicbox. + * @details If the screen size is "1280x720", the below size lists are used for default. + * Or you can find the default sizes in pixel from /usr/share/data-provider-master/resolution.ini. + * Size types are defined from the libdynamicbox-service package (dynamicbox-service.h). + * + * Normal mode dynamicbox + * 1x1=175x175, #DBOX_SIZE_TYPE_1x1 + * 2x1=354x175, #DBOX_SIZE_TYPE_2x1 + * 2x2=354x354, #DBOX_SIZE_TYPE_2x2 + * 4x1=712x175, #DBOX_SIZE_TYPE_4x1 + * 4x2=712x354, #DBOX_SIZE_TYPE_4x2 + * 4x4=712x712, #DBOX_SIZE_TYPE_4x4 + * + * Extended sizes + * 4x3=712x533, #DBOX_SIZE_TYPE_4x3 + * 4x5=712x891, #DBOX_SIZE_TYPE_4x5 + * 4x6=712x1070, #DBOX_SIZE_TYPE_4x6 + * + * Easy mode dynamicbox + * 21x21=224x215, #DBOX_SIZE_TYPE_EASY_1x1 + * 23x21=680x215, #DBOX_SIZE_TYPE_EASY_3x1 + * 23x23=680x653, #DBOX_SIZE_TYPE_EASY_3x3 + * + * Special dynamicbox + * 0x0=720x1280, #DBOX_SIZE_TYPE_0x0 + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * Even if you get a handle from the return value of this function, it is not a created instance. + * So you have to consider it as a not initialized handle. + * It can be initialized only after getting the return callback with "ret == #DBOX_STATUS_ERROR_NONE" + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * If this returns @c NULL, you can get the reason of failure using dynamicbox_last_status() + * @param[in] dbox_id DynamicBox Id + * @param[in] content Contents that will be given to the dynamicbox instance + * @param[in] cluster Main group + * @param[in] category Sub group + * @param[in] period Update period (@c DBOX_DEFAULT_PERIOD can be used for this; this argument will be used to specify the period of updating contents of a dynamicbox) + * @param[in] type Size type (defined from libdynamicbox-service package) + * @param[in] cb After the request is sent to the master provider, this callback will be called + * @param[in] data This data will be passed to the callback + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return handle + * @retval Handle Dynamicbox handle but not yet initialized + * @retval @c NULL if it fails to create a handle + * @see dynamicbox_ret_cb + */ +extern dynamicbox_h dynamicbox_add(const char *dbox_id, const char *content, const char *cluster, const char *category, double period, dynamicbox_size_type_e type, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Deletes a dynamicbox (will replace dynamicbox_del). + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * If you call this with an uninitialized handle, the return callback will be called synchronously. + * So before returning from this function, the return callback will be called first. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * @param[in] handler Handler of a dynamicbox instance + * @param[in] type Deletion type (DBOX_DELETE_PERMANENTLY or DBOX_DELETE_TEMPORARY) + * @param[in] cb Return callback + * @param[in] data User data for return callback + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY Already in process + * @retval #DBOX_STATUS_ERROR_FAULT Failed to create a request packet + * @retval #DBOX_STATUS_ERROR_NONE Successfully sent, return callack will be called + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_del(dynamicbox_h handler, dynamicbox_delete_type_e type, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Sets a dynamicbox events callback. + * @details To get the event which is pushed from the provider, Register the event callback using this API. + * The registered callback will be invoked if there are any events from the provider. + * @since_tizen 2.3 + * @param[in] cb Event handler + * @param[in] data User data for the event handler + * @return int + * @retval #DBOX_STATUS_ERROR_NONE If succeed to set event handler + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_OUT_OF_MEMORY Not enough memory + * @see dynamicbox_unset_event_handler() + */ +extern int dynamicbox_add_event_handler(dynamicbox_event_handler_cb cb, void *data); + +/** + * @internal + * @brief Unsets the dynamicbox event handler. + * @since_tizen 2.3 + * @param[in] cb Event handler + * @return void * Event handler data + * @retval pointer Pointer of 'data' which is used with the dynamicbox_set_event_handler + * @see dynamicbox_set_event_handler() + */ +extern void *dynamicbox_remove_event_handler(dynamicbox_event_handler_cb cb); + +/** + * @internal + * @brief Registers the dynamicbox fault event handler. + * @details Argument list: event, pkgname, filename, funcname. + * @since_tizen 2.3 + * @param[in] cb Event handler + * @param[in] data Event handler data + * @return int + * @retval #DBOX_STATUS_ERROR_NONE If succeed to set fault event handler + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_OUT_OF_MEMORY Not enough memory + * @see dynamicbox_unset_fault_handler() + */ +extern int dynamicbox_add_fault_handler(dynamicbox_fault_handler_cb cb, void *data); + +/** + * @internal + * @brief Unsets the dynamicbox fault event handler. + * @since_tizen 2.3 + * @param[in] cb Event handler + * @return void * Callback data which is set via dynamicbox_set_fault_handler + * @retval pointer Pointer of 'data' which is used with the dynamicbox_set_fault_handler + * @see dynamicbox_set_fault_handler() + */ +extern void *dynamicbox_remove_fault_handler(dynamicbox_fault_handler_cb cb); + +/** + * @internal + * @brief Activates the faulted dynamicbox. + * @details Request result will be returned via return callback. + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * Even though this function returns ERROR_NONE, it means that it just successfully sent a request to the provider. + * So you have to check the return callback and its "ret" argument. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * @param[in] dbox_id Package name which should be activated + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int type + * @retval #DBOX_STATUS_ERROR_NONE Successfully sent a request + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Failed to make a request + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_activate(const char *dbox_id, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Resizes the dynamicbox. + * @details + * Normal mode dynamicbox size + * 1x1=175x175, DBOX_SIZE_TYPE_1x1 + * 2x1=354x175, DBOX_SIZE_TYPE_2x1 + * 2x2=354x354, DBOX_SIZE_TYPE_2x2 + * 4x1=712x175, DBOX_SIZE_TYPE_4x1 + * 4x2=712x354, DBOX_SIZE_TYPE_4x2 + * 4x4=712x712, DBOX_SIZE_TYPE_4x4 + * + * Extended dynamicbox size + * 4x3=712x533, DBOX_SIZE_TYPE_4x3 + * 4x5=712x891, DBOX_SIZE_TYPE_4x5 + * 4x6=712x1070, DBOX_SIZE_TYPE_4x6 + * + * Easy mode dynamicbox size + * 21x21=224x215, DBOX_SIZE_TYPE_EASY_1x1 + * 23x21=680x215, DBOX_SIZE_TYPE_EASY_3x1 + * 23x23=680x653, DBOX_SIZE_TYPE_EASY_3x3 + * + * Special mode dynamicbox size + * 0x0=720x1280, DBOX_SIZE_TYPE_0x0 + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * @param[in] handler Handler of a dynamicbox instance + * @param[in] type Type of a dynamicbox size (e.g., DBOX_SIZE_TYPE_1x1, ...) + * @param[in] cb Result callback of the resize operation + * @param[in] data User data for return callback + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int type + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY Previous request of resize is in progress + * @retval #DBOX_STATUS_ERROR_ALREADY Already resized, there is no differences between current size and requested size + * @retval #DBOX_STATUS_ERROR_PERMISSION_DENIED Permission denied, you only have view the content of this box + * @retval #DBOX_STATUS_ERROR_FAULT Failed to make a request + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_resize(dynamicbox_h handler, dynamicbox_size_type_e type, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Sends the click event to a dynamicbox, This is not related with mouse_event, viewer can send "clicked" event directly. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] x Rational X of the content width + * @param[in] y Rational Y of the content height + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + */ +extern int dynamicbox_click(dynamicbox_h handler, double x, double y); + +/** + * @internal + * @brief Changes the cluster/sub-cluster name of the given dynamicbox handler. + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * @param[in] handler Handler of a dynamicbox instance + * @param[in] cluster New cluster of a dynamicbox + * @param[in] category New category of a dynamicbox + * @param[in] cb Result callback for changing the cluster/category of a dynamicbox + * @param[in] data User data for the result callback + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE Request is successfully sent. the return callback will be called + * @retval #DBOX_STATUS_ERROR_BUSY Previous request is not finished yet + * @retval #DBOX_STATUS_ERROR_ALREADY Group name is same with current one + * @retval #DBOX_STATUS_ERROR_PERMISSION_DENIED You have no permission to change property of this dynamicbox instance + * @retval #DBOX_STATUS_ERROR_FAULT Failed to make a request + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_set_group(dynamicbox_h handler, const char *cluster, const char *category, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Gets the cluster and category (sub-cluster) name of the given dynamicbox (it is not I18N format, only English). + * @since_tizen 2.3 + * @remarks You have to do not release the cluster & category. + * It is allocated inside of a given dynamicbox instance, so you can only read it. + * @param[in] handler Handler of a dynamicbox instance + * @param[out] cluster Storage(memory) for containing the cluster name + * @param[out] category Storage(memory) for containing the category name + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + */ +extern int dynamicbox_get_group(dynamicbox_h handler, const char **cluster, const char **category); + +/** + * @internal + * @brief Gets the period of the dynamicbox handler. + * @since_tizen 2.3 + * @remarks If this function returns 0.0f, it means the dynamicbox has no update period or the handle is not valid. + * This function only works after the return callback of dynamicbox_create fucntion is called. + * If this returns negative value, you can get the reason of failure using dynamicbox_last_status() + * @param[in] handler Handler of a dynamicbox instance + * @return double + * @retval >0 Current update period of a dynamicbox + * @retval 0.0f The box has no update period + * @retval -1.0f Failed to get the period info + */ +extern double dynamicbox_period(dynamicbox_h handler); + +/** + * @internal + * @brief Changes the update period. + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * @param[in] handler Handler of a dynamicbox instance + * @param[in] period New update period of a dynamicbox + * @param[in] cb Result callback of changing the update period of this dynamicbox + * @param[in] data User data for the result callback + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY + * @retval #DBOX_STATUS_ERROR_ALREADY + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_set_period(dynamicbox_h handler, double period, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Checks whether the given dynamicbox is a text type or not. + * @remarks + * If this returns DBOX_CONTENT_TYPE_INVALID, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @return dynamicbox_type + * @retval #DBOX_CONTENT_TYPE_IMAGE Contents of a dynamicbox is based on the image file + * @retval #DBOX_CONTENT_TYPE_BUFFER Contents of a dynamicbox is based on canvas buffer(shared) + * @retval #DBOX_CONTENT_TYPE_TEXT Contents of a dynamicbox is based on formatted text file + * @retval #DBOX_CONTENT_TYPE_RESOURCE_ID Contens of a dynamicbox is shared by the resource id (depends on the Window system, eg, Xorg) + * @retval #DBOX_CONTENT_TYPE_UIFW UI F/W supported content type for dynamic box + * @retval #DBOX_CONTENT_TYPE_INVALID Invalid type + * @see dynamicbox_type() + */ +extern dynamicbox_type_e dynamicbox_type(dynamicbox_h handler, int gbar); + +/** + * @internal + * @brief Checks if the given dynamicbox is created by user or not. + * @remarks if this returns negative value, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @details If the dynamicbox instance is created by a system this will return 0. + * @param[in] handler Handler of a dynamicbox instance + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 0 Automatically created dynamicbox by the provider + * @retval 1 Created by user via dynamicbox_add() + * @see dynamicbox_add() + * @see dynamicbox_set_event_handler() + */ +extern int dynamicbox_is_created_by_user(dynamicbox_h handler); + +/** + * @internal + * @brief Gets content information string of the given dynamicbox. + * @remarks if this returns @c NULL, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return const char * + * @retval content_info Dynamicbox content info that can be used again via content_info argument of dynamicbox_add() + * @see dynamicbox_add() + */ +extern const char *dynamicbox_content(dynamicbox_h handler); + +/** + * @internal + * @brief Gets the sub cluster title string of the given dynamicbox. + * @details This API is now used for accessibility. + * Each box should set their content as a string to be read by TTS. + * So if the box has focused on the homescreen, the homescreen will read text using this API. + * @since_tizen 2.3 + * @remarks The title returned by this API can be read by TTS. + * But it is just recomendation for the homescreen. + * So, to read it or not depends on its implementation. + * if this returns @c NULL, you can get the reason of failure using dynamicbox_last_status() + * @param[in] handler Handler of a dynamicbox instance + * @return const char * + * @retval sub Cluster name + * @retval @c NULL + */ +extern const char *dynamicbox_title(dynamicbox_h handler); + +/** + * @internal + * @brief Gets the filename of the given dynamicbox, if it is an IMAGE type dynamicbox. + * @details If the box is developed as an image format to represent its contents, the homescreen should know its image file name. + * @remarks if this returns @c NULL, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return const char * + * @retval filename If the dynamicbox type is image this function will give you a abs-path of an image file (content is rendered) + * @retval @c NULL If this has no image file or type is not image file. + */ +extern const char *dynamicbox_filename(dynamicbox_h handler); + +/** + * @internal + * @brief Gets the package name of the given dynamicbox handler. + * @remarks if this returns @c NULL, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return const char * + * @retval pkgname Package name + * @retval @c NULL If the handler is not valid + */ +extern const char *dynamicbox_pkgname(dynamicbox_h handler); + +/** + * @internal + * @brief Gets the priority of a current content. + * @remarks if this returns negative value, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return double + * @retval 0.0f Handler is @c NULL + * @retval -1.0f Handler is not valid (not yet initialized) + * @retval real Number between 0.0 and 1.0 + */ +extern double dynamicbox_priority(dynamicbox_h handler); + +/** + * @internal + * @brief Acquires the buffer of a given dynamicbox (only for the buffer type). + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return void * + * @retval address Address of a Frame Buffer + * @retval @c NULL If it fails to get buffer address + */ +extern void *dynamicbox_acquire_buffer(dynamicbox_h handler, int gbar); + +/** + * @internal + * @brief Releases the buffer of a dynamicbox (only for the buffer type). + * @since_tizen 2.3 + * @param[in] buffer Buffer + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @see dynamicbox_acquire_buffer() + */ +extern int dynamicbox_release_buffer(void *buffer); + +/** + * @internal + * @brief Gets the reference count of Dynamicbox buffer (only for the buffer type). + * @since_tizen 2.3 + * @param[in] buffer Buffer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval refcnt Positive integer value including ZERO + */ +extern int dynamicbox_buffer_refcnt(void *buffer); + +/** + * @internal + * @brief Gets the size of the Dynamicbox. + * @remarks + * If this returns DBOX_SIZE_TYPE_UNKNOWN, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return dynamicbox_size_type_e + * @retval #DBOX_SIZE_TYPE_NxM N by M size + * @retval #DBOX_SIZE_TYPE_UNKNOWN Invalid handler or size type is not defined yet + */ +extern dynamicbox_size_type_e dynamicbox_size(dynamicbox_h handler); + +/** + * @internal + * @brief Gets the size of the Glance Bar. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[out] w Width of glance bar in pixels + * @param[out] h Height of glance bar in pixels + * @return int type + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameters are used + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + */ +extern int dynamicbox_get_glance_bar_size(dynamicbox_h handler, int *w, int *h); + +/** + * @internal + * @brief Gets a list of the supported sizes of a given handler. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] size_list Array buffer for getting the size types + * @param[in] cnt size of array + * @param[out] cnt Count of returned size types + * @param[out] size_list Array of size types + * @return int type + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + */ +extern int dynamicbox_get_supported_sizes(dynamicbox_h handler, int *cnt, dynamicbox_size_type_e *size_list); + +/** + * @internal + * @brief Gets BUFFER SIZE of the dynamicbox if it is a buffer type. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval size Size in bytes of the dynamicbox buffer + */ +extern int dynamicbox_buffer_size(dynamicbox_h handler, int gbar); + +/** + * @internal + * @brief Sends a content event (for buffer type) to the provider (dynamicbox). + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] type Event type + * @param[in] x Coordinates of X axis + * @param[in] y Coordinates of Y axis + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully sent + * @see dynamicbox_feed_access_event() + * @see dynamicbox_feed_key_event() + */ +extern int dynamicbox_feed_mouse_event(dynamicbox_h handler, dynamicbox_mouse_event_type_e type, dynamicbox_mouse_event_info_t info); + +/** + * @internal + * @brief Sends an access event (for buffer type) to the provider (dynamicbox). + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] type Event type + * @param[in] x Coordinates of X axsis + * @param[in] y Coordinates of Y axsis + * @param[in] cb Result callback function + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully sent + * @see dynamicbox_feed_mouse_event() + * @see dynamicbox_feed_key_event() + */ +extern int dynamicbox_feed_access_event(dynamicbox_h handler, dynamicbox_access_event_type_e type, dynamicbox_access_event_info_t info, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Sends a key event (for buffer type) to the provider (dynamicbox). + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] type Key event type + * @param[in] keycode Code of key + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully sent + * @see dynamicbox_feed_mouse_event() + * @see dynamicbox_feed_access_event() + */ +extern int dynamicbox_feed_key_event(dynamicbox_h handler, dynamicbox_key_event_type_e type, dynamicbox_key_event_info_t info, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Sets pin-up status of the given handler. + * @details If the dynamicbox supports the pinup feature, + * you can freeze the update of the given dynamicbox. + * But it is different from pause. + * The box will be updated and it will decide wheter update its content or not when the pinup is on. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] flag Pinup value + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + * @see dynamicbox_ret_cb + * @see dynamicbox_set_visibility() + * @see dynamicbox_is_pinned_up() + */ +extern int dynamicbox_set_pinup(dynamicbox_h handler, int flag, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Checks the PIN-UP status of the given handler. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + * @retval 1 Box is pinned up + * @retval 0 Box is not pinned up + * @see dynamicbox_set_pinup() + */ +extern int dynamicbox_is_pinned_up(dynamicbox_h handler); + +/** + * @internal + * @brief Checks the availability of the PIN-UP feature for the given handler. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 1 If the box support Pinup feature + * @retval 0 If the box does not support the Pinup feature + * @see dynamicbox_is_pinned_up() + * @see dynamicbox_set_pinup() + */ +extern int dynamicbox_has_pinup(dynamicbox_h handler); + +/** + * @internal + * @brief Checks the existence of Glance Bar for the given handler. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 1 If the box support the Glance Bar + * @retval 0 If the box has no Glance Bar + */ +extern int dynamicbox_has_glance_bar(dynamicbox_h handler); + +/** + * @internal + * @brief Creates Glance Bar of the given handler with the relative position from dynamicbox. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] x 0.0 ~ 1.0 + * @param[in] y 0.0 ~ 1.0 + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see dynamicbox_create_glance_bar() + * @see dynamicbox_destroy_glance_bar() + * @see dynamicbox_move_glance_bar() + */ +extern int dynamicbox_create_glance_bar(dynamicbox_h handler, double x, double y, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Updates a position of the given Glance Bar. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] x 0.0 ~ 1.0, 0.0 indicates the coordinate X of left of dynamicbox + * @param[in] y 0.0 ~ 1.0, 0.0 indicates the coordinate Y of top of dynamicbox + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE If sending a request for updating position of the Glance Bar has been done successfully + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + */ +extern int dynamicbox_move_glance_bar(dynamicbox_h handler, double x, double y); + +/** + * @internal + * @brief Destroys the Glance Bar of the given handler if it is created. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] cb Callback function + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_destroy_glance_bar(dynamicbox_h handler, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Checks the create status of the given dynamicbox handler. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval 0 Glance Bar is not created + * @retval 1 Glance Bar is created + */ +extern int dynamicbox_glance_bar_is_created(dynamicbox_h handler); + +/** + * @internal + * @brief Sets a function table for parsing the text content of a dynamicbox. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] ops + * @return int + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @see dynamicbox_set_gbar_text_handler() + */ +extern int dynamicbox_set_text_handler(dynamicbox_h handler, int gbar, dynamicbox_script_operator_t ops); + +/** + * @internal + * @brief Emits a text signal to the given dynamicbox only if it is a text type. + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * @param[in] handler Handler of a dynamicbox instance + * @param[in] emission Emission string + * @param[in] source Source string + * @param[in] sx Start X + * @param[in] sy Start Y + * @param[in] ex End X + * @param[in] ey End Y + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid parameters + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully emitted + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_emit_text_signal(dynamicbox_h handler, dynamicbox_text_event_t event_info, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Sets a private data pointer to carry it using the given handler. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] data Data pointer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE Successfully registered + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @see dynamicbox_data() + */ +extern int dynamicbox_set_data(dynamicbox_h handler, void *data); + +/** + * @internal + * @brief Gets a private data pointer which is carried by a given handler. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return void * + * @retval data Data pointer + * @retval @c NULL If there is no data + * @see dynamicbox_set_data() + */ +extern void *dynamicbox_data(dynamicbox_h handler); + +/** + * @internal + * @brief Subscribes an event for dynamicboxes only in a given cluster and sub-cluster. + * @details If you wrote a view-only client, + * you can receive the event of specific dynamicboxes which belong to a given cluster/category. + * But you cannot modify their attributes (such as size, ...). + * @since_tizen 2.3 + * @param[in] cluster Cluster ("*" can be used for subscribe all cluster's dynamicboxes event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe dynamicboxes events of all category(sub-cluster) in a given "cluster") + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully requested + * @see dynamicbox_unsubscribe_group() + */ +extern int dynamicbox_subscribe_group(const char *cluster, const char *category); + +/** + * @internal + * @brief Unsubscribes an event for the dynamicboxes, but you will receive already added dynamicboxes events. + * @since_tizen 2.3 + * @param[in] cluster Cluster("*" can be used for subscribe all cluster's dynamicboxes event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe all sub-cluster's dynamicboxes event in a given "cluster") + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully requested + * @see dynamicbox_subscribe_group() + */ +extern int dynamicbox_unsubscribe_group(const char *cluster, const char *category); + +/** + * @internal + * @brief Refreshes the group (cluster/sub-cluser (aka. category)). + * @details This function will trigger the update of all dynamicboxes in a given cluster/category group. + * @since_tizen 2.3 + * @remarks Basically, a default dynamicbox system doesn't use the cluster/category concept. + * But you can use it. So if you decide to use it, then you can trigger the update of all dynamicboxes in the given group. + * @param[in] cluster Cluster ID + * @param[in] category Sub-cluster ID + * @param[in] force 1 if the boxes should be updated even if they are paused + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully requested + * @see dynamicbox_refresh() + */ +extern int dynamicbox_refresh_group(const char *cluster, const char *category, int force); + +/** + * @internal + * @brief Refreshes a dynamicbox. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] force 1 if the box should be updated even if it is paused + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully requested + * @see dynamicbox_refresh_group() + */ +extern int dynamicbox_refresh(dynamicbox_h handler, int force); + +/** + * @internal + * @brief Gets Resource Id of a dynamicbox content. + * @details This function doesn't guarantee the life-cycle of the resource id. + * If the service provider destroyed the resource id, you will not know about it. + * So you should validate it before accessing it. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @return int + * @retval 0 If the resource id is not created + * @retval ResourceId Resource Id + * @see dynamicbox_resource_id() + */ +extern unsigned int dynamicbox_resource_id(const dynamicbox_h handler, int gbar); + +/** + * @internal + * @brief Gets the Resource Id of a dynamicbox. + * @details Even if a render process releases the Resource Id, the Resource Id will be kept before being released by dynamicbox_release_resource_id. + * You should release the resource id manually. + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] cb Callback function which will be called with result of acquiring dbox resource id + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully requested + * @pre Dynamicbox service system should support the ResourceId type buffer. + * The dynamicbox should be designed to use the buffer (or script). + * @see dynamicbox_release_resource_id() + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_acquire_resource_id(dynamicbox_h handler, int gbar, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Get the Resource Id of a dynamicbox for Extra buffer + * @details Even if a render process(provider) released the Resource Id, it will be kept while release it by viewer.\n + * This will prevent from unexpected resource releasing for viewer.\n + * You should release this using dynamicbox_release_resource_id() + * @remarks + * This is an ASYNCHRONOUS API. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] idx Index of extra buffer, it is limited to dynamicbox configuration + * @param[in] cb Callback function which will be called with result of acquiring dbox resource id + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully requested + * @pre Dynamicbox service system should support the resource id type buffer. + * The dynamicbox should be designed to use the buffer (or script) + * @see dynamicbox_release_resource_id() + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_acquire_extra_resource_id(dynamicbox_h handler, int gbar, int idx, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Releases the Resource Id of a dynamicbox. + * @details After a client gets a new Resource Id or does not need to keep the current Resource Id anymore, use this function to release it. + * If there is no user for a given Resource Id, the Resource Id will be destroyed. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[in] resource_id Resource Id of given dynamicbox handler + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @pre The Resource Id should be acquired by dynamicbox_acquire_resource_id + * @see dynamicbox_acquire_resource_id() + */ +extern int dynamicbox_release_resource_id(dynamicbox_h handler, int gbar, unsigned int resource_id); + +/** + * @internal + * @brief Updates a visible state of the dynamicbox. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] state Configure the current visible state of a dynamicbox + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY + * @retval #DBOX_STATUS_ERROR_PERMISSION_DENIED + * @retval #DBOX_STATUS_ERROR_ALREADY + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + */ +extern int dynamicbox_set_visibility(dynamicbox_h handler, dynamicbox_visible_state_e state); + +/** + * @internal + * @brief Gets the current visible state of a dynamicbox. + * @remarks + * If this returns DBOX_VISIBLE_ERROR, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return dynamicbox_visible_state + * @retval #DBOX_SHOW Dynamicbox is shown (Default state) + * @retval #DBOX_HIDE Dynamicbox is hidden, Update timer is not frozen (but a user cannot receive any updated events; a user should refresh(reload) the content of a dynamicbox when a user make this show again) + * @retval #DBOX_HIDE_WITH_PAUSE Dynamicbox is hidden, it will pause the update timer, but if a dynamicbox updates its contents, update event will occur + * @retval #DBOX_VISIBLE_ERROR To enlarge the size of this enumeration type + */ +extern dynamicbox_visible_state_e dynamicbox_visibility(dynamicbox_h handler); + +/** + * @internal + * @brief Sets an update mode of the current dynamicbox. + * @details If you set 1 for active update mode, you should get a buffer without updated event from provider. + * But if it is passive mode, you have to update content of a box when you get updated events. + * Default is Passive mode. + * @since_tizen 2.3 + * @remarks + * This is an ASYNCHRONOUS API. + * This function is Asynchronous, so you will get result of add requst from @a cb, if you failed to send request to create a new dynamicbox, + * This function will returns proper error code + * @param[in] handler Handler of a dynamicbox instance + * @param[in] active_update 1 means active update, 0 means passive update (default) + * @param[in] cb Result callback function + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_BUSY + * @retval #DBOX_STATUS_ERROR_PERMISSION_DENIED + * @retval #DBOX_STATUS_ERROR_ALREADY + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @see dynamicbox_ret_cb + */ +extern int dynamicbox_set_update_mode(dynamicbox_h handler, int active_update, dynamicbox_ret_cb cb, void *data); + +/** + * @internal + * @brief Checks the active update mode of the given dynamicbox. + * @remarks + * If this returns negative value, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return int + * @retval 0 If passive mode + * @retval 1 If active mode or error code + */ +extern int dynamicbox_is_active_update(dynamicbox_h handler); + +/** + * @internal + * @brief Syncs manually + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_NONE If success + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid handle + * @see dynamicbox_set_manual_sync() + * @see dynamicbox_manual_sync() + */ +extern int dynamicbox_sync_buffer(dynamicbox_h handler, int gbar); + +/** + * @internal + * @brief Getting the damaged region info + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @param[out] region Readonly information for damaged area + * @return int + * @retval #DBOX_STATUS_ERROR_NONE if success + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid handle + */ +extern int dynamicbox_damage_region_get(dynamicbox_h handler, int gbar, const dynamicbox_damage_region_t *region); + +/** + * @internal + * @brief Gets an alternative icon of the given dynamicbox instance. + * @details If the box should be represented as a shortcut icon, this function will get the alternative icon. + * @remarks + * If this returns @c NULL, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return const char * + * @retval address Absolute path of an alternative icon file + * @retval @c NULL Dynamicbox has no alternative icon file + * @see dynamicbox_alt_name() + */ +extern const char *dynamicbox_alternative_icon(dynamicbox_h handler); + +/** + * @internal + * @brief Gets an alternative name of the given dynamicbox instance. + * @details If the box should be represented as a shortcut name, this function will get the alternative name. + * @remarks + * If this returns @c NULL, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @return const char * + * @retval name Alternative name of a dynamicbox + * @retval @c NULL Dynamicbox has no alternative name + * @see dynamicbox_alt_icon() + */ +extern const char *dynamicbox_alternative_name(dynamicbox_h handler); + +/** + * @internal + * @brief Gets a lock for a frame buffer. + * @details This function should be used to prevent from rendering to the frame buffer while reading it. + * And the locking area should be short and must be released ASAP, or the render thread will be hanged. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @see dynamicbox_release_buffer_lock() + */ +extern int dynamicbox_acquire_buffer_lock(dynamicbox_h handler, int gbar); + +/** + * @internal + * @brief Releases a lock of the frame buffer. + * @details This function should be called ASAP after acquiring a lock of FB, or the render process will be blocked. + * @since_tizen 2.3 + * @param[in] handler Handler of a dynamicbox instance + * @param[in] gbar 1 for Glance Bar or 0 + * @privlevel platform + * @privilege %http://developer.samsung.com/tizen/privilege/dynamicbox.viewer + * @return int + * @retval #DBOX_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid argument + * @retval #DBOX_STATUS_ERROR_NONE Successfully done + * @see dynamicbox_acquire_buffer_lock() + */ +extern int dynamicbox_release_buffer_lock(dynamicbox_h handler, int gbar); + +/** + * @internal + * @brief Sets options for controlling a dynamicbox sub-system. + * @details + * #DBOX_OPTION_FRAME_DROP_FOR_RESIZE + * While resizing the box, viewer doesn't want to know the updated frames of an old size content anymore. + * In that case, turn this on, the provider will not send the updated event to the viewer about an old content. + * So the viewer can reduce its burden to update unnecessary frames. + * #DBOX_OPTION_MANUAL_SYNC + * If you don't want to update frames automatically, or you want only reload the frames by your hands, (manually) + * Turn this on. + * After turnning it on, you should sync it using dynamicbox_sync_buffer(). + * #DBOX_OPTION_SHARED_CONTENT + * If this option is turnned on, even though you create a new dynamicbox, + * if there are already added same instances that have same contents, the instance will not be created again. + * Instead of creating a new instance, a viewer will provide an old instance with a new handle. + * @since_tizen 2.3 + * @param[in] option Option which will be affected by this call + * @param[in] state New value for given option + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Unknown option + * @retval #DBOX_STATUS_ERROR_FAULT Failed to change the state of option + * @retval #DBOX_STATUS_ERROR_NONE Successfully changed + * @see dynamicbox_get_option() + * @see dynamicbox_sync_buffer() + */ +extern int dynamicbox_set_option(dynamicbox_option_type_e option, int state); + +/** + * @internal + * @brief Gets options of a dynamicbox sub-system. + * @remarks + * If this returns negative value, you can get the reason of failure using dynamicbox_last_status() + * @since_tizen 2.3 + * @param[in] option Type of option + * @return int + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Invalid option + * @retval #DBOX_STATUS_ERROR_FAULT Failed to get option + * @retval >=0 Value of given option (must be >=0) + * @see dynamicbox_set_option() + */ +extern int dynamicbox_option(dynamicbox_option_type_e option); + +/** + * @internal + * @brief Set a handler for launching an app by auto-launch feature + * @details If a user clicks a box, which box enabled auto-launch option, the launcher_handler will be called. + * From that callback, you should launch an app using given ui-app id. + * @since_tizen 2.3 + * @param[in] launch_handler Handler for launching an app manually + * @param[in] data Callback data which will be given a data for launch_handler + * @return int type + * @retval #DBOX_STATUS_ERROR_NONE Succeed to set new handler. there is no other cases + */ +extern int dynamicbox_set_auto_launch_handler(dynamicbox_auto_launch_handler_cb cb, void *data); + +/** + * @internal + * @brief Get the last extra buffer index and its id. + * @details + * If there is an event of #DBOX_EVENT_DBOX_EXTRA_BUFFER_CREATED or #DBOX_EVENT_GBAR_EXTRA_BUFFER_CREATED, + * #DBOX_EVENT_DBOX_EXTRA_BUFFER_DESTROYED or #DBOX_EVENT_GBAR_EXTRA_BUFFER_DESTROYED + * you can use this to get the last created buffer info + * @since_tizen 2.3 + * @param[in] handler Dynamicbox handler + * @param[in] gbar 1 if you want get the glance bar's info or 0 + * @param[out] idx Index of buffer + * @param[out] resource_id Resource Id + * @return status + * @retval #DBOX_STATUS_ERROR_NONE Successfully get + * @retval #DBOX_STATUS_ERROR_INVALID_PARAMETER Handler is not valid + * @retval #DBOX_STATUS_ERROR_NOT_EXIST There is no extra buffer + */ +extern int dynamicbox_get_affected_extra_buffer(dynamicbox_h handler, int gbar, int *idx, unsigned int *resource_id); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif // __DYNAMICBOX_VIEWER_H diff --git a/dynamicbox_viewer/include/dynamicbox_internal.h b/dynamicbox_viewer/include/dynamicbox_internal.h new file mode 100644 index 0000000..ad3f7d7 --- /dev/null +++ b/dynamicbox_viewer/include/dynamicbox_internal.h @@ -0,0 +1,270 @@ +/* + * 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. + */ + +struct cb_info { + dynamicbox_ret_cb cb; + void *data; +}; + +extern void dbox_invoke_event_handler(struct dynamicbox *handler, dynamicbox_event_type_e event); +extern void dbox_invoke_fault_handler(dynamicbox_fault_type_e type, const char *pkgname, const char *filename, const char *function); + +extern struct dynamicbox_common *dbox_find_common_handle(const char *pkgname, const char *filename); +extern struct dynamicbox *dbox_new_dynamicbox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category); +extern struct dynamicbox_common *dbox_find_common_handle_by_timestamp(double timestamp); + +extern int dbox_set_group(struct dynamicbox_common *common, const char *cluster, const char *category); +extern void dbox_set_size(struct dynamicbox_common *common, int w, int h); +extern void dbox_set_gbarsize(struct dynamicbox_common *common, int w, int h); +extern void dbox_set_default_gbarsize(struct dynamicbox_common *common, int w, int h); +extern int dbox_set_content(struct dynamicbox_common *common, const char *content); +extern int dbox_set_title(struct dynamicbox_common *handler, const char *title); +extern void dbox_set_auto_launch(struct dynamicbox_common *handler, const char *auto_launch); +extern void dbox_set_id(struct dynamicbox_common *handler, const char *id); +extern void dbox_set_size_list(struct dynamicbox_common *handler, int size_list); +extern void dbox_set_priority(struct dynamicbox_common *handler, double priority); +extern int dbox_set_dbox_fb(struct dynamicbox_common *handler, const char *filename); +extern int dbox_set_gbar_fb(struct dynamicbox_common *handler, const char *filename); +extern struct fb_info *dbox_get_gbar_fb(struct dynamicbox_common *handler); +extern struct fb_info *dbox_get_dbox_fb(struct dynamicbox_common *handler); +extern void dbox_set_user(struct dynamicbox_common *handler, int user); +extern void dbox_set_pinup(struct dynamicbox_common *handler, int pinup); +extern void dbox_set_text_dbox(struct dynamicbox_common *handler); +extern void dbox_set_text_gbar(struct dynamicbox_common *handler); +extern int dbox_text_dbox(struct dynamicbox_common *handler); +extern int dbox_text_gbar(struct dynamicbox_common *handler); +extern void dbox_set_period(struct dynamicbox_common *handler, double period); +extern void dbox_set_update_mode(struct dynamicbox_common *handler, int active_mode); +extern void dbox_set_filename(struct dynamicbox_common *handler, const char *filename); +extern void dbox_unlink_filename(struct dynamicbox_common *common); +extern void dbox_set_alt_icon(struct dynamicbox_common *handler, const char *icon); +extern void dbox_set_alt_name(struct dynamicbox_common *handle, const char *name); +extern int dbox_destroy_common_handle(struct dynamicbox_common *common); +extern struct dynamicbox_common *dbox_create_common_handle(struct dynamicbox *handle, const char *pkgname, const char *cluster, const char *category); +extern int dbox_sync_gbar_fb(struct dynamicbox_common *common); +extern int dbox_sync_dbox_fb(struct dynamicbox_common *common); +extern int dbox_common_unref(struct dynamicbox_common *common, struct dynamicbox *handle); +extern int dbox_common_ref(struct dynamicbox_common *common, struct dynamicbox *handle); +extern struct dynamicbox_common *dbox_find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category); +extern struct dynamicbox *dbox_find_dbox_in_show(struct dynamicbox_common *common); +extern struct dynamicbox *dbox_get_dbox_nth(struct dynamicbox_common *common, int nth); +extern void *dbox_remove_event_handler(dynamicbox_event_handler_cb dbox_cb); +extern int dbox_add_event_handler(dynamicbox_event_handler_cb dbox_cb, void *data); +extern int dbox_add_fault_handler(dynamicbox_fault_handler_cb dbox_cb, void *data); +extern void *dbox_remove_fault_handler(dynamicbox_fault_handler_cb dbox_cb); +extern struct cb_info *dbox_create_cb_info(dynamicbox_ret_cb cb, void *data); +extern void dbox_destroy_cb_info(struct cb_info *info); + +extern struct dynamicbox *dbox_ref(struct dynamicbox *handler); +extern struct dynamicbox *dbox_unref(struct dynamicbox *handler, int destroy_common); +extern int dbox_send_delete(struct dynamicbox *handler, int type, dynamicbox_ret_cb cb, void *data); +extern int dbox_delete_all(void); + +typedef enum dynamicbox_state { + DBOX_STATE_CREATE = 0xBEEFbeef, + DBOX_STATE_DELETE = 0xDEADdead, /* Delete only for this client */ + DBOX_STATE_DESTROYED = 0x00DEAD00 +} dynamicbox_state_e; + +struct dynamicbox_common { + dynamicbox_state_e state; + + struct dlist *dynamicbox_list; + int refcnt; + + char *cluster; + char *category; + + char *pkgname; + char *id; + + char *content; + char *title; + char *filename; + + double timestamp; + + struct alt_info { + char *icon; + char *name; + } alt; + + dynamicbox_delete_type_e delete_type; + + int is_user; + int is_gbar_created; + int is_pinned_up; + int is_active_update; + dynamicbox_visible_state_e visible; + + struct { + dynamicbox_dbox_type_e type; + struct fb_info *fb; + + int size_list; + + int width; + int height; + double priority; + + char *auto_launch; + double period; + int pinup_supported; + int mouse_event; + + /* For the filtering event */ + double x; + double y; + + /* For the extra buffer */ + unsigned int *extra_buffer; + int last_extra_buffer_idx; + + /* Lock */ + dynamicbox_lock_info_t lock; + + /* For damaged region */ + struct dynamicbox_damage_region last_damage; + } dbox; + + struct { + dynamicbox_gbar_type_e type; + struct fb_info *fb; + + int width; + int height; + + int default_width; + int default_height; + + /* For the filtering event */ + double x; + double y; + + /* For the extra buffer */ + unsigned int *extra_buffer; + int last_extra_buffer_idx; + + /* Lock */ + dynamicbox_lock_info_t lock; + + /* For damaged region */ + struct dynamicbox_damage_region last_damage; + } gbar; + + int nr_of_sizes; + + struct requested_flag { + unsigned int created:1; + unsigned int deleted:1; + unsigned int pinup:1; + unsigned int group_changed:1; + unsigned int period_changed:1; + unsigned int size_changed:1; + unsigned int gbar_created:1; + unsigned int gbar_destroyed:1; + unsigned int update_mode:1; + unsigned int access_event:1; + unsigned int key_event:1; + + /*! + * \note + * Reserved + */ + unsigned int reserved:21; + } request; +}; + +struct job_item { + struct dynamicbox *handle; + dynamicbox_ret_cb cb; + int ret; + void *data; +}; + +struct dynamicbox { + dynamicbox_state_e state; + + int refcnt; + int paused_updating; + + dynamicbox_visible_state_e visible; + struct dynamicbox_common *common; + + void *data; + + struct callback_table { + struct dynamicbox_script_operators dbox_ops; + struct dynamicbox_script_operators gbar_ops; + + struct created { + dynamicbox_ret_cb cb; + void *data; + } created; + + struct deleted { + dynamicbox_ret_cb cb; + void *data; + } deleted; + + struct pinup { + dynamicbox_ret_cb cb; + void *data; + } pinup; + + struct group_changed { + dynamicbox_ret_cb cb; + void *data; + } group_changed; + + struct period_changed { + dynamicbox_ret_cb cb; + void *data; + } period_changed; + + struct size_changed { + dynamicbox_ret_cb cb; + void *data; + } size_changed; + + struct gbar_created { + dynamicbox_ret_cb cb; + void *data; + } gbar_created; + + struct gbar_destroyed { + dynamicbox_ret_cb cb; + void *data; + } gbar_destroyed; + + struct update_mode { + dynamicbox_ret_cb cb; + void *data; + } update_mode; + + struct access_event { + dynamicbox_ret_cb cb; + void *data; + } access_event; + + struct key_event { + dynamicbox_ret_cb cb; + void *data; + } key_event; + } cbs; +}; + +/* End of a file */ diff --git a/include/fb.h b/dynamicbox_viewer/include/fb.h similarity index 85% rename from include/fb.h rename to dynamicbox_viewer/include/fb.h index 9e567dd..e7b8543 100644 --- a/include/fb.h +++ b/dynamicbox_viewer/include/fb.h @@ -16,18 +16,11 @@ struct fb_info; -enum buffer_type { /*!< Must have to be sync with libprovider, liblivebox-viewer */ - BUFFER_TYPE_FILE, - BUFFER_TYPE_SHM, - BUFFER_TYPE_PIXMAP, - BUFFER_TYPE_ERROR -}; - extern int fb_init(void *disp); extern int fb_fini(void); extern const char *fb_id(struct fb_info *info); extern int fb_get_size(struct fb_info *info, int *w, int *h); -extern int fb_sync(struct fb_info *info); +extern int fb_sync(struct fb_info *info, int x, int y, int w, int h); extern int fb_size(struct fb_info *info); extern int fb_refcnt(void *data); extern int fb_is_created(struct fb_info *info); diff --git a/include/file_service.h b/dynamicbox_viewer/include/file_service.h similarity index 100% rename from include/file_service.h rename to dynamicbox_viewer/include/file_service.h diff --git a/include/master_rpc.h b/dynamicbox_viewer/include/master_rpc.h similarity index 74% rename from include/master_rpc.h rename to dynamicbox_viewer/include/master_rpc.h index d850bfd..7dde9ed 100644 --- a/include/master_rpc.h +++ b/dynamicbox_viewer/include/master_rpc.h @@ -14,10 +14,10 @@ * limitations under the License. */ -extern int master_rpc_async_request(struct livebox *handler, struct packet *packet, int urgent, void (*ret_cb)(struct livebox *handler, const struct packet *result, void *data), void *data); +extern int master_rpc_async_request(struct dynamicbox *handler, struct packet *packet, int urgent, void (*ret_cb)(struct dynamicbox *handler, const struct packet *result, void *data), void *data); extern int master_rpc_sync_request(struct packet *packet); extern void master_rpc_check_and_fire_consumer(void); -extern int master_rpc_request_only(struct livebox *handler, struct packet *packet); +extern int master_rpc_request_only(struct dynamicbox *handler, struct packet *packet); extern int master_rpc_clear_fault_package(const char *pkgname); extern int master_rpc_clear_all_request(void); diff --git a/include/util.h b/dynamicbox_viewer/include/util.h similarity index 87% rename from include/util.h rename to dynamicbox_viewer/include/util.h index b66b542..498a249 100644 --- a/include/util.h +++ b/dynamicbox_viewer/include/util.h @@ -17,13 +17,12 @@ extern int util_check_extension(const char *filename, const char *check_ptr); extern double util_timestamp(void); extern const char *util_basename(const char *name); -extern int util_validate_livebox_package(const char *pkgname); extern const char *util_uri_to_path(const char *uri); extern int util_unlink(const char *filename); -#define SCHEMA_FILE "file://" -#define SCHEMA_PIXMAP "pixmap://" -#define SCHEMA_SHM "shm://" +#define SCHEMA_FILE "file://" +#define SCHEMA_PIXMAP "pixmap://" +#define SCHEMA_SHM "shm://" #define container_of(ptr, type, member) \ ({ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ diff --git a/dynamicbox_viewer/src/client.c b/dynamicbox_viewer/src/client.c new file mode 100644 index 0000000..61ae62d --- /dev/null +++ b/dynamicbox_viewer/src/client.c @@ -0,0 +1,2296 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "client.h" +#include "dynamicbox.h" +#include "dynamicbox_internal.h" +#include "desc_parser.h" +#include "fb.h" +#include "util.h" +#include "master_rpc.h" +#include "conf.h" +#include "file_service.h" +#include "dlist.h" + +int errno; + +#define MAX_DIRECT_ADDR 256 + +static struct info { + int fd; + int direct_fd; + guint timer_id; + char *client_addr; + char *direct_addr; +} s_info = { + .fd = -1, + .direct_fd = -1, + .timer_id = 0, + .client_addr = NULL, + .direct_addr = NULL, +}; + +static struct packet *master_fault_package(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *function; + + if (packet_get(packet, "sss", &pkgname, &id, &function) != 3) { + ErrPrint("Invalid arguments\n"); + return NULL; + } + + DbgPrint("[%s]\n", pkgname); + master_rpc_clear_fault_package(pkgname); + dbox_invoke_fault_handler(DBOX_FAULT_DEACTIVATED, pkgname, id, function); + return NULL; +} + +static struct packet *master_hold_scroll(pid_t pid, int handle, const struct packet *packet) +{ + struct dynamicbox_common *common; + dynamicbox_h dynamicbox; + const char *pkgname; + const char *id; + int seize; + int ret; + struct dlist *l; + + ret = packet_get(packet, "ssi", &pkgname, &id, &seize); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + DbgPrint("HOLD: [%s] seize(%d)\n", id, seize); + seize = seize ? DBOX_EVENT_HOLD_SCROLL : DBOX_EVENT_RELEASE_SCROLL; + dlist_foreach(common->dynamicbox_list, l, dynamicbox) { + dbox_invoke_event_handler(dynamicbox, seize); + } + +out: + return NULL; +} + +static struct packet *master_pinup(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *content; + dynamicbox_h handler; + struct dlist *l; + struct dlist *n; + struct dynamicbox_common *common; + char *new_content; + int ret; + int status; + int pinup; + + ret = packet_get(packet, "iisss", &status, &pinup, &pkgname, &id, &content); + if (ret != 5) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance (%s) is not exists\n", id); + goto out; + } + + if (status == (int)DBOX_STATUS_ERROR_NONE) { + new_content = strdup(content); + if (new_content) { + free(common->content); + common->content = new_content; + common->is_pinned_up = pinup; + } else { + ErrPrint("Heap: %s\n", strerror(errno)); + status = DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + } + + common->request.pinup = 0; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.pinup.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + /* Make sure that user can call pinup API in its result callback */ + cb = handler->cbs.pinup.cb; + cbdata = handler->cbs.pinup.data; + + handler->cbs.pinup.cb = NULL; + handler->cbs.pinup.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_PINUP_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_deleted(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + double timestamp; + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + struct dlist *n; + int reason; + + if (packet_get(packet, "ssdi", &pkgname, &id, ×tamp, &reason) != 4) { + ErrPrint("Invalid arguemnt\n"); + goto out; + } + + DbgPrint("[%s]\n", pkgname); + common = dbox_find_common_handle_by_timestamp(timestamp); + if (!common) { + /*! + * \note + * This can be happens only if the user delete a dynamicbox + * right after create it before receive created event. + */ + goto out; + } + + /*!< Check validity of this "handler" */ + if (common->state != DBOX_STATE_CREATE) { + if (common->state != DBOX_STATE_DELETE) { + /*! + * \note + * This is not possible + */ + ErrPrint("Already deleted handler (%s - %s)\n", pkgname, id); + return NULL; + } + } + + common->request.deleted = 0; + /*! + * We should change the state of "common handler' before handling the callbacks. + * Because if user tries to create a new handle in the callbacks, + * find_sharable_common_handle will returns destroying object. + * Then we will get panic. + * To prevent it, we should change its state first. + */ + common->state = DBOX_STATE_DELETE; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.created.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + /*! + * \note + * + * "if (handler->id == NULL) {" + * + * The instance is not created yet. + * But the master forcely destroy it and send destroyed event to this + * without the created event. + * + * It could be destroyed when a slave has critical error(fault) + * before creating an instance successfully. + */ + if (handler->cbs.created.cb == handler->cbs.deleted.cb) { + if (handler->cbs.created.data != handler->cbs.deleted.data) { + DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id); + } + + handler->cbs.deleted.cb = NULL; + handler->cbs.deleted.data = NULL; + } + + cb = handler->cbs.created.cb; + cbdata = handler->cbs.created.data; + + handler->cbs.created.cb = NULL; + handler->cbs.created.data = NULL; + + if (reason == (int)DBOX_STATUS_ERROR_NONE) { + reason = DBOX_STATUS_ERROR_CANCEL; + } + + cb(handler, reason, cbdata); + } else if (common->id) { + if (handler->cbs.deleted.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.deleted.cb; + cbdata = handler->cbs.deleted.data; + + handler->cbs.deleted.cb = NULL; + handler->cbs.deleted.data = NULL; + + cb(handler, reason, cbdata); + } else { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + } + } + + /* Just try to delete it, if a user didn't remove it from the live box list */ + dbox_unref(handler, 1); + } + +out: + return NULL; +} + +static struct packet *master_dbox_update_begin(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + const char *id; + const char *content; + const char *title; + const char *fbfile; + double priority; + int ret; + + ret = packet_get(packet, "ssdsss", &pkgname, &id, &priority, &content, &title, &fbfile); + if (ret != 6) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("(%s) is not created\n", id); + goto out; + } + + dbox_set_priority(common, priority); + dbox_set_content(common, content); + dbox_set_title(common, title); + + /*! + * \NOTE + * Width & Height is not changed in this case. + * If the active update is began, the size should not be changed, + * And if the size is changed, the provider should finish the updating first. + * And then begin updating again after change its size. + */ + if (dbox_get_dbox_fb(common)) { + (void)dbox_set_dbox_fb(common, fbfile); + + ret = dbox_sync_dbox_fb(common); + + if (ret != (int)DBOX_STATUS_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret); + } else { + struct dlist *l; + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_UPDATE_BEGIN); + } + } + } else { + ErrPrint("Invalid request[%s], %s\n", id, fbfile); + } + +out: + return NULL; +} + +static struct packet *master_gbar_update_begin(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + const char *id; + const char *fbfile; + int ret; + + ret = packet_get(packet, "sss", &pkgname, &id, &fbfile); + if (ret != 2) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (dbox_get_gbar_fb(common)) { + (void)dbox_set_gbar_fb(common, fbfile); + + ret = dbox_sync_gbar_fb(common); + if (ret != (int)DBOX_STATUS_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret); + } else { + struct dlist *l; + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_UPDATE_BEGIN); + } + } + } else { + ErrPrint("Invalid request[%s], %s\n", id, fbfile); + } + +out: + return NULL; +} + +static struct packet *master_dbox_update_end(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + const char *id; + int ret; + + ret = packet_get(packet, "ss", &pkgname, &id); + if (ret != 2) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (dbox_get_dbox_fb(common)) { + struct dlist *l; + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_UPDATE_END); + } + } else { + ErrPrint("Invalid request[%s]\n", id); + } + +out: + return NULL; +} + +static struct packet *master_key_status(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + const char *pkgname; + const char *id; + int ret; + int status; + + ret = packet_get(packet, "ssi", &pkgname, &id, &status); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + common->request.key_event = 0; + dlist_foreach(common->dynamicbox_list, l, handler) { + if (handler->cbs.key_event.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.key_event.cb; + cbdata = handler->cbs.key_event.data; + + handler->cbs.key_event.cb = NULL; + handler->cbs.key_event.data = NULL; + + cb(handler, status, cbdata); + } else { + ErrPrint("Invalid event[%s]\n", id); + } + } + +out: + return NULL; +} + +static struct packet *master_request_close_gbar(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + const char *pkgname; + const char *id; + int ret; + int reason; + + ret = packet_get(packet, "ssi", &pkgname, &id, &reason); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (!common->is_gbar_created) { + DbgPrint("GBAR is not created, closing what?(%s)\n", id); + goto out; + } + + DbgPrint("Reason: %d\n", reason); + + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_REQUEST_CLOSE_GBAR); + } +out: + return NULL; +} + +static struct packet *master_access_status(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + const char *pkgname; + const char *id; + int ret; + int status; + + ret = packet_get(packet, "ssi", &pkgname, &id, &status); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + common->request.access_event = 0; + dlist_foreach(common->dynamicbox_list, l, handler) { + if (handler->cbs.access_event.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.access_event.cb; + cbdata = handler->cbs.access_event.data; + + handler->cbs.access_event.cb = NULL; + handler->cbs.access_event.data = NULL; + + cb(handler, status, cbdata); + } + } +out: + return NULL; +} + +static struct packet *master_gbar_update_end(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + const char *id; + int ret; + + ret = packet_get(packet, "ss", &pkgname, &id); + if (ret != 2) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance[%s] is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("[%s] is not created\n", id); + goto out; + } + + if (dbox_get_dbox_fb(common)) { + struct dlist *l; + + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_UPDATE_END); + } + } else { + ErrPrint("Invalid request[%s]", id); + } + +out: + return NULL; +} + +static struct packet *master_extra_info(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *content; + const char *title; + const char *icon; + const char *name; + double priority; + int ret; + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + struct dlist *n; + + ret = packet_get(packet, "ssssssd", &pkgname, &id, + &content, &title, + &icon, &name, + &priority); + if (ret != 7) { + ErrPrint("Invalid parameters\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + /*! + * \note + * Already deleted by the user. + * Don't try to notice anything with this, Just ignore all events + * Beacuse the user doesn't wants know about this anymore + */ + ErrPrint("(%s) is not exists, but updated\n", id); + goto out; + } + + dbox_set_priority(common, priority); + dbox_set_content(common, content); + dbox_set_title(common, title); + dbox_set_alt_icon(common, icon); + dbox_set_alt_name(common, name); + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_EXTRA_INFO_UPDATED); + } +out: + return NULL; +} + +static struct packet *master_extra_updated(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + dynamicbox_h handler; + struct dynamicbox_common *common; + int ret; + int x; + int y; + int w; + int h; + int is_gbar; + int event_type; + int idx; + + ret = packet_get(packet, "ssiiiiii", &pkgname, &id, &is_gbar, &idx, &x, &y, &w, &h); + if (ret != 8) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + /*! + * \note + * Already deleted by the user. + * Don't try to notice anything with this, Just ignore all events + * Beacuse the user doesn't wants know about this anymore + */ + ErrPrint("(%s) is not exists, but updated\n", id); + goto out; + } + + if (is_gbar) { + common->gbar.last_damage.x = x; + common->gbar.last_damage.y = y; + common->gbar.last_damage.w = w; + common->gbar.last_damage.h = h; + common->gbar.last_extra_buffer_idx = idx; + + event_type = DBOX_EVENT_GBAR_EXTRA_UPDATED; + } else { + common->dbox.last_damage.x = x; + common->dbox.last_damage.y = y; + common->dbox.last_damage.w = w; + common->dbox.last_damage.h = h; + common->dbox.last_extra_buffer_idx = idx; + + event_type = DBOX_EVENT_DBOX_EXTRA_UPDATED; + + if (conf_frame_drop_for_resizing() && common->request.size_changed) { + /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ + DbgPrint("Discards obsoloted update event\n"); + ret = DBOX_STATUS_ERROR_BUSY; + } else { + if (!conf_manual_sync()) { + ret = dbox_sync_dbox_fb(common); + if (ret != (int)DBOX_STATUS_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret); + } + } else { + ret = DBOX_STATUS_ERROR_NONE; + } + } + } + + if (!common->request.created && ret == (int)DBOX_STATUS_ERROR_NONE) { + struct dlist *l; + struct dlist *n; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, event_type); + } + } + +out: + return NULL; +} + +static struct packet *master_dbox_updated(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *fbfile; + const char *safe_file; + dynamicbox_h handler; + struct dynamicbox_common *common; + int ret; + int x; + int y; + int w; + int h; + + ret = packet_get(packet, "ssssiiii", &pkgname, &id, &fbfile, &safe_file, &x, &y, &w, &h); + if (ret != 8) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + /*! + * \note + * Already deleted by the user. + * Don't try to notice anything with this, Just ignore all events + * Beacuse the user doesn't wants know about this anymore + */ + ErrPrint("(%s) is not exists, but updated\n", id); + goto out; + } + + common->dbox.last_damage.x = x; + common->dbox.last_damage.y = y; + common->dbox.last_damage.w = w; + common->dbox.last_damage.h = h; + common->dbox.last_extra_buffer_idx = DBOX_PRIMARY_BUFFER; + dbox_set_filename(common, safe_file); + + if (dbox_text_dbox(common)) { + const char *common_filename; + + common_filename = common->filename ? common->filename : util_uri_to_path(common->id); + + (void)parse_desc(common, common_filename, 0); + /*! + * \note + * DESC parser will call the "text event callback". + * Don't need to call global event callback in this case. + */ + dbox_unlink_filename(common); + goto out; + } else if (dbox_get_dbox_fb(common)) { + /*! + * \todo + * replace this with "flag" instead of "callback address" + */ + if (conf_frame_drop_for_resizing() && common->request.size_changed) { + /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ + DbgPrint("Discards obsoloted update event\n"); + ret = DBOX_STATUS_ERROR_BUSY; + } else { + (void)dbox_set_dbox_fb(common, fbfile); + + if (!conf_manual_sync()) { + ret = dbox_sync_dbox_fb(common); + if (ret != (int)DBOX_STATUS_ERROR_NONE) { + ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret); + } + } else { + ret = DBOX_STATUS_ERROR_NONE; + } + } + } else { + ret = DBOX_STATUS_ERROR_NONE; + } + + if (ret == (int)DBOX_STATUS_ERROR_NONE && !common->request.created) { + struct dlist *l; + struct dlist *n; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_UPDATED); + } + } + dbox_unlink_filename(common); + +out: + return NULL; +} + +static struct packet *master_gbar_created(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + const char *id; + const char *buf_id; + struct dlist *l; + struct dlist *n; + int width; + int height; + int ret; + int status; + + ret = packet_get(packet, "sssiii", &pkgname, &id, &buf_id, &width, &height, &status); + if (ret != 6) { + ErrPrint("Invalid argument\n"); + goto out; + } + + DbgPrint("[%s]\n", pkgname); + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("Instance(%s) is not created\n", id); + goto out; + } + + if (!common->request.gbar_created) { + ErrPrint("GBAR create request is canceled\n"); + goto out; + } + + common->is_gbar_created = (status == (int)DBOX_STATUS_ERROR_NONE); + common->request.gbar_created = 0; + + if (common->is_gbar_created) { + dbox_set_gbarsize(common, width, height); + if (dbox_text_gbar(common)) { + DbgPrint("Text TYPE does not need to handle this\n"); + } else { + (void)dbox_set_gbar_fb(common, buf_id); + + switch (common->gbar.type) { + case GBAR_TYPE_SCRIPT: + case GBAR_TYPE_BUFFER: + switch (fb_type(dbox_get_gbar_fb(common))) { + case DBOX_FB_TYPE_FILE: + case DBOX_FB_TYPE_SHM: + common->gbar.lock = dynamicbox_service_create_lock(common->id, DBOX_TYPE_GBAR, DBOX_LOCK_READ); + break; + case DBOX_FB_TYPE_PIXMAP: + case DBOX_FB_TYPE_ERROR: + default: + break; + } + break; + case GBAR_TYPE_UIFW: + case GBAR_TYPE_TEXT: + default: + break; + } + + ret = dbox_sync_gbar_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + } + } + + DbgPrint("PERF_DBOX\n"); + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.gbar_created.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.gbar_created.cb; + cbdata = handler->cbs.gbar_created.data; + + handler->cbs.gbar_created.cb = NULL; + handler->cbs.gbar_created.data = NULL; + + /*! + * Before call the Callback function, + * gbar_create_cb must be reset. + * Because, in the create callback, user can call create_gbar function again. + */ + cb(handler, status, cbdata); + } else if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_CREATED); + } + } + +out: + return NULL; +} + +static struct packet *master_gbar_destroyed(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dlist *l; + struct dynamicbox_common *common; + const char *pkgname; + const char *id; + int ret; + int status; + + ret = packet_get(packet, "ssi", &pkgname, &id, &status); + if (ret != 3) { + ErrPrint("Invalid argument\n"); + goto out; + } + + DbgPrint("[%s]\n", pkgname); + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("Instance(%s) is not created\n", id); + goto out; + } + + if (common->is_gbar_created == 0) { + ErrPrint("GBAR is not created, event is ignored\n"); + goto out; + } + + common->is_gbar_created = 0; + common->request.gbar_destroyed = 0; + + dlist_foreach(common->dynamicbox_list, l, handler) { + if (handler->cbs.gbar_destroyed.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.gbar_destroyed.cb; + cbdata = handler->cbs.gbar_destroyed.data; + + handler->cbs.gbar_destroyed.cb = NULL; + handler->cbs.gbar_destroyed.data = NULL; + + /*! + * Before call the Callback function, + * gbar_destroyed_cb must be reset. + * Because, in the create callback, user can call destroy_gbar function again. + */ + cb(handler, status, cbdata); + } else if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_DESTROYED); + } + } + + /*! + * \note + * Lock file should be deleted after all callbacks are processed. + */ + switch (common->gbar.type) { + case GBAR_TYPE_SCRIPT: + case GBAR_TYPE_BUFFER: + switch (fb_type(dbox_get_gbar_fb(common))) { + case DBOX_FB_TYPE_FILE: + case DBOX_FB_TYPE_SHM: + dynamicbox_service_destroy_lock(common->gbar.lock); + common->gbar.lock = NULL; + break; + case DBOX_FB_TYPE_PIXMAP: + case DBOX_FB_TYPE_ERROR: + default: + break; + } + break; + case GBAR_TYPE_UIFW: + case GBAR_TYPE_TEXT: + default: + break; + } + +out: + return NULL; +} + +static struct packet *master_gbar_updated(pid_t pid, int handle, const struct packet *packet) +{ + const char *pkgname; + const char *id; + const char *descfile; + const char *fbfile; + int ret; + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + int x; + int y; + int w; + int h; + + ret = packet_get(packet, "ssssiiii", &pkgname, &id, &fbfile, &descfile, &x, &y, &w, &h); + if (ret != 8) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("Instance(%s) is not exists\n", id); + goto out; + } + + common->gbar.last_damage.x = x; + common->gbar.last_damage.y = y; + common->gbar.last_damage.w = w; + common->gbar.last_damage.h = h; + + if (common->state != DBOX_STATE_CREATE) { + /*! + * \note + * This handler is already deleted by the user. + * So don't try to notice anything about this anymore. + * Just ignore all events. + */ + ErrPrint("Instance(%s) is not created\n", id); + goto out; + } + + if (dbox_text_gbar(common)) { + (void)parse_desc(common, descfile, 1); + } else { + if (conf_frame_drop_for_resizing() && common->request.size_changed) { + /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ + DbgPrint("Discards obsoloted update event\n"); + } else { + (void)dbox_set_gbar_fb(common, fbfile); + + if (!conf_manual_sync()) { + ret = dbox_sync_gbar_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret); + } else { + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_UPDATED); + } + } + } else { + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_UPDATED); + } + } + } + } + +out: + return NULL; +} + +static struct packet *master_gbar_extra_buffer_destroyed(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int pixmap; + int idx; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not found\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("DBOX(%s) is not created yet\n", id); + goto out; + } + + if (!common->gbar.extra_buffer && conf_extra_buffer_count()) { + common->gbar.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->gbar.extra_buffer)); + if (!common->gbar.extra_buffer) { + ErrPrint("DBOX(%s) calloc: %s\n", id, strerror(errno)); + } + } + + common->gbar.last_extra_buffer_idx = idx; + if (common->gbar.extra_buffer[idx] != pixmap) { + DbgPrint("Extra buffer Pixmap is not matched %u <> %u\n", common->dbox.extra_buffer[idx], pixmap); + } + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_EXTRA_BUFFER_DESTROYED); + } +out: + return NULL; +} + +static struct packet *master_dbox_extra_buffer_destroyed(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int idx; + int pixmap; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not found\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("DBOX(%s) is not created yet\n", id); + goto out; + } + + if (!common->dbox.extra_buffer && conf_extra_buffer_count()) { + common->dbox.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->dbox.extra_buffer)); + if (!common->dbox.extra_buffer) { + ErrPrint("DBOX(%s) calloc: %s\n", id, strerror(errno)); + } + } + + common->dbox.last_extra_buffer_idx = idx; + if (common->dbox.extra_buffer[idx] != pixmap) { + DbgPrint("Extra buffer Pixmap is not matched %u <> %u\n", common->dbox.extra_buffer[idx], pixmap); + } + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_EXTRA_BUFFER_DESTROYED); + } +out: + return NULL; +} + +static struct packet *master_dbox_extra_buffer_created(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int idx; + int pixmap; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not found\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("DBOX(%s) is not created yet\n", id); + goto out; + } + + if (!common->dbox.extra_buffer && conf_extra_buffer_count()) { + common->dbox.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->dbox.extra_buffer)); + if (!common->dbox.extra_buffer) { + ErrPrint("DBOX(%s) calloc: %s\n", id, strerror(errno)); + } + } + + common->dbox.last_extra_buffer_idx = idx; + common->dbox.extra_buffer[idx] = pixmap; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_EXTRA_BUFFER_CREATED); + } +out: + return NULL; +} + +static struct packet *master_gbar_extra_buffer_created(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + struct dlist *l; + struct dlist *n; + const char *id; + int pixmap; + int idx; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &pixmap, &idx); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + if (idx < 0 || idx >= conf_extra_buffer_count()) { + ErrPrint("Extra buffer count is not matched\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not found\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("DBOX(%s) is not created yet\n", id); + goto out; + } + + if (!common->gbar.extra_buffer && conf_extra_buffer_count()) { + common->gbar.extra_buffer = calloc(conf_extra_buffer_count(), sizeof(*common->gbar.extra_buffer)); + if (!common->gbar.extra_buffer) { + ErrPrint("DBOX(%s) calloc: %s\n", id, strerror(errno)); + } + } + + common->gbar.last_extra_buffer_idx = idx; + common->gbar.extra_buffer[idx] = pixmap; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_EXTRA_BUFFER_CREATED); + } +out: + return NULL; +} + +static struct packet *master_update_mode(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + struct dlist *n; + const char *pkgname; + const char *id; + int active_mode; + int status; + int ret; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "ssii", &pkgname, &id, &status, &active_mode); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not found\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("DBOX(%s) is not created yet\n", id); + goto out; + } + + if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_set_update_mode(common, active_mode); + } + + common->request.update_mode = 0; + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.update_mode.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.update_mode.cb; + cbdata = handler->cbs.update_mode.data; + + handler->cbs.update_mode.cb = NULL; + handler->cbs.update_mode.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_UPDATE_MODE_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + const char *pkgname; + const char *id; + const char *fbfile; + int status; + int ret; + int w; + int h; + int is_gbar; + + if (!packet) { + ErrPrint("Invalid packet\n"); + goto out; + } + + ret = packet_get(packet, "sssiiii", &pkgname, &id, &fbfile, &is_gbar, &w, &h, &status); + if (ret != 7) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not found\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("DBOX(%s) is not created yet\n", id); + goto out; + } + + common->request.size_changed = 0; + if (is_gbar) { + /*! + * \NOTE + * GBAR is not able to resized by the client. + * GBAR is only can be managed by the provider. + * So the GBAR has no private resized event handler. + * Notify it via global event handler only. + */ + if (status == (int)DBOX_STATUS_ERROR_NONE) { + struct dlist *l; + + dbox_set_gbarsize(common, w, h); + dlist_foreach(common->dynamicbox_list, l, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GBAR_SIZE_CHANGED); + } + } else { + ErrPrint("This is not possible. GBAR Size is changed but the return value is not ZERO (%d)\n", status); + } + } else { + struct dlist *l; + struct dlist *n; + + if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_set_size(common, w, h); + + /*! + * \NOTE + * If there is a created DBOX FB, + * Update it too. + */ + if (dbox_get_dbox_fb(common)) { + (void)dbox_set_dbox_fb(common, fbfile); + + ret = dbox_sync_dbox_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + + /* Just update the size info only. */ + } + } + + /*! + * \NOTE + * I cannot believe client. + * So I added some log before & after call the user callback. + */ + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.size_changed.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.size_changed.cb; + cbdata = handler->cbs.size_changed.data; + + handler->cbs.size_changed.cb = NULL; + handler->cbs.size_changed.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_SIZE_CHANGED); + } + } + } + +out: + return NULL; +} + +static struct packet *master_period_changed(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + struct dlist *n; + const char *pkgname; + const char *id; + int ret; + double period; + int status; + + ret = packet_get(packet, "idss", &status, &period, &pkgname, &id); + if (ret != 4) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not found\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + ErrPrint("DBOX(%s) is not created\n", id); + goto out; + } + + if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_set_period(common, period); + } + + common->request.period_changed = 0; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.period_changed.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.period_changed.cb; + cbdata = handler->cbs.period_changed.data; + + handler->cbs.period_changed.cb = NULL; + handler->cbs.period_changed.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_PERIOD_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_group_changed(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + struct dlist *n; + const char *pkgname; + const char *id; + int ret; + const char *cluster; + const char *category; + int status; + + ret = packet_get(packet, "ssiss", &pkgname, &id, &status, &cluster, &category); + if (ret != 5) { + ErrPrint("Invalid argument\n"); + goto out; + } + + common = dbox_find_common_handle(pkgname, id); + if (!common) { + ErrPrint("DBOX(%s) is not exists\n", id); + goto out; + } + + if (common->state != DBOX_STATE_CREATE) { + /*! + * \note + * Do no access this handler, + * You cannot believe this handler anymore. + */ + ErrPrint("DBOX(%s) is not created\n", id); + goto out; + } + + if (status == (int)DBOX_STATUS_ERROR_NONE) { + (void)dbox_set_group(common, cluster, category); + } + + common->request.group_changed = 0; + + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.group_changed.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.group_changed.cb; + cbdata = handler->cbs.group_changed.data; + + handler->cbs.group_changed.cb = NULL; + handler->cbs.group_changed.data = NULL; + + cb(handler, status, cbdata); + } else if (status == (int)DBOX_STATUS_ERROR_NONE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_GROUP_CHANGED); + } + } + +out: + return NULL; +} + +static struct packet *master_update_id(pid_t pid, int handle, const struct packet *packet) +{ + int ret; + double timestamp; + const char *id; + struct dynamicbox_common *common; + + if (!packet) { + ErrPrint("Invalid packet\n"); + return NULL; + } + + ret = packet_get(packet, "ds", ×tamp, &id); + if (ret != 2) { + ErrPrint("Invalid paramter\n"); + return NULL; + } + + common = dbox_find_common_handle_by_timestamp(timestamp); + if (!common) { + ErrPrint("Handle is not found for %d\n", timestamp); + return NULL; + } + + dbox_set_id(common, id); + DbgPrint("Update ID(%s) for %lf\n", id, timestamp); + return NULL; +} + +static struct packet *master_created(pid_t pid, int handle, const struct packet *packet) +{ + dynamicbox_h handler; + struct dynamicbox_common *common; + struct dlist *l; + + int dbox_w; + int dbox_h; + int gbar_w; + int gbar_h; + const char *pkgname; + const char *id; + + const char *content; + const char *cluster; + const char *category; + const char *dbox_fname; + const char *gbar_fname; + const char *title; + + double timestamp; + const char *auto_launch; + double priority; + int size_list; + int user; + int pinup_supported; + dynamicbox_dbox_type_e dbox_type; + dynamicbox_gbar_type_e gbar_type; + double period; + int is_pinned_up; + + int old_state = DBOX_STATE_DESTROYED; + + int ret; + + ret = packet_get(packet, "dsssiiiisssssdiiiiidsi", + ×tamp, + &pkgname, &id, &content, + &dbox_w, &dbox_h, &gbar_w, &gbar_h, + &cluster, &category, &dbox_fname, &gbar_fname, + &auto_launch, &priority, &size_list, &user, &pinup_supported, + &dbox_type, &gbar_type, &period, &title, &is_pinned_up); + if (ret != 22) { + ErrPrint("Invalid argument\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + goto out; + } + + ErrPrint("[%lf] pkgname: %s, id: %s, content: %s, " + "gbar_w: %d, gbar_h: %d, dbox_w: %d, dbox_h: %d, " + "cluster: %s, category: %s, dbox_fname: \"%s\", gbar_fname: \"%s\", " + "auto_launch: %s, priority: %lf, size_list: %d, user: %d, pinup: %d, " + "dbox_type: %d, gbar_type: %d, period: %lf, title: [%s], is_pinned_up: %d\n", + timestamp, pkgname, id, content, + gbar_w, gbar_h, dbox_w, dbox_h, + cluster, category, dbox_fname, gbar_fname, + auto_launch, priority, size_list, user, pinup_supported, + dbox_type, gbar_type, period, title, is_pinned_up); + + common = dbox_find_common_handle_by_timestamp(timestamp); + if (!common) { + handler = dbox_new_dynamicbox(pkgname, id, timestamp, cluster, category); + if (!handler) { + ErrPrint("Failed to create a new dynamicbox\n"); + ret = DBOX_STATUS_ERROR_FAULT; + goto out; + } + common = handler->common; + old_state = common->state; + } else { + if (common->state != DBOX_STATE_CREATE) { + if (common->state != DBOX_STATE_DELETE) { + /*! + * \note + * This is not possible!!! + */ + ErrPrint("Invalid handler\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + goto out; + } + + /*! + * \note + * After get the delete states, + * call the create callback with deleted result. + */ + } + + old_state = common->state; + + if (common->id && common->request.created == 0) { + ErrPrint("Already created: timestamp[%lf] " + "pkgname[%s], id[%s] content[%s] " + "cluster[%s] category[%s] dbox_fname[%s] gbar_fname[%s]\n", + timestamp, pkgname, id, + content, cluster, category, + dbox_fname, gbar_fname); + + ret = DBOX_STATUS_ERROR_ALREADY; + goto out; + } + + dbox_set_id(common, id); + } + + common->request.created = 0; + dbox_set_size(common, dbox_w, dbox_h); + common->dbox.type = dbox_type; + common->is_pinned_up = is_pinned_up; + + switch (dbox_type) { + case DBOX_TYPE_UIFW: + case DBOX_TYPE_FILE: + break; + case DBOX_TYPE_SCRIPT: + case DBOX_TYPE_BUFFER: + if (!strlen(dbox_fname)) { + break; + } + (void)dbox_set_dbox_fb(common, dbox_fname); + + /*! + * \note + * DBOX should create the lock file from here. + * Even if the old_state == DBOX_STATE_DELETE, + * the lock file will be deleted from deleted event callback. + */ + switch (fb_type(dbox_get_dbox_fb(common))) { + case DBOX_FB_TYPE_FILE: + case DBOX_FB_TYPE_SHM: + common->dbox.lock = dynamicbox_service_create_lock(common->id, DBOX_TYPE_DBOX, DBOX_LOCK_READ); + break; + case DBOX_FB_TYPE_PIXMAP: + case DBOX_FB_TYPE_ERROR: + default: + break; + } + + ret = dbox_sync_dbox_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + break; + case DBOX_TYPE_TEXT: + dbox_set_text_dbox(common); + break; + default: + break; + } + + common->gbar.type = gbar_type; + dbox_set_gbarsize(common, gbar_w, gbar_h); + dbox_set_default_gbarsize(common, gbar_w, gbar_h); + switch (gbar_type) { + case GBAR_TYPE_SCRIPT: + case GBAR_TYPE_BUFFER: + if (!strlen(gbar_fname)) { + break; + } + + dbox_set_gbar_fb(common, gbar_fname); + + ret = dbox_sync_gbar_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } + + /*! + * \brief + * GBAR doesn't need to create the lock file from here. + * Just create it from GBAR_CREATED event. + */ + + break; + case GBAR_TYPE_TEXT: + dbox_set_text_gbar(common); + break; + case GBAR_TYPE_UIFW: + default: + break; + } + + dbox_set_priority(common, priority); + + dbox_set_size_list(common, size_list); + dbox_set_group(common, cluster, category); + + dbox_set_content(common, content); + dbox_set_title(common, title); + + dbox_set_user(common, user); + + dbox_set_auto_launch(common, auto_launch); + dbox_set_pinup(common, pinup_supported); + + dbox_set_period(common, period); + + ret = 0; + + if (common->state == DBOX_STATE_CREATE) { + dlist_foreach(common->dynamicbox_list, l, handler) { + /*! + * \note + * These callback can change the handler->state. + * So we have to use the "old_state" which stored state before call these callbacks + */ + + if (handler->cbs.created.cb) { + dynamicbox_ret_cb cb; + void *cbdata; + + cb = handler->cbs.created.cb; + cbdata = handler->cbs.created.data; + + handler->cbs.created.cb = NULL; + handler->cbs.created.data = NULL; + + cb(handler, ret, cbdata); + } else { + dbox_invoke_event_handler(handler, DBOX_EVENT_CREATED); + } + + /** + * If there is any updates before get this event, + * Invoke all update event forcely + */ + switch (common->dbox.last_extra_buffer_idx) { + case DBOX_UNKNOWN_BUFFER: + break; + case DBOX_PRIMARY_BUFFER: + DbgPrint("Primary buffer updated\n"); + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_UPDATED); + break; + default: + DbgPrint("Extra buffer updated\n"); + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_EXTRA_UPDATED); + break; + } + } + } + +out: + if (ret == 0 && old_state == DBOX_STATE_DELETE) { + struct dlist *n; + + DbgPrint("Take place an unexpected case [%d]\n", common->refcnt); + dlist_foreach_safe(common->dynamicbox_list, l, n, handler) { + if (handler->cbs.created.cb) { + if (!handler->common->request.deleted) { + if (dbox_send_delete(handler, common->delete_type, handler->cbs.created.cb, handler->cbs.created.data) < 0) { + /*! + * \note + * Already sent or something else happens. + * Callback will be called in any cases + */ + } + } else if (handler->state != DBOX_STATE_DELETE) { + handler->cbs.created.cb(handler, DBOX_STATUS_ERROR_CANCEL, handler->cbs.created.data); + dbox_unref(handler, 1); + } + } else { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } + + /*! + * \note + * handler->cbs.created.cb = NULL; + * handler->cbs.created.data = NULL; + * + * Do not clear this to use this from the deleted event callback. + * if this value is not cleared when the deleted event callback check it, + * it means that the created function is not called yet. + * Then the call the deleted event callback with DBOX_STATUS_ERROR_CANCEL errno. + */ + } + + return NULL; +} + +static struct method s_table[] = { + { /* DBOX_UPDATED */ + .cmd = CMD_STR_DBOX_UPDATED, /* pkgname, id, dbox_w, dbox_h, priority, ret */ + .handler = master_dbox_updated, + }, + { /* GBAR_UPDATED */ + .cmd = CMD_STR_GBAR_UPDATED, /* pkgname, id, descfile, pd_w, pd_h, ret */ + .handler = master_gbar_updated, + }, + { /* EXTRA_UPDATED */ + .cmd = CMD_STR_EXTRA_UPDATED, + .handler = master_extra_updated, + }, + { /* EXTRA_INFO */ + .cmd = CMD_STR_EXTRA_INFO, + .handler = master_extra_info, + }, + { /* DELETED */ + .cmd = CMD_STR_DELETED, /* pkgname, id, timestamp, ret */ + .handler = master_deleted, + }, + { /* FAULTED */ + .cmd = CMD_STR_FAULT_PACKAGE, /* pkgname, id, function, ret */ + .handler = master_fault_package, + }, + { /* SCROLL */ + .cmd = CMD_STR_SCROLL, + .handler = master_hold_scroll, + }, + { /* DBOX_UPDATE_BEGIN */ + .cmd = CMD_STR_DBOX_UPDATE_BEGIN, + .handler = master_dbox_update_begin, + }, + { /* DBOX_UPDATE_END */ + .cmd = CMD_STR_DBOX_UPDATE_END, + .handler = master_dbox_update_end, + }, + { /* GBAR_UPDATE_BEGIN */ + .cmd = CMD_STR_GBAR_UPDATE_BEGIN, + .handler = master_gbar_update_begin, + }, + { /* GBAR_UPDATE_END */ + .cmd = CMD_STR_GBAR_UPDATE_END, + .handler = master_gbar_update_end, + }, + { /* ACCESS_STATUS */ + .cmd = CMD_STR_ACCESS_STATUS, + .handler = master_access_status, + }, + { /* KEY_STATUS */ + .cmd = CMD_STR_KEY_STATUS, + .handler = master_key_status, + }, + { /* CLOSE_GBAR */ + .cmd = CMD_STR_CLOSE_GBAR, + .handler = master_request_close_gbar, + }, + { /* GBAR_CREATED */ + .cmd = CMD_STR_GBAR_CREATED, + .handler = master_gbar_created, + }, + { /* GBAR_DESTROYED */ + .cmd = CMD_STR_GBAR_DESTROYED, + .handler = master_gbar_destroyed, + }, + { /* CREATED */ + .cmd = CMD_STR_CREATED, + .handler = master_created, + }, + { /* GROUP_CHANGED */ + .cmd = CMD_STR_GROUP_CHANGED, + .handler = master_group_changed, + }, + { /* PERIOD_CHANGED */ + .cmd = CMD_STR_PERIOD_CHANGED, + .handler = master_period_changed, + }, + { /* SIZE_CHANGED */ + .cmd = CMD_STR_SIZE_CHANGED, + .handler = master_size_changed, + }, + { /* PINUP */ + .cmd = CMD_STR_PINUP, + .handler = master_pinup, + }, + { /* UPDATE_MODE */ + .cmd = CMD_STR_UPDATE_MODE, + .handler = master_update_mode, + }, + { /* DBOX_CREATE_XBUF */ + .cmd = CMD_STR_DBOX_CREATE_XBUF, + .handler = master_dbox_extra_buffer_created, + }, + { /* GBAR_CREATE_XBUF */ + .cmd = CMD_STR_GBAR_CREATE_XBUF, + .handler = master_gbar_extra_buffer_created, + }, + { /* DBOX_DESTROY_XBUF */ + .cmd = CMD_STR_DBOX_DESTROY_XBUF, + .handler = master_dbox_extra_buffer_destroyed, + }, + { /* GBAR_DESTROY_XBUF */ + .cmd = CMD_STR_GBAR_DESTROY_XBUF, + .handler = master_gbar_extra_buffer_destroyed, + }, + { /* UPDATE_ID */ + .cmd = CMD_STR_UPDATE_ID, + .handler = master_update_id, + }, + { + .cmd = NULL, + .handler = NULL, + }, +}; + +static void acquire_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + if (!result) { + DbgPrint("Result packet is not valid\n"); + } else { + int ret; + int extra_buffer_count; + + if (packet_get(result, "ii", &ret, &extra_buffer_count) != 2) { + ErrPrint("Invalid argument\n"); + } else { + DbgPrint("Acquire returns: %d (%d)\n", ret, extra_buffer_count); + conf_set_extra_buffer_count(extra_buffer_count); + } + } + + return; +} + +static inline int make_connection(void) +{ + struct packet *packet; + unsigned int cmd = CMD_ACQUIRE; + int ret; + + DbgPrint("Let's making connection!\n"); + + s_info.fd = com_core_packet_client_init(client_addr(), 0, s_table); + if (s_info.fd < 0) { + ErrPrint("Try this again later\n"); + return DBOX_STATUS_ERROR_IO_ERROR; + } + + packet = packet_create((const char *)&cmd, "ds", util_timestamp(), client_direct_addr()); + if (!packet) { + com_core_packet_client_fini(s_info.fd); + s_info.fd = -1; + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 1, acquire_cb, NULL); + if (ret < 0) { + ErrPrint("Master RPC returns %d\n", ret); + com_core_packet_client_fini(s_info.fd); + s_info.fd = -1; + return DBOX_STATUS_ERROR_IO_ERROR; + } + + return DBOX_STATUS_ERROR_NONE; +} + +static int connected_cb(int handle, void *data) +{ + master_rpc_check_and_fire_consumer(); + return 0; +} + +static void master_started_cb(keynode_t *node, void *data) +{ + int state = 0; + + if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0) { + ErrPrint("Unable to get [%s]\n", VCONFKEY_MASTER_STARTED); + } + + DbgPrint("Master state: %d\n", state); + if (state == 1 && make_connection() == (int)DBOX_STATUS_ERROR_NONE) { + int ret; + ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb); + if (ret < 0) { + DbgPrint("master_started vconf key de-registered [%d]\n", ret); + } + } +} + +static gboolean timeout_cb(gpointer data) +{ + if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) { + ErrPrint("Failed to add vconf for monitoring service state\n"); + } else { + DbgPrint("vconf event callback is registered\n"); + } + + master_started_cb(NULL, NULL); + + s_info.timer_id = 0; + return FALSE; +} + +static int disconnected_cb(int handle, void *data) +{ + if (s_info.fd != handle) { + /*!< This handle is not my favor */ + return 0; + } + + s_info.fd = -1; /*!< Disconnected */ + + master_rpc_clear_all_request(); + dbox_invoke_fault_handler(DBOX_FAULT_PROVIDER_DISCONNECTED, MASTER_PKGNAME, "default", "disconnected"); + + dbox_delete_all(); + + /* Try to reconnect after 1 sec later */ + if (!s_info.timer_id) { + DbgPrint("Reconnecting timer is added\n"); + s_info.timer_id = g_timeout_add(1000, timeout_cb, NULL); + if (s_info.timer_id == 0) { + ErrPrint("Unable to add reconnecting timer\n"); + return 0; + } + } else { + ErrPrint("Reconnecting timer is already exists\n"); + } + + return 0; +} + +static struct method s_direct_table[] = { + { + .cmd = CMD_STR_DBOX_UPDATED, /* pkgname, id, lb_w, lb_h, priority, ret */ + .handler = master_dbox_updated, + }, + { + .cmd = CMD_STR_GBAR_UPDATED, /* pkgname, id, descfile, pd_w, pd_h, ret */ + .handler = master_gbar_updated, + }, + { + .cmd = CMD_STR_EXTRA_UPDATED, + .handler = master_extra_updated, + }, + { + .cmd = NULL, + .handler = NULL, + }, +}; + +static void prepare_direct_update(void) +{ + char path[MAX_DIRECT_ADDR]; + + if (!conf_direct_update()) { + return; + } + + if (!strncmp(s_info.client_addr, COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { + ErrPrint("Remote model is not support this\n"); + return; + } + + snprintf(path, sizeof(path) - 1, "/tmp/.%d.%lf.dbox.viewer", getpid(), util_timestamp()); + + s_info.direct_addr = strdup(path); + if (!s_info.direct_addr) { + ErrPrint("strdup: %s\n", strerror(errno)); + return; + } + + s_info.direct_fd = com_core_packet_server_init(client_direct_addr(), s_direct_table); + if (s_info.direct_fd < 0) { + ErrPrint("Failed to prepare server: %s\n", client_direct_addr()); + return; + } + + DbgPrint("Direct update is prepared: %s - %d\n", client_direct_addr(), client_direct_fd()); +} + +int client_init(int use_thread) +{ + com_core_packet_use_thread(use_thread); + + s_info.client_addr = vconf_get_str(VCONFKEY_MASTER_CLIENT_ADDR); + if (!s_info.client_addr) { + s_info.client_addr = strdup(CLIENT_SOCKET); + if (!s_info.client_addr) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + } + + (void)file_service_init(); + + DbgPrint("Server Address: %s\n", s_info.client_addr); + + com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL); + com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL); + + /** + * @note + * Before creating a connection with master, + * Initiate the private channel for getting the updated event from providers + * How could we propagates the our address to every providers? + */ + prepare_direct_update(); + + if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) { + ErrPrint("Failed to add vconf for service state\n"); + } else { + DbgPrint("vconf event callback is registered\n"); + } + + master_started_cb(NULL, NULL); + return DBOX_STATUS_ERROR_NONE; +} + +int client_fd(void) +{ + return s_info.fd; +} + +const char *client_addr(void) +{ + return s_info.client_addr; +} + +const char *client_direct_addr(void) +{ + return s_info.direct_addr; +} + +int client_direct_fd(void) +{ + return s_info.direct_fd; +} + +int client_fini(void) +{ + int ret; + + (void)file_service_fini(); + + ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb); + if (ret < 0) { + DbgPrint("Ignore vconf key: %d\n", ret); + } + + com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL); + com_core_del_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL); + com_core_packet_client_fini(s_info.fd); + s_info.fd = -1; + + if (s_info.direct_fd >= 0) { + com_core_packet_server_fini(s_info.direct_fd); + s_info.direct_fd = -1; + } + + free(s_info.client_addr); + s_info.client_addr = NULL; + + free(s_info.direct_addr); + s_info.direct_addr = NULL; + return DBOX_STATUS_ERROR_NONE; +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/conf.c b/dynamicbox_viewer/src/conf.c new file mode 100644 index 0000000..fe0a448 --- /dev/null +++ b/dynamicbox_viewer/src/conf.c @@ -0,0 +1,82 @@ +#include +#include + +static struct info { + int manual_sync; + int frame_drop_for_resizing; + int shared_content; + int direct_update; + int extra_buffer_count; + + double event_filter; +} s_info = { + .manual_sync = 0, + .frame_drop_for_resizing = 1, + .shared_content = 0, + .direct_update = 0, + .extra_buffer_count = 0, + + .event_filter = 0.01f, +}; + +void conf_set_direct_update(int flag) +{ + s_info.direct_update = flag; +} + +int conf_direct_update(void) +{ + return s_info.direct_update; +} + +void conf_set_manual_sync(int flag) +{ + s_info.manual_sync = flag; +} + +int conf_manual_sync(void) +{ + return s_info.manual_sync; +} + +void conf_set_frame_drop_for_resizing(int flag) +{ + s_info.frame_drop_for_resizing = flag; +} + +int conf_frame_drop_for_resizing(void) +{ + return s_info.frame_drop_for_resizing; +} + +void conf_set_shared_content(int flag) +{ + s_info.shared_content = flag; +} + +int conf_shared_content(void) +{ + return s_info.shared_content; +} + +double conf_event_filter(void) +{ + return s_info.event_filter; +} + +void conf_set_event_filter(double filter) +{ + s_info.event_filter = filter; +} + +void conf_set_extra_buffer_count(int buffer_count) +{ + s_info.extra_buffer_count = buffer_count; +} + +int conf_extra_buffer_count(void) +{ + return s_info.extra_buffer_count; +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/desc_parser.c b/dynamicbox_viewer/src/desc_parser.c new file mode 100644 index 0000000..4103b90 --- /dev/null +++ b/dynamicbox_viewer/src/desc_parser.c @@ -0,0 +1,698 @@ +/* + * 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 +#include +#include /* malloc */ +#include /* strdup */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "dynamicbox.h" +#include "dynamicbox_internal.h" +#include "desc_parser.h" +#include "dlist.h" +#include "util.h" + +#define INFO_SIZE "size" +#define INFO_CATEGORY "category" + +static const char *type_list[] = { + "access", + "access,operation", + "color", + "drag", + "image", + "info", + "script", + "signal", + "text", + NULL +}; + +static const char *field_list[] = { + "type", + "part", + "data", + "option", + "id", + "target", + "file", + NULL +}; + +enum block_type { + TYPE_ACCESS, + TYPE_ACCESS_OP, + TYPE_COLOR, + TYPE_DRAG, + TYPE_IMAGE, + TYPE_INFO, + TYPE_SCRIPT, + TYPE_SIGNAL, + TYPE_TEXT, + TYPE_MAX +}; + +enum field_type { + FIELD_TYPE, + FIELD_PART, + FIELD_DATA, + FIELD_OPTION, + FIELD_ID, + FIELD_TARGET, + FIELD_FILE +}; + +struct block { + enum block_type type; + char *part; + char *data; + char *option; + char *id; + char *target; + char *file; + + /* Should be released */ + char *filebuf; + const char *filename; +}; + +static int update_text(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block || !block->part || !block->data) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_text) { + ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data); + } + + return 0; +} + +static int update_image(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block || !block->part) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_image) { + ops->update_image(handle, block->id, block->part, block->data, block->option); + } + + return 0; +} + +static int update_script(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block || !block->part) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_script) { + ops->update_script(handle, block->id, block->target, block->part, block->data, block->option); + } + + return 0; +} + +static int update_signal(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_signal) { + ops->update_signal(handle, block->id, block->data, block->part); + } + + return 0; +} + +static int update_drag(dynamicbox_h handle, struct block *block, int is_gbar) +{ + double dx, dy; + struct dynamicbox_script_operators *ops; + + if (!block || !block->data || !block->part) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) { + ErrPrint("Invalid format of data\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_drag) { + ops->update_drag(handle, block->id, block->part, dx, dy); + } + + return 0; +} + +static int update_info(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block || !block->part || !block->data) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (!strcasecmp(block->part, INFO_SIZE)) { + int w, h; + + if (sscanf(block->data, "%dx%d", &w, &h) != 2) { + ErrPrint("Invalid format (%s)\n", block->data); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (ops->update_info_size) { + ops->update_info_size(handle, block->id, w, h); + } + } else if (!strcasecmp(block->part, INFO_CATEGORY)) { + if (ops->update_info_category) { + ops->update_info_category(handle, block->id, block->data); + } + } + + return 0; +} + +static int update_access(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_access) { + ops->update_access(handle, block->id, block->part, block->data, block->option); + } + + return 0; +} + +static int operate_access(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->operate_access) { + ops->operate_access(handle, block->id, block->part, block->data, block->option); + } + + return 0; +} + +static int update_color(dynamicbox_h handle, struct block *block, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + if (!block) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_color) { + ops->update_color(handle, block->id, block->part, block->data); + } + + return 0; +} + +static inline int update_begin(dynamicbox_h handle, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_begin) { + ops->update_begin(handle); + } + + return 0; +} + +static inline int update_end(dynamicbox_h handle, int is_gbar) +{ + struct dynamicbox_script_operators *ops; + + ops = is_gbar ? &handle->cbs.gbar_ops : &handle->cbs.dbox_ops; + if (ops->update_end) { + ops->update_end(handle); + } + + return 0; +} + +static inline void delete_block(struct block *block) +{ + free(block->filebuf); + free(block); +} + +static inline void consuming_parsed_block(dynamicbox_h handle, int is_gbar, struct block *block) +{ + typedef int (*update_function_t)(dynamicbox_h handle, struct block *block, int is_gbar); + static update_function_t updators[] = { + update_access, + operate_access, + update_color, + update_drag, + update_image, + update_info, + update_script, + update_signal, + update_text, + NULL + }; + + if (block->type >= 0 || block->type < TYPE_MAX) { + (void)updators[block->type](handle, block, is_gbar); + } else { + ErrPrint("Block type[%d] is not valid\n", block->type); + } +} + +static inline char *load_file(const char *filename) +{ + char *filebuf = NULL; + int fd; + off_t filesize; + int ret; + size_t readsize = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + ErrPrint("open: %s (%s)\n", strerror(errno), filename); + return NULL; + } + + filesize = lseek(fd, 0L, SEEK_END); + if (filesize == (off_t)-1) { + ErrPrint("lseek: %s\n", strerror(errno)); + goto errout; + } + + if (lseek(fd, 0L, SEEK_SET) < 0) { + ErrPrint("lseek: %s\n", strerror(errno)); + goto errout; + } + + filebuf = malloc(filesize + 1); + if (!filebuf) { + ErrPrint("malloc: %s\n", strerror(errno)); + goto errout; + } + + while (readsize < filesize) { + ret = read(fd, filebuf + readsize, (size_t)filesize - readsize); + if (ret < 0) { + if (errno == EINTR) { + DbgPrint("Read is interrupted\n"); + continue; + } + + ErrPrint("read: %s\n", strerror(errno)); + free(filebuf); + filebuf = NULL; + break; + } + + readsize += ret; + } + + if (filebuf) { + filebuf[readsize] = '\0'; + } + + /*! + * \note + * Now, we are ready to parse the filebuf. + */ + +errout: + if (close(fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + + return filebuf; +} + +int parse_desc(struct dynamicbox_common *common, const char *filename, int is_gbar) +{ + int type_idx = 0; + int type_len = 0; + int field_idx = 0; + int field_len = 0; + char *filebuf; + char *fileptr; + char *ptr = NULL; + struct block *block = NULL; + struct dlist *block_list = NULL; + struct dlist *l; + struct dlist *n; + struct dlist *handle_iterator; + dynamicbox_h handler; + enum state { + BEGIN, + FIELD, + DATA, + END, + DONE, + ERROR, + } state; + + filebuf = load_file(filename); + if (!filebuf) { + return DBOX_STATUS_ERROR_IO_ERROR; + } + + fileptr = filebuf; + + state = BEGIN; + while (*fileptr && state != ERROR) { + switch (state) { + case BEGIN: + if (*fileptr == '{') { + block = calloc(1, sizeof(*block)); + if (!block) { + ErrPrint("calloc: %s\n", strerror(errno)); + state = ERROR; + continue; + } + state = FIELD; + ptr = NULL; + } + break; + case FIELD: + if (isspace(*fileptr)) { + if (ptr != NULL) { + *fileptr = '\0'; + } + } else if (*fileptr == '=') { + *fileptr = '\0'; + ptr = NULL; + state = DATA; + } else if (ptr == NULL) { + ptr = fileptr; + field_idx = 0; + field_len = 0; + + while (field_list[field_idx]) { + if (field_list[field_idx][field_len] == *fileptr) { + break; + } + field_idx++; + } + + if (!field_list[field_idx]) { + ErrPrint("Invalid field\n"); + state = ERROR; + continue; + } + + field_len++; + } else { + if (field_list[field_idx][field_len] != *fileptr) { + field_idx++; + while (field_list[field_idx]) { + if (!strncmp(field_list[field_idx], fileptr - field_len, field_len)) { + break; + } else { + field_idx++; + } + } + + if (!field_list[field_idx]) { + state = ERROR; + ErrPrint("field is not valid\n"); + continue; + } + } + + field_len++; + } + break; + case DATA: + switch (field_idx) { + case FIELD_TYPE: + if (ptr == NULL) { + if (isspace(*fileptr)) { + break; + } + + if (*fileptr == '\0') { + state = ERROR; + ErrPrint("Type is not valid\n"); + continue; + } + + ptr = fileptr; + type_idx = 0; + type_len = 0; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (type_list[type_idx][type_len] != *fileptr) { + type_idx++; + while (type_list[type_idx]) { + if (!strncmp(type_list[type_idx], fileptr - type_len, type_len)) { + break; + } else { + type_idx++; + } + } + + if (!type_list[type_idx]) { + state = ERROR; + ErrPrint("type is not valid (%s)\n", fileptr - type_len); + continue; + } + } + + if (!*fileptr) { + block->type = type_idx; + state = DONE; + ptr = NULL; + } + + type_len++; + break; + case FIELD_PART: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->part = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_DATA: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->data = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_OPTION: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->option = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_ID: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->id = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_TARGET: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->target = ptr; + state = DONE; + ptr = NULL; + } + break; + case FIELD_FILE: + if (ptr == NULL) { + ptr = fileptr; + } + + if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { + *fileptr = '\0'; + } + + if (!*fileptr) { + block->target = ptr; + state = DONE; + ptr = NULL; + } + default: + break; + } + + break; + case DONE: + if (isspace(*fileptr)) { + } else if (*fileptr == '}') { + state = BEGIN; + block->filename = filename; + block_list = dlist_append(block_list, block); + block = NULL; + } else { + state = FIELD; + continue; + } + break; + case END: + default: + break; + } + + fileptr++; + } + + if (state != BEGIN) { + struct dlist *l; + struct dlist *n; + ErrPrint("State %d\n", state); + + free(filebuf); + free(block); + + dlist_foreach_safe(block_list, l, n, block) { + free(block); + block_list = dlist_remove(block_list, l); + } + + return DBOX_STATUS_ERROR_FAULT; + } + + + block = dlist_data(dlist_prev(block_list)); + if (block) { + block->filebuf = filebuf; + } else { + ErrPrint("Last block is not exists (There is no parsed block)\n"); + free(filebuf); + } + + ErrPrint("Begin: Set content for object\n"); + dlist_foreach(common->dynamicbox_list, l, handler) { + update_begin(handler, is_gbar); + } + + dlist_foreach_safe(block_list, l, n, block) { + dlist_foreach(common->dynamicbox_list, handle_iterator, handler) { + consuming_parsed_block(handler, is_gbar, block); + } + + block_list = dlist_remove(block_list, l); + delete_block(block); + } + + dlist_foreach(common->dynamicbox_list, l, handler) { + update_end(handler, is_gbar); + } + ErrPrint("End: Set content for object\n"); + + return DBOX_STATUS_ERROR_NONE; +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/dlist.c b/dynamicbox_viewer/src/dlist.c new file mode 100644 index 0000000..9aa8caa --- /dev/null +++ b/dynamicbox_viewer/src/dlist.c @@ -0,0 +1,189 @@ +/* + * 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 +#include +#include + +#include "dlist.h" + +/*! + * \brief + * This dlist is called Modified Doubly Linked List. + * + * Noramlly, The dobule linked list contains address of previous and next element. + * This dlist also contains them, but the tail element only contains prev address. + * + * The head element's prev pointer indicates the last element. + * But the last element's next pointer indicates NIL. + * + * So we can find the last element while crawling this DList + * But we have to remember the address of the head element. + */ + +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; + } + + item->data = data; + + if (!list) { + item->prev = item; + item->next = NULL; + } else { + if (list->prev->next) { + list->prev->next = item; + } + + item->prev = list->prev; + item->next = list; + + list->prev = item; + + } + + return item; +} + +struct dlist *dlist_remove(struct dlist *list, struct dlist *l) +{ + if (!list || !l) { + return NULL; + } + + if (l == list) { + list = l->next; + } else { + l->prev->next = l->next; + } + + if (l->next) { + l->next->prev = l->prev; + } + /*! + * \note + * If the removed entry 'l' has no next element, it is the last element. + * In this case, check the existence of the list first, + * and if the list is not empty, update the 'prev' of the list (which is a head element of the list) + * + * If we didn't care about this, the head element(list) can indicates the invalid element. + */ + else if (list) { + list->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; + + i = 0; + for (n = l; n; n = n->next) { + if (i == nth) { + return n; + } + i++; + } + + return NULL; +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/dynamicbox.c b/dynamicbox_viewer/src/dynamicbox.c new file mode 100644 index 0000000..4526e28 --- /dev/null +++ b/dynamicbox_viewer/src/dynamicbox.c @@ -0,0 +1,4115 @@ +/* + * Copyright 2014 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 +#include +#include /* malloc */ +#include /* strdup */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "debug.h" +#include "fb.h" +#include "dynamicbox.h" +#include "dynamicbox_internal.h" +#include "dlist.h" +#include "util.h" +#include "master_rpc.h" +#include "client.h" +#include "conf.h" + +#define EAPI __attribute__((visibility("default"))) + +#if defined(FLOG) +FILE *__file_log_fp; +#endif + +static int default_launch_handler(dynamicbox_h handler, const char *appid, void *data); + +static struct info { + int init_count; + int prevent_overwrite; + guint job_timer; + struct dlist *job_list; + + struct launch { + int (*handler)(dynamicbox_h handler, const char *appid, void *data); + void *data; + } launch; +} s_info = { + .init_count = 0, + .prevent_overwrite = 0, + .job_timer = 0, + .job_list = NULL, + .launch = { + .handler = default_launch_handler, + .data = NULL, + }, +}; + +static void dbox_pixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data); +static void gbar_pixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data); +static void gbar_xpixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data); +static void dbox_xpixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data); + +static int default_launch_handler(dynamicbox_h handler, const char *appid, void *data) +{ + int ret; + + ret = aul_launch_app(appid, NULL); + if (ret <= 0) { + ErrPrint("Failed to launch an app %s (%d)\n", appid, ret); + } + + /* + app_control_h service; + + DbgPrint("AUTO_LAUNCH [%s]\n", handler->common->dbox.auto_launch); + + ret = app_control_create(&service); + if (ret == APP_CONTROL_ERROR_NONE) { + app_control_set_package(service, handler->common->dbox.auto_launch); + app_control_send_launch_request(service, NULL, NULL); + app_control_destroy(service); + } else { + ErrPrint("Failed to launch an app %s (%d)\n", handler->common->dbox.auto_launch, ret); + } + */ + + return ret > 0 ? DBOX_STATUS_ERROR_NONE : DBOX_STATUS_ERROR_FAULT; +} + +static inline void default_create_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default created event handler: %d\n", ret); +} + +static inline void default_pinup_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default pinup event handler: %d\n", ret); +} + +static inline void default_group_changed_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default group changed event handler: %d\n", ret); +} + +static inline void default_period_changed_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default period changed event handler: %d\n", ret); +} + +static inline void default_gbar_created_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default GBAR created event handler: %d\n", ret); +} + +static inline void default_gbar_destroyed_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default GBAR destroyed event handler: %d\n", ret); +} + +static inline void default_dbox_size_changed_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default DBOX size changed event handler: %d\n", ret); +} + +static inline void default_update_mode_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default update mode set event handler: %d\n", ret); +} + +static inline void default_access_event_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default access event handler: %d\n", ret); +} + +static inline void default_key_event_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default key event handler: %d\n", ret); +} + +static void update_mode_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + ErrPrint("Resize request is failed: %d\n", ret); + goto errout; + } + + return; + +errout: + handler->cbs.update_mode.cb(handler, ret, handler->cbs.update_mode.data); + handler->cbs.update_mode.cb = NULL; + handler->cbs.update_mode.data = NULL; + handler->common->request.update_mode = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void resize_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + goto errout; + } + + /*! + * \note + * In case of resize request, + * The dynamicbox handler will not have resized value right after this callback, + * It can only get the new size when it makes updates. + * + * So the user can only get the resized value(result) from the first update event + * after this request. + */ + if (ret < 0) { + ErrPrint("Resize request is failed: %d\n", ret); + goto errout; + } + + return; + +errout: + handler->cbs.size_changed.cb(handler, ret, handler->cbs.size_changed.data); + handler->cbs.size_changed.cb = NULL; + handler->cbs.size_changed.data = NULL; + handler->common->request.size_changed = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void text_signal_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + void *cbdata; + struct cb_info *info = data; + dynamicbox_ret_cb cb; + + cbdata = info->data; + cb = info->cb; + dbox_destroy_cb_info(info); + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handler, ret, cbdata); + } + return; +} + +static void set_group_ret_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + goto errout; + } + + return; + +errout: + handler->cbs.group_changed.cb(handler, ret, handler->cbs.group_changed.data); + handler->cbs.group_changed.cb = NULL; + handler->cbs.group_changed.data = NULL; + handler->common->request.group_changed = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void period_ret_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + goto errout; + } + + return; + +errout: + handler->cbs.period_changed.cb(handler, ret, handler->cbs.period_changed.data); + handler->cbs.period_changed.cb = NULL; + handler->cbs.period_changed.data = NULL; + handler->common->request.period_changed = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void gbar_create_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + goto errout; + } + + if (ret < 0) { + ErrPrint("Failed to create a GBAR[%d]\n", ret); + goto errout; + } + + return; + +errout: + handler->cbs.gbar_created.cb(handler, ret, handler->cbs.gbar_created.data); + handler->cbs.gbar_created.cb = NULL; + handler->cbs.gbar_created.data = NULL; + handler->common->request.gbar_created = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void activated_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + struct cb_info *info = data; + void *cbdata; + dynamicbox_ret_cb cb; + const char *pkgname = ""; + + cbdata = info->data; + cb = info->cb; + dbox_destroy_cb_info(info); + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "is", &ret, &pkgname) != 2) { + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handler, ret, cbdata); + } +} + +static void gbar_destroy_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + dynamicbox_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cbdata = info->data; + cb = info->cb; + dbox_destroy_cb_info(info); + + if (!result) { + ErrPrint("Result is NIL (may connection lost)\n"); + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid parameter\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.gbar_destroyed.cb = cb; + handler->cbs.gbar_destroyed.data = cbdata; + } else { + handler->common->is_gbar_created = 0; + handler->common->request.gbar_destroyed = 0; + + if (cb) { + cb(handler, ret, cbdata); + } + } +} + +static void delete_cluster_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + struct cb_info *info = data; + int ret; + dynamicbox_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handler, ret, cbdata); + } +} + +static void delete_category_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + struct cb_info *info = data; + int ret; + dynamicbox_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (cb) { + cb(handler, ret, cbdata); + } +} + +static int dbox_acquire_dbox_pixmap(dynamicbox_h handler, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + const char *id; + unsigned int cmd = CMD_DBOX_ACQUIRE_PIXMAP; + int ret; + + id = fb_id(handler->common->dbox.fb); + if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + packet = packet_create((const char *)&cmd, "ss", handler->common->pkgname, handler->common->id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, dbox_pixmap_acquired_cb, cbinfo); + if (ret < 0) { + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +static void dbox_pixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int pixmap; + int ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + dynamicbox_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + pixmap = 0; /* PIXMAP 0 means error */ + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + } + + if (ret == (int)DBOX_STATUS_ERROR_BUSY) { + ret = dbox_acquire_dbox_pixmap(handler, cb, cbdata); + DbgPrint("Busy, Try again: %d\n", ret); + /* Try again */ + } else if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + if (cb) { + cb(handler, pixmap, cbdata); + } + + if (handler->common->state != DBOX_STATE_DELETE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } else { + if (cb) { + cb(handler, pixmap, cbdata); + } + } +} + +static void dbox_xpixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int pixmap; + int ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + dynamicbox_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + pixmap = 0; + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + } + + if (cb) { + cb(handler, pixmap, cbdata); + } + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static int dbox_acquire_gbar_extra_pixmap(dynamicbox_h handler, int idx, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_GBAR_ACQUIRE_XPIXMAP; + int ret; + + packet = packet_create((const char *)&cmd, "ssi", handler->common->pkgname, handler->common->id, idx); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, gbar_xpixmap_acquired_cb, cbinfo); + if (ret < 0) { + /*! + * \note + * Packet will be destroyed by master_rpc_async_request + */ + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +static int dbox_acquire_dbox_extra_pixmap(dynamicbox_h handler, int idx, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_DBOX_ACQUIRE_XPIXMAP; + int ret; + + packet = packet_create((const char *)&cmd, "ssi", handler->common->pkgname, handler->common->id, idx); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, dbox_xpixmap_acquired_cb, cbinfo); + if (ret < 0) { + /*! + * \note + * Packet will be destroyed by master_rpc_async_request + */ + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +static int dbox_acquire_gbar_pixmap(dynamicbox_h handler, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_GBAR_ACQUIRE_PIXMAP; + const char *id; + int ret; + + id = fb_id(handler->common->gbar.fb); + if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + packet = packet_create((const char *)&cmd, "ss", handler->common->pkgname, handler->common->id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, gbar_pixmap_acquired_cb, cbinfo); + if (ret < 0) { + /*! + * \note + * Packet will be destroyed by master_rpc_async_request + */ + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +static void gbar_xpixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int pixmap; + int ret; + dynamicbox_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + pixmap = 0; /* PIXMAP 0 means error */ + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (cb) { + DbgPrint("ret: %x, pixmap: %d\n", ret, pixmap); + cb(handler, pixmap, cbdata); + } + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void gbar_pixmap_acquired_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int pixmap; + int ret; + dynamicbox_ret_cb cb; + void *cbdata; + struct cb_info *info = data; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + pixmap = 0; /* PIXMAP 0 means error */ + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { + pixmap = 0; + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (ret == (int)DBOX_STATUS_ERROR_BUSY) { + ret = dbox_acquire_gbar_pixmap(handler, cb, cbdata); + DbgPrint("Busy, Try again: %d\n", ret); + /* Try again */ + } else if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + if (cb) { + cb(handler, pixmap, cbdata); + } + + if (handler->common->state != DBOX_STATE_DELETE) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } else { + if (cb) { + DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap); + cb(handler, pixmap, cbdata); + } + } +} + +static void pinup_done_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + goto errout; + } else if (packet_get(result, "i", &ret) != 1) { + goto errout; + } + + if (ret < 0) { + goto errout; + } + + return; + +errout: + handler->cbs.pinup.cb(handler, ret, handler->cbs.pinup.data); + handler->cbs.pinup.cb = NULL; + handler->cbs.pinup.data = NULL; + handler->common->request.pinup = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void key_ret_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + return; + } + + if (packet_get(result, "i", &ret) != 1) { + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + return; + } + + if (ret != DBOX_STATUS_ERROR_NONE) { + goto errout; + } + + return; +errout: + handler->cbs.key_event.cb(handler, ret, handler->cbs.key_event.data); + handler->cbs.key_event.cb = NULL; + handler->cbs.key_event.data = NULL; + handler->common->request.key_event = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static void access_ret_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + return; + } + + if (packet_get(result, "i", &ret) != 1) { + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + return; + } + + if (ret != DBOX_STATUS_ERROR_NONE) { + goto errout; + } + + return; + +errout: + handler->cbs.access_event.cb(handler, ret, handler->cbs.access_event.data); + handler->cbs.access_event.cb = NULL; + handler->cbs.access_event.data = NULL; + handler->common->request.access_event = 0; + + if (handler->common->state != DBOX_STATE_DELETE) { + if (ret == (int)DBOX_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + } +} + +static int send_access_event(dynamicbox_h handler, const char *event, int x, int y, int type) +{ + struct packet *packet; + double timestamp; + + timestamp = util_timestamp(); + + packet = packet_create(event, "ssdiii", handler->common->pkgname, handler->common->id, timestamp, x, y, type); + if (!packet) { + ErrPrint("Failed to build packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_async_request(handler, packet, 0, access_ret_cb, NULL); +} + +static int send_key_event(dynamicbox_h handler, const char *event, unsigned int keycode) +{ + struct packet *packet; + double timestamp; + + timestamp = util_timestamp(); + packet = packet_create(event, "ssdi", handler->common->pkgname, handler->common->id, timestamp, keycode); + if (!packet) { + ErrPrint("Failed to build packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_async_request(handler, packet, 0, key_ret_cb, NULL); +} + +static int send_mouse_event(dynamicbox_h handler, const char *event, int x, int y) +{ + struct packet *packet; + double timestamp; + + timestamp = util_timestamp(); + packet = packet_create_noack(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y); + if (!packet) { + ErrPrint("Failed to build param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(handler, packet); +} + +static int initialize_dynamicbox(void *disp, int use_thread) +{ + int ret; +#if defined(FLOG) + char filename[BUFSIZ]; + snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid()); + __file_log_fp = fopen(filename, "w+t"); + if (!__file_log_fp) { + __file_log_fp = fdopen(1, "w+t"); + } +#endif + ret = dynamicbox_service_init(); + if (ret != DBOX_STATUS_ERROR_NONE) { + return ret; + } + + ret = fb_init(disp); + if (ret != DBOX_STATUS_ERROR_NONE) { + dynamicbox_service_fini(); + return ret; + } + + ret = client_init(use_thread); + if (ret != DBOX_STATUS_ERROR_NONE) { + fb_fini(); + dynamicbox_service_fini(); + return ret; + } + + s_info.init_count++; + return ret; +} + +static inline char *dbox_pkgname(const char *pkgname) +{ + char *dbox; + + dbox = dynamicbox_service_dbox_id(pkgname); + if (!dbox) { + dbox = strdup(pkgname); + } + + return dbox; +} + +static gboolean job_execute_cb(void *data) +{ + struct job_item *item; + struct dlist *l; + + l = dlist_nth(s_info.job_list, 0); + if (!l) { + s_info.job_timer = 0; + return FALSE; + } + + item = dlist_data(l); + s_info.job_list = dlist_remove(s_info.job_list, l); + + if (item) { + item->cb(item->handle, item->ret, item->data); + dbox_unref(item->handle, 1); + free(item); + } + + return TRUE; +} + +static int job_add(dynamicbox_h handle, dynamicbox_ret_cb job_cb, int ret, void *data) +{ + struct job_item *item; + + if (!job_cb) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + item = malloc(sizeof(*item)); + if (!item) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + item->handle = dbox_ref(handle); + item->cb = job_cb; + item->data = data; + item->ret = ret; + + s_info.job_list = dlist_append(s_info.job_list, item); + + if (!s_info.job_timer) { + s_info.job_timer = g_timeout_add(1, job_execute_cb, NULL); + if (!s_info.job_timer) { + ErrPrint("Failed to create a job timer\n"); + } + } + + return DBOX_STATUS_ERROR_NONE; +} + +static void new_ret_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + int ret; + struct cb_info *info = data; + dynamicbox_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (ret >= 0) { + handler->cbs.created.cb = cb; + handler->cbs.created.data = cbdata; + + /*! + * \note + * Don't go anymore ;) + */ + return; + } else if (cb) { + /*! + * \note + * It means the current instance is not created, + * so user has to know about this. + * notice it to user using "deleted" event. + */ + cb(handler, ret, cbdata); + } + + dbox_unref(handler, 1); +} + +static int create_real_instance(dynamicbox_h handler, dynamicbox_ret_cb cb, void *data) +{ + struct cb_info *cbinfo; + struct packet *packet; + struct dynamicbox_common *common; + unsigned int cmd = CMD_NEW; + int ret; + + common = handler->common; + + packet = packet_create((const char *)&cmd, "dssssdii", + common->timestamp, common->pkgname, common->content, + common->cluster, common->category, + common->dbox.period, common->dbox.width, common->dbox.height); + if (!packet) { + ErrPrint("Failed to create a new packet\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + packet_destroy(packet); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + /*! + * \note + * master_rpc_async_request will destroy the packet (decrease the refcnt) + * So be aware the packet object after return from master_rpc_async_request. + */ + ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo); + if (ret < 0) { + ErrPrint("Failed to send a new packet\n"); + dbox_destroy_cb_info(cbinfo); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT); + return DBOX_STATUS_ERROR_FAULT; + } + handler->common->request.created = 1; + return DBOX_STATUS_ERROR_NONE; +} + +static void create_cb(dynamicbox_h handle, int ret, void *data) +{ + struct cb_info *cbinfo = data; + + if (cbinfo->cb) { + cbinfo->cb(handle, ret, cbinfo->data); + } + + dbox_destroy_cb_info(cbinfo); + + /*! + * \note + * Forcely generate "updated" event + */ + dbox_invoke_event_handler(handle, DBOX_EVENT_DBOX_UPDATED); +} + +static int create_fake_instance(dynamicbox_h handler, dynamicbox_ret_cb cb, void *data) +{ + struct cb_info *cbinfo; + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + if (job_add(handler, create_cb, DBOX_STATUS_ERROR_NONE, cbinfo) != DBOX_STATUS_ERROR_NONE) { + dbox_destroy_cb_info(cbinfo); + } + + return DBOX_STATUS_ERROR_NONE; +} + +static void refresh_for_paused_updating_cb(dynamicbox_h handle, int ret, void *data) +{ + if (handle->paused_updating == 0) { + DbgPrint("Paused updates are cleared\n"); + return; + } + + DbgPrint("Pending updates are found\n"); + dbox_invoke_event_handler(handle, DBOX_EVENT_DBOX_UPDATED); +} + +static int dbox_set_visibility(dynamicbox_h handler, dynamicbox_visible_state_e state) +{ + struct packet *packet; + int need_to_add_job = 0; + unsigned int cmd = CMD_CHANGE_VISIBILITY; + int ret; + + if (handler->common->visible != DBOX_SHOW && state == DBOX_SHOW) { + need_to_add_job = !!handler->paused_updating; + } else if (handler->common->visible == DBOX_SHOW && state != DBOX_SHOW) { + if (!!dbox_find_dbox_in_show(handler->common)) { + return DBOX_STATUS_ERROR_NONE; + } + } else if (handler->common->visible == DBOX_SHOW && state == DBOX_SHOW && handler->paused_updating) { + if (job_add(handler, refresh_for_paused_updating_cb, DBOX_STATUS_ERROR_NONE, NULL) < 0) { + ErrPrint("Unable to add a new job for refreshing box\n"); + } + + return DBOX_STATUS_ERROR_NONE; + } else { + /*! + * \brief + * No need to send this to the master + */ + return DBOX_STATUS_ERROR_NONE; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", handler->common->pkgname, handler->common->id, (int)state); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_request_only(handler, packet); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state); + handler->common->visible = state; + + if (need_to_add_job) { + if (job_add(handler, refresh_for_paused_updating_cb, DBOX_STATUS_ERROR_NONE, NULL) < 0) { + ErrPrint("Unable to add a new job for refreshing box\n"); + } + } + } + + return ret; +} + +static void dbox_update_visibility(struct dynamicbox_common *old_common) +{ + dynamicbox_h item; + + item = dbox_find_dbox_in_show(old_common); + if (!item) { + item = dbox_get_dbox_nth(old_common, 0); + if (item) { + dbox_set_visibility(item, DBOX_HIDE_WITH_PAUSE); + } else { + ErrPrint("Unable to get the valid handle from common handler\n"); + } + } else { + dbox_set_visibility(item, DBOX_SHOW); + } +} + +/*! + * \note + * The second parameter should be the "return value", + * But in this case, we will use it for "type of deleting instance". + */ +static void job_del_cb(dynamicbox_h handle, int type, void *data) +{ + struct cb_info *cbinfo = data; + dynamicbox_ret_cb cb; + + if (handle->visible == DBOX_SHOW) { + dbox_update_visibility(handle->common); + } + + cb = cbinfo->cb; + data = cbinfo->data; + dbox_destroy_cb_info(cbinfo); + + if (handle->common->state != DBOX_STATE_CREATE) { + DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt); + if (cb) { + cb(handle, DBOX_STATUS_ERROR_NONE, data); + } + + return; + } + + if (handle->common->refcnt == 1) { + handle->common->delete_type = type; + handle->common->state = DBOX_STATE_DELETE; + + if (!handle->common->id) { + /*! + * \note + * The id is not determined yet. + * It means a user didn't receive created event yet. + * Then just stop to delete procedure from here. + * Because the "created" event handle will release this. + * By the way, if the user adds any callback for getting return status of this, + * call it at here. + */ + if (cb) { + cb(handle, DBOX_STATUS_ERROR_NONE, data); + } + } + + DbgPrint("Send delete request\n"); + dbox_send_delete(handle, type, cb, data); + } else { + if (cb) { + cb(handle, DBOX_STATUS_ERROR_NONE, data); + } + + DbgPrint("Before unref: %d\n", handle->common->refcnt); + dbox_unref(handle, 1); + } +} + +static void resize_job_cb(dynamicbox_h handler, int ret, void *data) +{ + struct cb_info *info = data; + + if (info->cb) { + info->cb(handler, ret, info->data); + } + + free(info); + + /*! + * \note + * Forcely update the box + */ + dbox_invoke_event_handler(handler, DBOX_EVENT_DBOX_UPDATED); +} + +static void turn_off_gbar_destroyed_flag_cb(dynamicbox_h handler, int ret, void *data) +{ + if (handler->common->request.gbar_destroyed) { + dynamicbox_ret_cb cb; + void *data; + + DbgPrint("gbar_destroyed request is canceled\n"); + handler->common->request.gbar_destroyed = 0; + cb = handler->cbs.gbar_destroyed.cb; + data = handler->cbs.gbar_destroyed.data; + handler->cbs.gbar_destroyed.cb = NULL; + handler->cbs.gbar_destroyed.data = NULL; + + if (cb) { + cb(handler, ret, data); + } + } +} + +static void turn_off_gbar_created_flag_cb(dynamicbox_h handler, int ret, void *data) +{ + if (handler->common->request.gbar_created) { + dynamicbox_ret_cb cb; + void *data; + + DbgPrint("gbar_created request is canceled\n"); + handler->common->request.gbar_created = 0; + cb = handler->cbs.gbar_created.cb; + data = handler->cbs.gbar_created.data; + handler->cbs.gbar_created.cb = NULL; + handler->cbs.gbar_created.data = NULL; + + if (cb) { + cb(handler, ret, data); + } + } +} + +EAPI int dynamicbox_init(void *disp, int prevent_overwrite, double event_filter, int use_thread) +{ + if (s_info.init_count > 0) { + s_info.init_count++; + return DBOX_STATUS_ERROR_NONE; + } + + /*! + * \note + * Some application doesn't want to use the environment value. + * So set them using arguments. + */ + s_info.prevent_overwrite = prevent_overwrite; + conf_set_event_filter(event_filter); + + return initialize_dynamicbox(disp, use_thread); +} + +EAPI int dynamicbox_fini(void) +{ + if (s_info.init_count <= 0) { + ErrPrint("Doesn't initialized\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + s_info.init_count--; + if (s_info.init_count > 0) { + ErrPrint("init count : %d\n", s_info.init_count); + return DBOX_STATUS_ERROR_NONE; + } + + client_fini(); + fb_fini(); + dynamicbox_service_fini(); + return DBOX_STATUS_ERROR_NONE; +} + +EAPI dynamicbox_h dynamicbox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, dynamicbox_size_type_e type, dynamicbox_ret_cb cb, void *data) +{ + char *dboxid; + dynamicbox_h handler; + int w = 0; + int h = 0; + + if (!pkgname || !cluster || !category) { + ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n", + pkgname, cluster, category); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + dboxid = dbox_pkgname(pkgname); + if (!dboxid) { + ErrPrint("Invalid package: %s\n", pkgname); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (dynamicbox_service_is_enabled(dboxid) == 0) { + DbgPrint("Livebox [%s](%s) is disabled package\n", dboxid, pkgname); + free(dboxid); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_DISABLED); + return NULL; + } + + if (type != DBOX_SIZE_TYPE_UNKNOWN) { + (void)dynamicbox_service_get_size(type, &w, &h); + } + + handler = calloc(1, sizeof(*handler)); + if (!handler) { + ErrPrint("Error: %s\n", strerror(errno)); + free(dboxid); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return NULL; + } + + if (!cb) { + cb = default_create_cb; + } + + handler->common = dbox_find_sharable_common_handle(dboxid, content, w, h, cluster, category); + if (!handler->common) { + handler->common = dbox_create_common_handle(handler, dboxid, cluster, category); + free(dboxid); + if (!handler->common) { + ErrPrint("Failed to find common handle\n"); + free(handler); + return NULL; + } + + if (!content || !strlen(content)) { + char *pc; + /** + * @note + * I know the content should not be modified. use it temporarly without "const" + */ + pc = dynamicbox_service_content(handler->common->pkgname); + dbox_set_content(handler->common, pc); + free(pc); + } else { + dbox_set_content(handler->common, content); + } + + dbox_set_period(handler->common, period); + dbox_set_size(handler->common, w, h); + dbox_common_ref(handler->common, handler); + + if (create_real_instance(handler, cb, data) < 0) { + if (dbox_common_unref(handler->common, handler) == 0) { + /*! + * Delete common + */ + dbox_destroy_common_handle(handler->common); + handler->common = NULL; + } + free(handler); + return NULL; + } + } else { + free(dboxid); + + dbox_common_ref(handler->common, handler); + + if (handler->common->request.created) { + /*! + * If a box is in creating, wait its result too + */ + handler->cbs.created.cb = cb; + handler->cbs.created.data = data; + } else { + /*! + * or fire the fake created_event + */ + if (create_fake_instance(handler, cb, data) < 0) { + if (dbox_common_unref(handler->common, handler) == 0) { + /*! + * Delete common + */ + dbox_destroy_common_handle(handler->common); + } + free(handler); + return NULL; + } + } + } + + handler->visible = DBOX_SHOW; + handler->state = DBOX_STATE_CREATE; + handler = dbox_ref(handler); + + if (handler->common->visible != DBOX_SHOW) { + dbox_set_visibility(handler, DBOX_SHOW); + } + + return handler; +} + +EAPI double dynamicbox_period(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return -1.0f; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return -1.0f; + } + + if (!handler->common->id) { + ErrPrint("Hnalder is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return -1.0f; + } + + return handler->common->dbox.period; +} + +EAPI int dynamicbox_set_period(dynamicbox_h handler, double period, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_SET_PERIOD; + int ret; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->request.period_changed) { + ErrPrint("Previous request for changing period is not finished\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + if (!handler->common->is_user) { + ErrPrint("CA Livebox is not able to change the period\n"); + return DBOX_STATUS_ERROR_PERMISSION_DENIED; + } + + if (handler->common->dbox.period == period) { + DbgPrint("No changes\n"); + return DBOX_STATUS_ERROR_ALREADY; + } + + packet = packet_create((const char *)&cmd, "ssd", handler->common->pkgname, handler->common->id, period); + if (!packet) { + ErrPrint("Failed to build a packet %s\n", handler->common->pkgname); + return DBOX_STATUS_ERROR_FAULT; + } + + if (!cb) { + cb = default_period_changed_cb; + } + + ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.period_changed.cb = cb; + handler->cbs.period_changed.data = data; + handler->common->request.period_changed = 1; + } + + return ret; +} + +EAPI int dynamicbox_del(dynamicbox_h handler, dynamicbox_delete_type_e type, dynamicbox_ret_cb cb, void *data) +{ + struct cb_info *cbinfo; + + if (!handler) { + ErrPrint("Handler is NIL\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is already deleted\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + handler->state = DBOX_STATE_DELETE; + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + if (job_add(handler, job_del_cb, type, cbinfo) != DBOX_STATUS_ERROR_NONE) { + ErrPrint("Failed to add a new job\n"); + dbox_destroy_cb_info(cbinfo); + return DBOX_STATUS_ERROR_FAULT; + } + + return DBOX_STATUS_ERROR_NONE; +} + +EAPI int dynamicbox_add_fault_handler(dynamicbox_fault_handler_cb dbox_cb, void *data) +{ + if (!dbox_cb) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return dbox_add_fault_handler(dbox_cb, data); +} + +EAPI void *dynamicbox_remove_fault_handler(dynamicbox_fault_handler_cb dbox_cb) +{ + if (!dbox_cb) { + return NULL; + } + + return dbox_remove_fault_handler(dbox_cb); +} + +EAPI int dynamicbox_add_event_handler(dynamicbox_event_handler_cb dbox_cb, void *data) +{ + if (!dbox_cb) { + ErrPrint("Invalid argument dbox_cb is nil\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return dbox_add_event_handler(dbox_cb, data); +} + +EAPI void *dynamicbox_remove_event_handler(dynamicbox_event_handler_cb dbox_cb) +{ + if (!dbox_cb) { + return NULL; + } + + return dbox_remove_event_handler(dbox_cb); +} + +EAPI int dynamicbox_set_update_mode(dynamicbox_h handler, int active_update, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_UPDATE_MODE; + int ret; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is Invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->request.update_mode) { + ErrPrint("Previous update_mode cb is not finished yet\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + if (handler->common->is_active_update == active_update) { + return DBOX_STATUS_ERROR_ALREADY; + } + + if (!handler->common->is_user) { + return DBOX_STATUS_ERROR_PERMISSION_DENIED; + } + + packet = packet_create((const char *)&cmd, "ssi", handler->common->pkgname, handler->common->id, active_update); + if (!packet) { + return DBOX_STATUS_ERROR_FAULT; + } + + if (!cb) { + cb = default_update_mode_cb; + } + + ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.update_mode.cb = cb; + handler->cbs.update_mode.data = data; + handler->common->request.update_mode = 1; + } + + return ret; +} + +EAPI int dynamicbox_is_active_update(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is Invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return handler->common->is_active_update; +} + +EAPI int dynamicbox_resize(dynamicbox_h handler, dynamicbox_size_type_e type, dynamicbox_ret_cb cb, void *data) +{ + struct dynamicbox_common *common; + int w; + int h; + int ret; + + /*! + * \TODO + * If this handle is host instance or link instance, + * Create a new instance or find another linkable instance. + */ + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + /*! + * \note + * resize operation should be separated by each handler. + * If a handler is resizing, the other handler can request resize too. + * So we should not use the common->request.size_changed flag. + */ + if (handler->cbs.size_changed.cb) { + ErrPrint("Previous resize request is not finished yet\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + if (dynamicbox_service_get_size(type, &w, &h) != 0) { + ErrPrint("Invalid size type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->dbox.width == w && handler->common->dbox.height == h) { + DbgPrint("No changes\n"); + return DBOX_STATUS_ERROR_ALREADY; + } + + if (!handler->common->is_user) { + ErrPrint("CA Livebox is not able to be resized\n"); + return DBOX_STATUS_ERROR_PERMISSION_DENIED; + } + + if (handler->common->refcnt <= 1) { + struct packet *packet; + unsigned int cmd = CMD_RESIZE; + + /* Only 1 instance */ + packet = packet_create((const char *)&cmd, "ssii", handler->common->pkgname, handler->common->id, w, h); + if (!packet) { + ErrPrint("Failed to build param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + if (!cb) { + cb = default_dbox_size_changed_cb; + } + + ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.size_changed.cb = cb; + handler->cbs.size_changed.data = data; + handler->common->request.size_changed = 1; + } + } else { + common = dbox_find_sharable_common_handle(handler->common->pkgname, handler->common->content, w, h, handler->common->cluster, handler->common->category); + if (!common) { + struct dynamicbox_common *old_common; + /*! + * \note + * If the common handler is in resizing, + * if user tries to resize a hander, then simply create new one even if the requested size is same with this. + + if (handler->common->request.size_changed) { + } + + */ + + old_common = handler->common; + + common = dbox_create_common_handle(handler, old_common->pkgname, old_common->cluster, old_common->category); + if (!common) { + ErrPrint("Failed to create common handle\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + dbox_set_size(common, w, h); + dbox_set_content(common, old_common->content); + dbox_set_period(common, old_common->dbox.period); + + /*! + * \note + * Disconnecting from old one. + */ + if (dbox_common_unref(old_common, handler) == 0) { + /*! + * \note + * Impossible + */ + ErrPrint("Common has no associated handler\n"); + } + + dbox_common_ref(common, handler); + + /*! + * Connect to a new one + */ + handler->common = common; + + /*! + * \TODO + * Need to care, if it fails to create a common handle, + * the resize operation will be failed. + * in that case, we should reuse the old common handle + */ + ret = create_real_instance(handler, cb, data); + if (ret < 0) { + dbox_common_unref(common, handler); + dbox_destroy_common_handle(common); + + dbox_common_ref(old_common, handler); + handler->common = old_common; + } else { + /*! + * In this case, we should update visibility of old_common's dynamicboxes + */ + if (handler->visible == DBOX_SHOW) { + dbox_update_visibility(old_common); + } + } + } else { + struct cb_info *cbinfo; + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Failed to create a cbinfo\n"); + ret = DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } else { + ret = job_add(handler, resize_job_cb, DBOX_STATUS_ERROR_NONE, cbinfo); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + struct dynamicbox_common *old_common; + + old_common = handler->common; + + if (dbox_common_unref(handler->common, handler) == 0) { + ErrPrint("Old common has no associated handler\n"); + } + + dbox_common_ref(common, handler); + handler->common = common; + + if (handler->visible == DBOX_SHOW) { + dbox_update_visibility(old_common); /* To update visibility: Show --> Paused */ + dbox_update_visibility(common); /* To update visibility: Paused --> Show */ + } + } else { + dbox_destroy_cb_info(cbinfo); + } + } + } + } + + return ret; +} + +EAPI int dynamicbox_click(dynamicbox_h handler, double x, double y) +{ + struct packet *packet; + double timestamp; + unsigned int cmd = CMD_CLICKED; + int ret; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->dbox.auto_launch) { + if (s_info.launch.handler) { + ret = s_info.launch.handler(handler, handler->common->dbox.auto_launch, s_info.launch.data); + if (ret < 0) { + ErrPrint("launch handler app %s (%d)\n", handler->common->dbox.auto_launch, ret); + } + } + } + + timestamp = util_timestamp(); + DbgPrint("CLICKED: %lf\n", timestamp); + + packet = packet_create_noack((const char *)&cmd, "sssddd", handler->common->pkgname, handler->common->id, "clicked", timestamp, x, y); + if (!packet) { + ErrPrint("Failed to build param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_request_only(handler, packet); + return ret; +} + +EAPI int dynamicbox_has_glance_bar(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return !!handler->common->gbar.fb; +} + +EAPI int dynamicbox_glance_bar_is_created(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->gbar.fb || !handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return handler->common->is_gbar_created; +} + +EAPI int dynamicbox_create_glance_bar(dynamicbox_h handler, double x, double y, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_CREATE_GBAR; + int ret; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->gbar.fb || !handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + /*! + * \note + * Only one handler can have a GBAR + */ + if (handler->common->is_gbar_created) { + DbgPrint("GBAR is already created\n"); + return DBOX_STATUS_ERROR_NONE; + } + + if (handler->common->request.gbar_created) { + ErrPrint("Previous request is not completed yet\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + /*! + * \note + * Turn off the gbar_destroyed request flag + */ + if (handler->common->request.gbar_destroyed) { + if (job_add(handler, turn_off_gbar_destroyed_flag_cb, DBOX_STATUS_ERROR_CANCEL, NULL) < 0) { + ErrPrint("Failed to add gbar_destroyed job\n"); + } + } + + packet = packet_create((const char *)&cmd, "ssdd", handler->common->pkgname, handler->common->id, x, y); + if (!packet) { + ErrPrint("Failed to build param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + if (!cb) { + cb = default_gbar_created_cb; + } + + DbgPrint("PERF_DBOX\n"); + ret = master_rpc_async_request(handler, packet, 0, gbar_create_cb, NULL); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.gbar_created.cb = cb; + handler->cbs.gbar_created.data = data; + handler->common->request.gbar_created = 1; + } + + return ret; +} + +EAPI int dynamicbox_move_glance_bar(dynamicbox_h handler, double x, double y) +{ + struct packet *packet; + unsigned int cmd = CMD_GBAR_MOVE; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->gbar.fb || !handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "ssdd", handler->common->pkgname, handler->common->id, x, y); + if (!packet) { + ErrPrint("Failed to build param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(handler, packet); +} + +EAPI int dynamicbox_activate(const char *pkgname, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_ACTIVATE_PACKAGE; + int ret; + + if (!pkgname) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + packet = packet_create((const char *)&cmd, "s", pkgname); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + ErrPrint("Unable to create cbinfo\n"); + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo); + if (ret < 0) { + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI int dynamicbox_destroy_glance_bar(dynamicbox_h handler, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_DESTROY_GBAR; + int ret; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->gbar.fb || !handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + /*! + * \FIXME + * Replace the callback check code. + * Use the flag instead of callback. + * the flag should be in the ADT "common" + */ + if (!handler->common->is_gbar_created && !handler->common->request.gbar_created) { + ErrPrint("GBAR is not created\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->request.gbar_destroyed) { + ErrPrint("GBAR destroy request is already sent\n"); + return DBOX_STATUS_ERROR_ALREADY; + } + + /*! + * \note + * Disable the gbar_created request flag + */ + if (handler->common->request.gbar_created) { + if (job_add(handler, turn_off_gbar_created_flag_cb, DBOX_STATUS_ERROR_CANCEL, NULL) < 0) { + ErrPrint("Failed to add a new job\n"); + } + } + + DbgPrint("[%s]\n", handler->common->pkgname); + + packet = packet_create((const char *)&cmd, "ss", handler->common->pkgname, handler->common->id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + if (!cb) { + cb = default_gbar_destroyed_cb; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, gbar_destroy_cb, cbinfo); + if (ret < 0) { + dbox_destroy_cb_info(cbinfo); + } else { + handler->common->request.gbar_destroyed = 1; + } + + return ret; +} + +EAPI int dynamicbox_feed_access_event(dynamicbox_h handler, dynamicbox_access_event_type_e type, dynamicbox_access_event_info_t info, dynamicbox_ret_cb cb, void *data) +{ + int w = 1; + int h = 1; + unsigned int cmd; + int ret = 0; /* re-used for sending event type */ + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->request.access_event) { + ErrPrint("Previous access event is not yet done\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + if (type & DBOX_ACCESS_EVENT_GBAR_MASK) { + if (!handler->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + w = handler->common->gbar.width; + h = handler->common->gbar.height; + + switch (type & ~(DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_DBOX_MASK)) { + case DBOX_ACCESS_EVENT_HIGHLIGHT: + cmd = CMD_GBAR_ACCESS_HL; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_ACTIVATE: + cmd = CMD_GBAR_ACCESS_ACTIVATE; + break; + case DBOX_ACCESS_EVENT_ACTION: + cmd = CMD_GBAR_ACCESS_ACTION; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_SCROLL: + cmd = CMD_GBAR_ACCESS_SCROLL; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_VALUE_CHANGE: + cmd = CMD_GBAR_ACCESS_VALUE_CHANGE; + break; + case DBOX_ACCESS_EVENT_MOUSE: + cmd = CMD_GBAR_ACCESS_MOUSE; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_BACK: + cmd = CMD_GBAR_ACCESS_BACK; + break; + case DBOX_ACCESS_EVENT_OVER: + cmd = CMD_GBAR_ACCESS_OVER; + break; + case DBOX_ACCESS_EVENT_READ: + cmd = CMD_GBAR_ACCESS_READ; + break; + case DBOX_ACCESS_EVENT_ENABLE: + cmd = CMD_GBAR_ACCESS_ENABLE; + ret = info->type; + break; + default: + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + } else if (type & DBOX_ACCESS_EVENT_DBOX_MASK) { + w = handler->common->dbox.width; + h = handler->common->dbox.height; + switch (type & ~(DBOX_ACCESS_EVENT_GBAR_MASK | DBOX_ACCESS_EVENT_DBOX_MASK)) { + case DBOX_ACCESS_EVENT_HIGHLIGHT: + cmd = CMD_DBOX_ACCESS_HL; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_ACTIVATE: + cmd = CMD_DBOX_ACCESS_ACTIVATE; + break; + case DBOX_ACCESS_EVENT_ACTION: + cmd = CMD_DBOX_ACCESS_ACTION; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_SCROLL: + cmd = CMD_DBOX_ACCESS_SCROLL; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_VALUE_CHANGE: + cmd = CMD_DBOX_ACCESS_VALUE_CHANGE; + break; + case DBOX_ACCESS_EVENT_MOUSE: + cmd = CMD_DBOX_ACCESS_MOUSE; + ret = (int)info->type; + break; + case DBOX_ACCESS_EVENT_BACK: + cmd = CMD_DBOX_ACCESS_BACK; + break; + case DBOX_ACCESS_EVENT_OVER: + cmd = CMD_DBOX_ACCESS_OVER; + break; + case DBOX_ACCESS_EVENT_READ: + cmd = CMD_DBOX_ACCESS_READ; + break; + case DBOX_ACCESS_EVENT_ENABLE: + cmd = CMD_DBOX_ACCESS_ENABLE; + ret = info->type; + break; + default: + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + } else { + ErrPrint("Invalid event type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!cb) { + cb = default_access_event_cb; + } + + ret = send_access_event(handler, (const char *)&cmd, info->x * w, info->y * h, ret); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.access_event.cb = cb; + handler->cbs.access_event.data = data; + handler->common->request.access_event = 1; + } + + return ret; +} + +EAPI int dynamicbox_feed_mouse_event(dynamicbox_h handler, dynamicbox_mouse_event_type_e type, dynamicbox_mouse_event_info_t info) +{ + int w = 1; + int h = 1; + unsigned int cmd; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!(type & DBOX_MOUSE_EVENT_MASK)) { + ErrPrint("Invalid content event is used\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (type & DBOX_MOUSE_EVENT_GBAR_MASK) { + int flag = 1; + + if (!handler->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->gbar.fb) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (type & DBOX_MOUSE_EVENT_MOVE) { + if (fabs(info->x - handler->common->gbar.x) < conf_event_filter() && fabs(info->y - handler->common->gbar.y) < conf_event_filter()) { + return DBOX_STATUS_ERROR_BUSY; + } + } else if (type & DBOX_MOUSE_EVENT_SET) { + flag = 0; + } + + if (flag) { + handler->common->gbar.x = info->x; + handler->common->gbar.y = info->y; + w = handler->common->gbar.width; + h = handler->common->gbar.height; + } + + switch ((type & ~(DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_DBOX_MASK))) { + case DBOX_MOUSE_EVENT_ENTER | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_ENTER; + break; + case DBOX_MOUSE_EVENT_LEAVE | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_LEAVE; + break; + case DBOX_MOUSE_EVENT_UP | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_UP; + break; + case DBOX_MOUSE_EVENT_DOWN | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_DOWN; + break; + case DBOX_MOUSE_EVENT_MOVE | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_MOVE; + break; + case DBOX_MOUSE_EVENT_SET | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_SET; + break; + case DBOX_MOUSE_EVENT_UNSET | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_UNSET; + break; + case DBOX_MOUSE_EVENT_ON_SCROLL | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_ON_SCROLL; + break; + case DBOX_MOUSE_EVENT_ON_HOLD | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_ON_HOLD; + break; + case DBOX_MOUSE_EVENT_OFF_SCROLL | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_OFF_SCROLL; + break; + case DBOX_MOUSE_EVENT_OFF_HOLD | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_GBAR_MOUSE_OFF_HOLD; + break; + default: + ErrPrint("Invalid event type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + } else if (type & DBOX_MOUSE_EVENT_DBOX_MASK) { + int flag = 1; + + if (!handler->common->dbox.fb) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (type & DBOX_MOUSE_EVENT_MOVE) { + if (fabs(info->x - handler->common->dbox.x) < conf_event_filter() && fabs(info->y - handler->common->dbox.y) < conf_event_filter()) { + return DBOX_STATUS_ERROR_BUSY; + } + } else if (type & DBOX_MOUSE_EVENT_SET) { + flag = 0; + } + + if (flag) { + handler->common->dbox.x = info->x; + handler->common->dbox.y = info->y; + w = handler->common->dbox.width; + h = handler->common->dbox.height; + } + + switch ((type & ~(DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_DBOX_MASK))) { + case DBOX_MOUSE_EVENT_ENTER | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_ENTER; + break; + case DBOX_MOUSE_EVENT_LEAVE | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_LEAVE; + break; + case DBOX_MOUSE_EVENT_UP | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_UP; + break; + case DBOX_MOUSE_EVENT_DOWN | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_DOWN; + break; + case DBOX_MOUSE_EVENT_MOVE | DBOX_MOUSE_EVENT_MASK: + if (!handler->common->dbox.mouse_event) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + cmd = CMD_DBOX_MOUSE_MOVE; + break; + case DBOX_MOUSE_EVENT_SET | DBOX_MOUSE_EVENT_MASK: + if (!handler->common->dbox.mouse_event) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + cmd = CMD_DBOX_MOUSE_SET; + break; + case DBOX_MOUSE_EVENT_UNSET | DBOX_MOUSE_EVENT_MASK: + if (!handler->common->dbox.mouse_event) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + cmd = CMD_DBOX_MOUSE_UNSET; + break; + case DBOX_MOUSE_EVENT_ON_SCROLL | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_ON_SCROLL; + break; + case DBOX_MOUSE_EVENT_ON_HOLD | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_ON_HOLD; + break; + case DBOX_MOUSE_EVENT_OFF_SCROLL | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_OFF_SCROLL; + break; + case DBOX_MOUSE_EVENT_OFF_HOLD | DBOX_MOUSE_EVENT_MASK: + cmd = CMD_DBOX_MOUSE_OFF_HOLD; + break; + default: + ErrPrint("Invalid event type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + } else { + ErrPrint("Invalid event type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return send_mouse_event(handler, (const char *)&cmd, info->x * w, info->y * h); +} + +EAPI int dynamicbox_feed_key_event(dynamicbox_h handler, dynamicbox_key_event_type_e type, dynamicbox_key_event_info_t info, dynamicbox_ret_cb cb, void *data) +{ + int ret; + unsigned int cmd; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!(type & DBOX_KEY_EVENT_MASK)) { + ErrPrint("Invalid key event is used\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->request.key_event) { + ErrPrint("Previous key event is not completed yet\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + if (type & DBOX_MOUSE_EVENT_GBAR_MASK) { + if (!handler->common->is_gbar_created) { + ErrPrint("GBAR is not created\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->gbar.fb) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (type & DBOX_KEY_EVENT_DOWN) { + /*! + * \TODO + * filtering the reproduced events if it is too fast + */ + } else if (type & DBOX_KEY_EVENT_SET) { + /*! + * \TODO + * What can I do for this case? + */ + } + + /*! + * Must be short than 29 bytes. + */ + switch ((type & ~(DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_DBOX_MASK))) { + case DBOX_KEY_EVENT_FOCUS_IN | DBOX_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_FOCUS_IN; + break; + case DBOX_KEY_EVENT_FOCUS_OUT | DBOX_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_FOCUS_OUT; + break; + case DBOX_KEY_EVENT_UP | DBOX_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_UP; + break; + case DBOX_KEY_EVENT_DOWN | DBOX_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_DOWN; + break; + case DBOX_KEY_EVENT_SET | DBOX_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_SET; + break; + case DBOX_KEY_EVENT_UNSET | DBOX_KEY_EVENT_MASK: + cmd = CMD_GBAR_KEY_UNSET; + break; + default: + ErrPrint("Invalid event type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + } else if (type & DBOX_MOUSE_EVENT_DBOX_MASK) { + if (!handler->common->dbox.fb) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (type & DBOX_KEY_EVENT_DOWN) { + /*! + * \TODO + * filtering the reproduced events if it is too fast + */ + } else if (type & DBOX_KEY_EVENT_SET) { + /*! + * What can I do for this case? + */ + } + + switch ((type & ~(DBOX_MOUSE_EVENT_GBAR_MASK | DBOX_MOUSE_EVENT_DBOX_MASK))) { + case DBOX_KEY_EVENT_FOCUS_IN | DBOX_KEY_EVENT_MASK: + cmd = CMD_DBOX_KEY_FOCUS_IN; + break; + case DBOX_KEY_EVENT_FOCUS_OUT | DBOX_KEY_EVENT_MASK: + cmd = CMD_DBOX_KEY_FOCUS_OUT; + break; + case DBOX_KEY_EVENT_UP | DBOX_KEY_EVENT_MASK: + cmd = CMD_DBOX_KEY_UP; + break; + case DBOX_KEY_EVENT_DOWN | DBOX_KEY_EVENT_MASK: + cmd = CMD_DBOX_KEY_DOWN; + break; + case DBOX_KEY_EVENT_SET | DBOX_KEY_EVENT_MASK: + cmd = CMD_DBOX_KEY_SET; + break; + case DBOX_KEY_EVENT_UNSET | DBOX_KEY_EVENT_MASK: + cmd = CMD_DBOX_KEY_UNSET; + break; + default: + ErrPrint("Invalid event type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + } else { + ErrPrint("Invalid event type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!cb) { + cb = default_key_event_cb; + } + + ret = send_key_event(handler, (const char *)&cmd, info->keycode); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.key_event.cb = cb; + handler->cbs.key_event.data = data; + handler->common->request.key_event = 1; + } + + return ret; +} + +EAPI const char *dynamicbox_filename(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return NULL; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return NULL; + } + + if (handler->common->filename) { + return handler->common->filename; + } + + /* Oooops */ + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NONE); + return util_uri_to_path(handler->common->id); +} + +EAPI int dynamicbox_get_glance_bar_size(dynamicbox_h handler, int *w, int *h) +{ + int _w; + int _h; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!w) { + w = &_w; + } + if (!h) { + h = &_h; + } + + if (!handler->common->is_gbar_created) { + *w = handler->common->gbar.default_width; + *h = handler->common->gbar.default_height; + } else { + *w = handler->common->gbar.width; + *h = handler->common->gbar.height; + } + + return DBOX_STATUS_ERROR_NONE; +} + +EAPI dynamicbox_size_type_e dynamicbox_size(dynamicbox_h handler) +{ + int w; + int h; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_SIZE_TYPE_UNKNOWN; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_SIZE_TYPE_UNKNOWN; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_SIZE_TYPE_UNKNOWN; + } + + w = handler->common->dbox.width; + h = handler->common->dbox.height; + + switch (handler->common->dbox.type) { + case DBOX_TYPE_BUFFER: + case DBOX_TYPE_SCRIPT: + if (!fb_is_created(handler->common->dbox.fb)) { + w = 0; + h = 0; + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NOT_EXIST); + } + break; + default: + break; + } + + return dynamicbox_service_size_type(w, h); +} + +EAPI int dynamicbox_set_group(dynamicbox_h handler, const char *cluster, const char *category, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_CHANGE_GROUP; + int ret; + + if (!handler) { + ErrPrint("Handler is NIL\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!cluster || !category || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->request.group_changed) { + ErrPrint("Previous group changing request is not finished yet\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + if (!handler->common->is_user) { + ErrPrint("CA Livebox is not able to change the group\n"); + return DBOX_STATUS_ERROR_PERMISSION_DENIED; + } + + if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) { + DbgPrint("No changes\n"); + return DBOX_STATUS_ERROR_ALREADY; + } + + packet = packet_create((const char *)&cmd, "ssss", handler->common->pkgname, handler->common->id, cluster, category); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + if (!cb) { + cb = default_group_changed_cb; + } + + ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.group_changed.cb = cb; + handler->cbs.group_changed.data = data; + handler->common->request.group_changed = 1; + } + + return ret; +} + +EAPI int dynamicbox_get_group(dynamicbox_h handler, const char **cluster, const char **category) +{ + if (!handler) { + ErrPrint("Handler is NIL\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!cluster || !category || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + *cluster = handler->common->cluster; + *category = handler->common->category; + return DBOX_STATUS_ERROR_NONE; +} + +EAPI int dynamicbox_get_supported_sizes(dynamicbox_h handler, int *cnt, dynamicbox_size_type_e *size_list) +{ + register int i; + register int j; + + if (!handler || !size_list) { + ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!cnt || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + for (j = i = 0; i < DBOX_NR_OF_SIZE_LIST; i++) { + if (handler->common->dbox.size_list & (0x01 << i)) { + if (j == *cnt) { + break; + } + + size_list[j++] = (dynamicbox_size_type_e)(0x01 << i); + } + } + + *cnt = j; + return DBOX_STATUS_ERROR_NONE; +} + +EAPI const char *dynamicbox_pkgname(dynamicbox_h handler) +{ + if (!handler) { + ErrPrint("Handler is NIL\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NONE); + return handler->common->pkgname; +} + +EAPI double dynamicbox_priority(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return -1.0f; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return -1.0f; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid (%p)\n", handler); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return -1.0f; + } + + return handler->common->dbox.priority; +} + +EAPI int dynamicbox_delete_cluster(const char *cluster, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_DELETE_CLUSTER; + int ret; + + packet = packet_create((const char *)&cmd, "s", cluster); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo); + if (ret < 0) { + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI int dynamicbox_delete_category(const char *cluster, const char *category, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_DELETE_CATEGORY; + int ret; + + packet = packet_create((const char *)&cmd, "ss", cluster, category); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo); + if (ret < 0) { + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI dynamicbox_type_e dynamicbox_type(dynamicbox_h handler, int gbar) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_CONTENT_TYPE_INVALID; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_CONTENT_TYPE_INVALID; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_CONTENT_TYPE_INVALID; + } + + if (gbar) { + switch (handler->common->gbar.type) { + case GBAR_TYPE_TEXT: + return DBOX_CONTENT_TYPE_TEXT; + case GBAR_TYPE_BUFFER: + case GBAR_TYPE_SCRIPT: + { + const char *id; + id = fb_id(handler->common->gbar.fb); + if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return DBOX_CONTENT_TYPE_RESOURCE_ID; + } + } + return DBOX_CONTENT_TYPE_BUFFER; + case GBAR_TYPE_UIFW: + return DBOX_CONTENT_TYPE_UIFW; + default: + break; + } + } else { + switch (handler->common->dbox.type) { + case DBOX_TYPE_FILE: + return DBOX_CONTENT_TYPE_IMAGE; + case DBOX_TYPE_BUFFER: + case DBOX_TYPE_SCRIPT: + { + const char *id; + id = fb_id(handler->common->dbox.fb); + if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return DBOX_CONTENT_TYPE_RESOURCE_ID; + } + } + return DBOX_CONTENT_TYPE_BUFFER; + case DBOX_TYPE_TEXT: + return DBOX_CONTENT_TYPE_TEXT; + case DBOX_TYPE_UIFW: + return DBOX_CONTENT_TYPE_UIFW; + default: + break; + } + } + + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_CONTENT_TYPE_INVALID; +} + +EAPI int dynamicbox_set_text_handler(dynamicbox_h handler, int gbar, struct dynamicbox_script_operators *ops) +{ + if (!handler) { + ErrPrint("Handler is NIL\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + memcpy(&handler->cbs.gbar_ops, ops, sizeof(*ops)); + } else { + memcpy(&handler->cbs.dbox_ops, ops, sizeof(*ops)); + } + + return DBOX_STATUS_ERROR_NONE; +} + +EAPI int dynamicbox_acquire_extra_resource_id(dynamicbox_h handler, int gbar, int idx, dynamicbox_ret_cb cb, void *data) +{ + if (idx < 0) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handler's buffer type yet + * so we cannot use its type to validate handle + * + * handler->common.gbar.type == unknown + */ + if (!handler->common->gbar.extra_buffer) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + if (idx >= conf_extra_buffer_count()) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return dbox_acquire_gbar_extra_pixmap(handler, idx, cb, data); + } else { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handler's buffer type yet + * so we cannot use its type to validate handle + * + * handler->common.dbox.type == unknown + */ + if (!handler->common->dbox.extra_buffer) { + ErrPrint("Extra buffer is not prepared\n"); + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + if (idx >= conf_extra_buffer_count()) { + ErrPrint("Invalid parameter: %d / %d\n", idx, conf_extra_buffer_count()); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return dbox_acquire_dbox_extra_pixmap(handler, idx, cb, data); + } +} + +EAPI int dynamicbox_acquire_resource_id(dynamicbox_h handler, int gbar, dynamicbox_ret_cb cb, void *data) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + if (handler->common->gbar.type != GBAR_TYPE_SCRIPT && handler->common->gbar.type != GBAR_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return dbox_acquire_gbar_pixmap(handler, cb, data); + } else { + if (handler->common->dbox.type != DBOX_TYPE_SCRIPT && handler->common->dbox.type != DBOX_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return dbox_acquire_dbox_pixmap(handler, cb, data); + } +} + +/*! + * \note + * Do not check the state of handler and common-handler. + * If this function is used in the deleted callback, + * the handler and common-handler's state would be DELETE + * if this function check the state of handles, + * user cannot release the pixmap. + */ +EAPI int dynamicbox_release_resource_id(dynamicbox_h handler, int gbar, unsigned int resource_id) +{ + struct packet *packet; + const char *pkgname; + const char *id; + unsigned int cmd; + + if (resource_id == 0 /* || handler->state != DBOX_STATE_CREATE */) { + ErrPrint("Pixmap is invalid [%d]\n", resource_id); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + if (!handler) { + /*! + * \note + * Even though the handler is NULL, we should send the release request to the master. + * Because the resource_id resource can be released after the handler is destroyed. + * Pixmap resource is used by client. and it cannot be guaranteed to release resource_id. + * In some cases, the resource_id can be released after the handler is deleted. + * + * Its implementation is up to the viewer app. + * But we cannot force it to use only with valid handler. + */ + DbgPrint("Using NULL handler\n"); + pkgname = NULL; + id = NULL; + /*! + * \note + * Master will try to find the buffer handler using given resource_id. if the pkgname and id is not valid. + */ + } else { + if (!handler->common /* || handler-common->state != DBOX_STATE_CREATE */) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handler's buffer type yet + * so we cannot use its type to validate handle + * + * handler->common.gbar.type == unknown + */ + + pkgname = handler->common->pkgname; + id = handler->common->id; + } + + cmd = CMD_GBAR_RELEASE_PIXMAP; + } else { + if (!handler) { + /*! + * \note + * Even though the handler is NULL, we should send the release request to the master. + * Because the resource_id resource can be released after the handler is destroyed. + * Pixmap resource is used by client. and it cannot be guaranteed to release resource_id. + * In some cases, the resource_id can be released after the handler is deleted. + * + * Its implementation is up to the viewer app. + * But we cannot force it to use only with valid handler. + */ + DbgPrint("Using NULL handler\n"); + pkgname = NULL; + id = NULL; + /*! + * \note + * Master will try to find the buffer handler using given resource_id. if the pkgname and id is not valid. + */ + } else { + if (!handler->common /* || handler->common->state != DBOX_STATE_CREATE */) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handler's buffer type yet + * so we cannot use its type to validate handle + * + * handler->common.dbox.type == unknown + */ + + pkgname = handler->common->pkgname; + id = handler->common->id; + } + + cmd = CMD_DBOX_RELEASE_PIXMAP; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", pkgname, id, resource_id); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(handler, packet); +} + +EAPI unsigned int dynamicbox_extra_resource_id(const dynamicbox_h handler, int gbar, int idx) +{ + if (idx < 0) { + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (gbar) { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handler's buffer type yet + * so we cannot use its type to validate handle + * + * handler->common.gbar.type == unknown + */ + + if (!handler->common->gbar.extra_buffer || handler->common->gbar.last_extra_buffer_idx < 0) { + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NOT_EXIST); + return 0u; + } + + return handler->common->gbar.extra_buffer[handler->common->gbar.last_extra_buffer_idx]; + } else { + /** + * This can be called from extra_resource_created event. + * and it can be called before get the created event. + * then we didn't know this handler's buffer type yet + * so we cannot use its type to validate handle + * + * handler->common.dbox.type == unknown + */ + + if (!handler->common->dbox.extra_buffer || handler->common->dbox.last_extra_buffer_idx < 0) { + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NOT_EXIST); + return 0u; + } + + return handler->common->dbox.extra_buffer[handler->common->dbox.last_extra_buffer_idx]; + } +} + +EAPI unsigned int dynamicbox_resource_id(const dynamicbox_h handler, int gbar) +{ + const char *id; + unsigned int pixmap = 0u; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + if (gbar) { + if (handler->common->gbar.type != GBAR_TYPE_SCRIPT && handler->common->gbar.type != GBAR_TYPE_BUFFER) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + id = fb_id(handler->common->gbar.fb); + if (id && sscanf(id, SCHEMA_PIXMAP "%u", &pixmap) != 1) { + ErrPrint("PIXMAP Id is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + } else { + if (handler->common->dbox.type != DBOX_TYPE_SCRIPT && handler->common->dbox.type != DBOX_TYPE_BUFFER) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + + id = fb_id(handler->common->dbox.fb); + if (id && sscanf(id, SCHEMA_PIXMAP "%u", &pixmap) != 1) { + ErrPrint("PIXMAP Id is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0u; + } + } + + return pixmap; +} + +EAPI void *dynamicbox_acquire_buffer(dynamicbox_h handler, int gbar) +{ + if (gbar) { + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (handler->common->gbar.type != GBAR_TYPE_SCRIPT && handler->common->gbar.type != GBAR_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + return fb_acquire_buffer(handler->common->gbar.fb); + } else { + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common->id) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (handler->common->dbox.type != DBOX_TYPE_SCRIPT && handler->common->dbox.type != DBOX_TYPE_BUFFER) { + ErrPrint("Handler is not valid type\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + return fb_acquire_buffer(handler->common->dbox.fb); + } +} + +EAPI int dynamicbox_release_buffer(void *buffer) +{ + return fb_release_buffer(buffer); +} + +EAPI int dynamicbox_buffer_refcnt(void *buffer) +{ + return fb_refcnt(buffer); +} + +EAPI int dynamicbox_buffer_size(dynamicbox_h handler, int gbar) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + return fb_size(handler->common->gbar.fb); + } else { + return fb_size(handler->common->dbox.fb); + } +} + +EAPI int dynamicbox_is_created_by_user(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return handler->common->is_user; +} + +EAPI int dynamicbox_set_pinup(dynamicbox_h handler, int flag, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + unsigned int cmd = CMD_PINUP_CHANGED; + int ret; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->request.pinup) { + ErrPrint("Previous pinup request is not finished\n"); + return DBOX_STATUS_ERROR_BUSY; + } + + if (handler->common->is_pinned_up == flag) { + DbgPrint("No changes\n"); + return DBOX_STATUS_ERROR_ALREADY; + } + + packet = packet_create((const char *)&cmd, "ssi", handler->common->pkgname, handler->common->id, flag); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + if (!cb) { + cb = default_pinup_cb; + } + + ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL); + if (ret == (int)DBOX_STATUS_ERROR_NONE) { + handler->cbs.pinup.cb = cb; + handler->cbs.pinup.data = data; + handler->common->request.pinup = 1; + } + + return ret; +} + +EAPI int dynamicbox_is_pinned_up(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return handler->common->is_pinned_up; +} + +EAPI int dynamicbox_has_pinup(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + return handler->common->dbox.pinup_supported; +} + +EAPI int dynamicbox_set_data(dynamicbox_h handler, void *data) +{ + if (!handler) { + ErrPrint("Handler is NIL\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + handler->data = data; + return DBOX_STATUS_ERROR_NONE; +} + +EAPI void *dynamicbox_data(dynamicbox_h handler) +{ + if (!handler) { + ErrPrint("Handler is NIL\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + return handler->data; +} + +EAPI const char *dynamicbox_content(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NONE); + return handler->common->content; +} + +EAPI const char *dynamicbox_title(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NONE); + return handler->common->title; +} + +EAPI int dynamicbox_emit_text_signal(dynamicbox_h handler, dynamicbox_text_event_t event_info, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + unsigned int cmd = CMD_TEXT_SIGNAL; + int ret; + const char *emission; + const char *source; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (handler->common->dbox.type != DBOX_TYPE_TEXT && handler->common->gbar.type != GBAR_TYPE_TEXT) { + DbgPrint("Not a text box, but send signal\n"); + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!event_info) { + ErrPrint("Invalid event info\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + emission = event_info->emission; + if (!emission) { + emission = ""; + } + + source = event_info->source; + if (!source) { + source = ""; + } + + packet = packet_create((const char *)&cmd, "ssssdddd", + handler->common->pkgname, handler->common->id, + emission, source, + event_info->geometry.sx, event_info->geometry.sy, + event_info->geometry.ex, event_info->geometry.ey); + if (!packet) { + ErrPrint("Failed to build a param\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo); + if (ret < 0) { + dbox_destroy_cb_info(cbinfo); + } + + return ret; +} + +EAPI int dynamicbox_subscribe_group(const char *cluster, const char *category) +{ + struct packet *packet; + unsigned int cmd = CMD_SUBSCRIBE; + + /*! + * \todo + * Validate the group info using DB + * If the group info is not valid, do not send this request + */ + + packet = packet_create_noack((const char *)&cmd, "ss", cluster ? cluster : "", category ? category : ""); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int dynamicbox_unsubscribe_group(const char *cluster, const char *category) +{ + struct packet *packet; + unsigned int cmd = CMD_UNSUBSCRIBE; + + /*! + * \todo + * Validate the group info using DB + * If the group info is not valid, do not send this request + * AND Check the subscribed or not too + */ + + packet = packet_create_noack((const char *)&cmd, "ss", cluster ? cluster : "", category ? category : ""); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int dynamicbox_refresh(dynamicbox_h handler, int force) +{ + struct packet *packet; + unsigned int cmd = CMD_UPDATE; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", handler->common->pkgname, handler->common->id, force); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(handler, packet); +} + +EAPI int dynamicbox_refresh_group(const char *cluster, const char *category, int force) +{ + struct packet *packet; + unsigned int cmd = CMD_REFRESH_GROUP; + + if (!cluster || !category) { + ErrPrint("Invalid argument\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + packet = packet_create_noack((const char *)&cmd, "ssi", cluster, category, force); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int dynamicbox_set_visibility(dynamicbox_h handler, dynamicbox_visible_state_e state) +{ + int old_state; + int ret; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->is_user) { + /* System cluster dynamicbox cannot be changed its visible states */ + if (state == DBOX_HIDE_WITH_PAUSE) { + ErrPrint("CA Livebox is not able to change the visibility\n"); + return DBOX_STATUS_ERROR_PERMISSION_DENIED; + } + } + + if (handler->visible == state) { + DbgPrint("%s has no changes\n", handler->common->pkgname); + return DBOX_STATUS_ERROR_ALREADY; + } + + old_state = handler->visible; + handler->visible = state; + + ret = dbox_set_visibility(handler, state); + if (ret < 0) { + handler->visible = old_state; + } + + return ret; +} + +EAPI dynamicbox_visible_state_e dynamicbox_visibility(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is invalid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_VISIBLE_ERROR; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_VISIBLE_ERROR; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_VISIBLE_ERROR; + } + + return handler->visible; +} + +EAPI int dynamicbox_viewer_set_paused(void) +{ + struct packet *packet; + unsigned int cmd = CMD_CLIENT_PAUSED; + + packet = packet_create_noack((const char *)&cmd, "d", util_timestamp()); + if (!packet) { + ErrPrint("Failed to create a pause packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int dynamicbox_viewer_set_resumed(void) +{ + struct packet *packet; + unsigned int cmd = CMD_CLIENT_RESUMED; + + packet = packet_create_noack((const char *)&cmd, "d", util_timestamp()); + if (!packet) { + ErrPrint("Failed to create a resume packet\n"); + return DBOX_STATUS_ERROR_FAULT; + } + + return master_rpc_request_only(NULL, packet); +} + +EAPI int dynamicbox_sync_buffer(dynamicbox_h handler, int gbar) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + return dbox_sync_gbar_fb(handler->common); + } else { + return dbox_sync_dbox_fb(handler->common); + } +} + +EAPI const char *dynamicbox_alternative_icon(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid[%p]\n", handler); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + return handler->common->alt.icon; +} + +EAPI const char *dynamicbox_alternative_name(dynamicbox_h handler) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid[%p]\n", handler); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + return handler->common->alt.name; +} + +EAPI int dynamicbox_acquire_buffer_lock(dynamicbox_h handler, int is_gbar) +{ + int ret = DBOX_STATUS_ERROR_NONE; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid[%p]\n", handler); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Handler is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid[%p]\n", handler); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (is_gbar) { + ret = dynamicbox_service_acquire_lock(handler->common->gbar.lock); + } else { + ret = dynamicbox_service_acquire_lock(handler->common->dbox.lock); + } + + return ret == 0 ? DBOX_STATUS_ERROR_NONE : DBOX_STATUS_ERROR_FAULT; +} + +EAPI int dynamicbox_release_buffer_lock(dynamicbox_h handler, int is_gbar) +{ + int ret = DBOX_STATUS_ERROR_NONE; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid[%p]\n", handler); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (is_gbar) { + ret = dynamicbox_service_release_lock(handler->common->gbar.lock); + } else { + ret = dynamicbox_service_release_lock(handler->common->dbox.lock); + } + + return ret == 0 ? DBOX_STATUS_ERROR_NONE : DBOX_STATUS_ERROR_FAULT; +} + +EAPI int dynamicbox_set_option(dynamicbox_option_type_e option, int state) +{ + int ret = DBOX_STATUS_ERROR_NONE; + + switch (option) { + case DBOX_OPTION_MANUAL_SYNC: + conf_set_manual_sync(state); + break; + case DBOX_OPTION_FRAME_DROP_FOR_RESIZE: + conf_set_frame_drop_for_resizing(state); + break; + case DBOX_OPTION_SHARED_CONTENT: + conf_set_shared_content(state); + break; + case DBOX_OPTION_DIRECT_UPDATE: + if (s_info.init_count) { + DbgPrint("Already intialized, this option is not applied\n"); + } + conf_set_direct_update(state); + break; + case DBOX_OPTION_EXTRA_BUFFER_CNT: + ErrPrint("Permission denied\n"); + ret = DBOX_STATUS_ERROR_PERMISSION_DENIED; + break; + default: + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +} + +EAPI int dynamicbox_option(dynamicbox_option_type_e option) +{ + int ret; + + dynamicbox_set_last_status(DBOX_STATUS_ERROR_NONE); + switch (option) { + case DBOX_OPTION_MANUAL_SYNC: + ret = conf_manual_sync(); + break; + case DBOX_OPTION_FRAME_DROP_FOR_RESIZE: + ret = conf_frame_drop_for_resizing(); + break; + case DBOX_OPTION_SHARED_CONTENT: + ret = conf_shared_content(); + break; + case DBOX_OPTION_DIRECT_UPDATE: + ret = conf_direct_update(); + break; + case DBOX_OPTION_EXTRA_BUFFER_CNT: + ret = conf_extra_buffer_count(); + break; + default: + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + break; + } + + return ret; +} + +EAPI int dynamicbox_set_auto_launch_handler(dynamicbox_auto_launch_handler_cb dbox_launch_handler, void *data) +{ + s_info.launch.handler = dbox_launch_handler; + s_info.launch.data = data; + + return DBOX_STATUS_ERROR_NONE; +} + +EAPI int dynamicbox_damage_region_get(dynamicbox_h handler, int gbar, const dynamicbox_damage_region_t *region) +{ + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid[%p]\n", handler); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (gbar) { + region = &handler->common->dbox.last_damage; + } else { + region = &handler->common->gbar.last_damage; + } + + return DBOX_STATUS_ERROR_NONE; +} + +EAPI int dynamicbox_get_affected_extra_buffer(dynamicbox_h handler, int gbar, int *idx, unsigned int *resource_id) +{ + int _idx; + unsigned int _resource_id; + + if (!handler || handler->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common || handler->common->state != DBOX_STATE_CREATE) { + ErrPrint("Invalid handle\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid[%p]\n", handler); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!idx) { + idx = &_idx; + } + + if (!resource_id) { + resource_id = &_resource_id; + } + + if (gbar) { + if (!handler->common->gbar.extra_buffer || handler->common->gbar.last_extra_buffer_idx < 0) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + *idx = handler->common->gbar.last_extra_buffer_idx; + *resource_id = handler->common->gbar.extra_buffer[*idx]; + } else { + if (!handler->common->dbox.extra_buffer || handler->common->dbox.last_extra_buffer_idx < 0) { + return DBOX_STATUS_ERROR_NOT_EXIST; + } + + *idx = handler->common->dbox.last_extra_buffer_idx; + *resource_id = handler->common->dbox.extra_buffer[*idx]; + } + + return DBOX_STATUS_ERROR_NONE; +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/dynamicbox_internal.c b/dynamicbox_viewer/src/dynamicbox_internal.c new file mode 100644 index 0000000..4b3e034 --- /dev/null +++ b/dynamicbox_viewer/src/dynamicbox_internal.c @@ -0,0 +1,1058 @@ +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include "dlist.h" +#include "debug.h" +#include "dynamicbox.h" +#include "dynamicbox_internal.h" +#include "fb.h" +#include "conf.h" +#include "util.h" +#include "master_rpc.h" + +int errno; + +typedef enum event_state { + INFO_STATE_CALLBACK_IN_IDLE = 0x00, + INFO_STATE_CALLBACK_IN_PROCESSING = 0x01 +} event_state_e; + +struct event_info { + int is_deleted; + int (*handler)(dynamicbox_h handler, dynamicbox_event_type_e event, void *data); + void *user_data; +}; + +struct fault_info { + int is_deleted; + int (*handler)(dynamicbox_fault_type_e event, const char *pkgname, const char *filename, const char *func, void *data); + void *user_data; +}; + +static struct info { + struct dlist *dynamicbox_common_list; + struct dlist *dynamicbox_list; + struct dlist *event_list; + struct dlist *fault_list; + event_state_e event_state; + event_state_e fault_state; +} s_info = { + .dynamicbox_common_list = NULL, + .dynamicbox_list = NULL, + .event_list = NULL, + .fault_list = NULL, + .event_state = INFO_STATE_CALLBACK_IN_IDLE, + .fault_state = INFO_STATE_CALLBACK_IN_IDLE, +}; + +static inline void default_delete_cb(dynamicbox_h handler, int ret, void *data) +{ + DbgPrint("Default deleted event handler: %d\n", ret); +} + +static void del_ret_cb(dynamicbox_h handler, const struct packet *result, void *data) +{ + struct cb_info *info = data; + int ret; + dynamicbox_ret_cb cb; + void *cbdata; + + cb = info->cb; + cbdata = info->data; + dbox_destroy_cb_info(info); + + if (!result) { + ErrPrint("Connection lost?\n"); + ret = DBOX_STATUS_ERROR_FAULT; + } else if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid argument\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (ret == 0) { + handler->cbs.deleted.cb = cb; + handler->cbs.deleted.data = cbdata; + } else if (cb) { + cb(handler, ret, cbdata); + } + + /*! + * \note + * Do not call the deleted callback from here. + * master will send the "deleted" event. + * Then invoke this callback. + * + * if (handler->cbs.deleted.cb) + * handler->cbs.deleted.cb(handler, ret, handler->cbs.deleted.data); + */ +} + +struct dynamicbox_common *dbox_create_common_handle(dynamicbox_h handle, const char *pkgname, const char *cluster, const char *category) +{ + struct dynamicbox_common *common; + + common = calloc(1, sizeof(*common)); + if (!common) { + ErrPrint("Heap: %s\n", strerror(errno)); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return NULL; + } + + common->pkgname = strdup(pkgname); + if (!common->pkgname) { + free(common); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return NULL; + } + + common->cluster = strdup(cluster); + if (!common->cluster) { + ErrPrint("Error: %s\n", strerror(errno)); + free(common->pkgname); + free(common); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return NULL; + } + + common->category = strdup(category); + if (!common->category) { + ErrPrint("Error: %s\n", strerror(errno)); + free(common->cluster); + free(common->pkgname); + free(common); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return NULL; + } + + /* Data provider will set this */ + common->dbox.type = DBOX_TYPE_FILE; + common->gbar.type = GBAR_TYPE_SCRIPT; + + /* Used for handling the mouse event on a box */ + common->dbox.mouse_event = 0; + + /* Cluster infomration is not determined yet */ + common->nr_of_sizes = 0x01; + + common->timestamp = util_timestamp(); + common->is_user = 1; + common->delete_type = DBOX_DELETE_PERMANENTLY; + + common->gbar.lock = NULL; + common->gbar.last_extra_buffer_idx = DBOX_UNKNOWN_BUFFER; + + common->dbox.lock = NULL; + common->dbox.last_extra_buffer_idx = DBOX_UNKNOWN_BUFFER; + + common->state = DBOX_STATE_CREATE; + common->visible = DBOX_SHOW; + + s_info.dynamicbox_common_list = dlist_append(s_info.dynamicbox_common_list, common); + return common; +} + +int dbox_destroy_common_handle(struct dynamicbox_common *common) +{ + dlist_remove_data(s_info.dynamicbox_common_list, common); + + common->state = DBOX_STATE_DESTROYED; + + if (common->filename) { + (void)util_unlink(common->filename); + } + + free(common->cluster); + free(common->category); + free(common->id); + free(common->pkgname); + free(common->filename); + free(common->dbox.auto_launch); + free(common->alt.icon); + free(common->alt.name); + + if (common->dbox.fb) { + fb_destroy(common->dbox.fb); + common->dbox.fb = NULL; + } + + if (common->gbar.fb) { + fb_destroy(common->gbar.fb); + common->gbar.fb = NULL; + } + + return 0; +} + +int dbox_common_ref(struct dynamicbox_common *common, dynamicbox_h handle) +{ + common->dynamicbox_list = dlist_append(common->dynamicbox_list, handle); + common->refcnt++; + + return common->refcnt; +} + +int dbox_common_unref(struct dynamicbox_common *common, dynamicbox_h handle) +{ + int refcnt; + dlist_remove_data(common->dynamicbox_list, handle); + refcnt = --common->refcnt; + + return refcnt; +} + +int dbox_set_group(struct dynamicbox_common *common, const char *cluster, const char *category) +{ + void *pc = NULL; + void *ps = NULL; + + if (cluster) { + pc = strdup(cluster); + if (!pc) { + ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + } + + if (category) { + ps = strdup(category); + if (!ps) { + ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category); + free(pc); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + } + + if (common->cluster) { + free(common->cluster); + } + + if (common->category) { + free(common->category); + } + + common->cluster = pc; + common->category = ps; + + return DBOX_STATUS_ERROR_NONE; +} + +void dbox_set_size(struct dynamicbox_common *common, int w, int h) +{ + int size_type; + + common->dbox.width = w; + common->dbox.height = h; + + size_type = dynamicbox_service_size_type(w, h); + if (size_type != DBOX_SIZE_TYPE_UNKNOWN) { + common->dbox.mouse_event = dynamicbox_service_mouse_event(common->pkgname, size_type); + } +} + +void dbox_set_update_mode(struct dynamicbox_common *common, int active_mode) +{ + common->is_active_update = active_mode; +} + +void dbox_set_gbarsize(struct dynamicbox_common *common, int w, int h) +{ + common->gbar.width = w; + common->gbar.height = h; +} + +void dbox_set_default_gbarsize(struct dynamicbox_common *common, int w, int h) +{ + common->gbar.default_width = w; + common->gbar.default_height = h; +} + +void dbox_invoke_fault_handler(dynamicbox_fault_type_e event, const char *pkgname, const char *file, const char *func) +{ + struct dlist *l; + struct dlist *n; + struct fault_info *info; + + s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING; + + dlist_foreach_safe(s_info.fault_list, l, n, info) { + if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) { + info->is_deleted = 1; + } + + if (info->is_deleted) { + s_info.fault_list = dlist_remove(s_info.fault_list, l); + free(info); + } + } + + s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING; +} + +void dbox_invoke_event_handler(dynamicbox_h handler, dynamicbox_event_type_e event) +{ + struct dlist *l; + struct dlist *n; + struct event_info *info; + + if (event == DBOX_EVENT_DBOX_UPDATED && handler->common->refcnt > 1) { + if (handler->visible != DBOX_SHOW) { + DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname); + handler->paused_updating++; + return; + } else { + handler->paused_updating = 0; + } + } + + s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING; + + dlist_foreach_safe(s_info.event_list, l, n, info) { + if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) { + DbgPrint("Event handler returns EXIT_FAILURE\n"); + info->is_deleted = 1; + } + + if (info->is_deleted) { + s_info.event_list = dlist_remove(s_info.event_list, l); + free(info); + } + } + + s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING; +} + +struct dynamicbox_common *dbox_find_common_handle(const char *pkgname, const char *id) +{ + struct dlist *l; + struct dynamicbox_common *common; + + dlist_foreach(s_info.dynamicbox_common_list, l, common) { + if (!common->id) { + continue; + } + + if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) { + return common; + } + } + + return NULL; +} + +struct dynamicbox_common *dbox_find_common_handle_by_timestamp(double timestamp) +{ + struct dlist *l; + struct dynamicbox_common *common; + + dlist_foreach(s_info.dynamicbox_common_list, l, common) { + if (common->timestamp == timestamp) { + return common; + } + } + + return NULL; +} + +dynamicbox_h dbox_new_dynamicbox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category) +{ + dynamicbox_h handler; + + handler = calloc(1, sizeof(*handler)); + if (!handler) { + ErrPrint("Failed to create a new dynamicbox\n"); + return NULL; + } + + handler->common = dbox_create_common_handle(handler, pkgname, cluster, category); + if (!handler->common) { + ErrPrint("Heap: %s\n", strerror(errno)); + free(handler); + return NULL; + } + + dbox_common_ref(handler->common, handler); + dbox_set_id(handler->common, id); + handler->common->timestamp = timestamp; + handler->common->state = DBOX_STATE_CREATE; + handler->visible = DBOX_SHOW; + s_info.dynamicbox_list = dlist_append(s_info.dynamicbox_list, handler); + + return dbox_ref(handler); +} + +int dbox_delete_all(void) +{ + struct dlist *l; + struct dlist *n; + dynamicbox_h handler; + + dlist_foreach_safe(s_info.dynamicbox_list, l, n, handler) { + dbox_invoke_event_handler(handler, DBOX_EVENT_DELETED); + dbox_unref(handler, 1); + } + + return DBOX_STATUS_ERROR_NONE; +} + +int dbox_set_content(struct dynamicbox_common *common, const char *content) +{ + char *pc = NULL; + + if (content) { + pc = strdup(content); + if (!pc) { + ErrPrint("heap: %s [%s]\n", strerror(errno), content); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + } + + free(common->content); + common->content = pc; + return DBOX_STATUS_ERROR_NONE; +} + +int dbox_set_title(struct dynamicbox_common *common, const char *title) +{ + char *pt = NULL; + + if (title) { + pt = strdup(title); + if (!pt) { + ErrPrint("heap: %s [%s]\n", strerror(errno), title); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + } + + free(common->title); + common->title = pt; + return DBOX_STATUS_ERROR_NONE; +} + +void dbox_set_size_list(struct dynamicbox_common *common, int size_list) +{ + common->dbox.size_list = size_list; +} + +void dbox_set_auto_launch(struct dynamicbox_common *common, const char *auto_launch) +{ + char *pa = NULL; + + if (!auto_launch || !strlen(auto_launch)) { + return; + } + + pa = strdup(auto_launch); + if (!pa) { + ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch); + return; + } + + free(common->dbox.auto_launch); + common->dbox.auto_launch = pa; +} + +void dbox_set_priority(struct dynamicbox_common *common, double priority) +{ + common->dbox.priority = priority; +} + +void dbox_set_id(struct dynamicbox_common *common, const char *id) +{ + char *pi = NULL; + + if (id) { + pi = strdup(id); + if (!pi) { + ErrPrint("heap: %s [%s]\n", strerror(errno), pi); + return; + } + } + + free(common->id); + common->id = pi; +} + +void dbox_unlink_filename(struct dynamicbox_common *common) +{ + if (common->dbox.type == DBOX_TYPE_FILE || common->dbox.type == DBOX_TYPE_TEXT) { + if (common->filename && common->filename[0] && unlink(common->filename) < 0) { + ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename); + } + } +} + +void dbox_set_filename(struct dynamicbox_common *common, const char *filename) +{ + if (common->filename) { + free(common->filename); + } + + common->filename = strdup(filename); + if (!common->filename) { + ErrPrint("Heap: %s\n", strerror(errno)); + } +} + +void dbox_set_alt_icon(struct dynamicbox_common *common, const char *icon) +{ + char *_icon = NULL; + + if (icon && strlen(icon)) { + _icon = strdup(icon); + if (!_icon) { + ErrPrint("Heap: %s\n", strerror(errno)); + } + } + + free(common->alt.icon); + common->alt.icon = _icon; +} + +void dbox_set_alt_name(struct dynamicbox_common *common, const char *name) +{ + char *_name = NULL; + + if (name && strlen(name)) { + _name = strdup(name); + if (!_name) { + ErrPrint("Heap: %s\n", strerror(errno)); + } + } + + free(common->alt.name); + common->alt.name = _name; +} + +int dbox_set_dbox_fb(struct dynamicbox_common *common, const char *filename) +{ + struct fb_info *fb; + + if (!common) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + fb = common->dbox.fb; + if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */ + return DBOX_STATUS_ERROR_NONE; + } + + common->dbox.fb = NULL; + + if (!filename || filename[0] == '\0') { + if (fb) { + fb_destroy(fb); + } + return DBOX_STATUS_ERROR_NONE; + } + + common->dbox.fb = fb_create(filename, common->dbox.width, common->dbox.height); + if (!common->dbox.fb) { + ErrPrint("Faield to create a FB\n"); + if (fb) { + fb_destroy(fb); + } + return DBOX_STATUS_ERROR_FAULT; + } + + if (fb) { + fb_destroy(fb); + } + + return DBOX_STATUS_ERROR_NONE; +} + +int dbox_set_gbar_fb(struct dynamicbox_common *common, const char *filename) +{ + struct fb_info *fb; + + if (!common || common->state != DBOX_STATE_CREATE) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + fb = common->gbar.fb; + if (fb && !strcmp(fb_id(fb), filename)) { + /* BUFFER is not changed, just update the content */ + return DBOX_STATUS_ERROR_EXIST; + } + common->gbar.fb = NULL; + + if (!filename || filename[0] == '\0') { + if (fb) { + fb_destroy(fb); + } + return DBOX_STATUS_ERROR_NONE; + } + + common->gbar.fb = fb_create(filename, common->gbar.width, common->gbar.height); + if (!common->gbar.fb) { + ErrPrint("Failed to create a FB\n"); + if (fb) { + fb_destroy(fb); + } + return DBOX_STATUS_ERROR_FAULT; + } + + if (fb) { + fb_destroy(fb); + } + return DBOX_STATUS_ERROR_NONE; +} + +struct fb_info *dbox_get_dbox_fb(struct dynamicbox_common *common) +{ + return common->dbox.fb; +} + +struct fb_info *dbox_get_gbar_fb(struct dynamicbox_common *common) +{ + return common->gbar.fb; +} + +void dbox_set_user(struct dynamicbox_common *common, int user) +{ + common->is_user = user; +} + +void dbox_set_pinup(struct dynamicbox_common *common, int pinup_supported) +{ + common->dbox.pinup_supported = pinup_supported; +} + +void dbox_set_text_dbox(struct dynamicbox_common *common) +{ + common->dbox.type = DBOX_TYPE_TEXT; +} + +void dbox_set_text_gbar(struct dynamicbox_common *common) +{ + common->gbar.type = GBAR_TYPE_TEXT; +} + +int dbox_text_dbox(struct dynamicbox_common *common) +{ + return common->dbox.type == DBOX_TYPE_TEXT; +} + +int dbox_text_gbar(struct dynamicbox_common *common) +{ + return common->gbar.type == GBAR_TYPE_TEXT; +} + +void dbox_set_period(struct dynamicbox_common *common, double period) +{ + common->dbox.period = period; +} + +dynamicbox_h dbox_ref(dynamicbox_h handler) +{ + if (!handler) { + return NULL; + } + + handler->refcnt++; + return handler; +} + +dynamicbox_h dbox_unref(dynamicbox_h handler, int destroy_common) +{ + if (!handler) { + return NULL; + } + + handler->refcnt--; + if (handler->refcnt > 0) { + return handler; + } + + if (handler->cbs.created.cb) { + handler->cbs.created.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.created.data); + handler->cbs.created.cb = NULL; + handler->cbs.created.data = NULL; + } + + if (handler->cbs.deleted.cb) { + handler->cbs.deleted.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.deleted.data); + handler->cbs.deleted.cb = NULL; + handler->cbs.deleted.data = NULL; + } + + if (handler->cbs.pinup.cb) { + handler->cbs.pinup.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.pinup.data); + handler->cbs.pinup.cb = NULL; + handler->cbs.pinup.data = NULL; + } + + if (handler->cbs.group_changed.cb) { + handler->cbs.group_changed.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.group_changed.data); + handler->cbs.group_changed.cb = NULL; + handler->cbs.group_changed.data = NULL; + } + + if (handler->cbs.period_changed.cb) { + handler->cbs.period_changed.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.period_changed.data); + handler->cbs.period_changed.cb = NULL; + handler->cbs.period_changed.data = NULL; + } + + if (handler->cbs.size_changed.cb) { + handler->cbs.size_changed.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.size_changed.data); + handler->cbs.size_changed.cb = NULL; + handler->cbs.size_changed.data = NULL; + } + + if (handler->cbs.gbar_created.cb) { + handler->cbs.gbar_created.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.gbar_created.data); + handler->cbs.gbar_created.cb = NULL; + handler->cbs.gbar_created.data = NULL; + } + + if (handler->cbs.gbar_destroyed.cb) { + handler->cbs.gbar_destroyed.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.gbar_destroyed.data); + handler->cbs.gbar_destroyed.cb = NULL; + handler->cbs.gbar_destroyed.data = NULL; + } + + if (handler->cbs.update_mode.cb) { + handler->cbs.update_mode.cb(handler, DBOX_STATUS_ERROR_FAULT, handler->cbs.update_mode.data); + handler->cbs.update_mode.cb = NULL; + handler->cbs.update_mode.data = NULL; + } + + if (handler->cbs.access_event.cb) { + handler->cbs.access_event.cb(handler, DBOX_ACCESS_STATUS_ERROR, handler->cbs.access_event.data); + handler->cbs.access_event.cb = NULL; + handler->cbs.access_event.data = NULL; + } + + if (handler->cbs.key_event.cb) { + handler->cbs.key_event.cb(handler, DBOX_KEY_STATUS_ERROR, handler->cbs.key_event.data); + handler->cbs.key_event.cb = NULL; + handler->cbs.key_event.data = NULL; + } + + dlist_remove_data(s_info.dynamicbox_list, handler); + + handler->state = DBOX_STATE_DESTROYED; + if (dbox_common_unref(handler->common, handler) == 0) { + if (destroy_common) { + /*! + * \note + * Lock file should be deleted after all callbacks are processed. + */ + (void)dynamicbox_service_destroy_lock(handler->common->dbox.lock); + handler->common->dbox.lock = NULL; + dbox_destroy_common_handle(handler->common); + } + } + free(handler); + DbgPrint("Handler is released\n"); + return NULL; +} + +int dbox_send_delete(dynamicbox_h handler, int type, dynamicbox_ret_cb cb, void *data) +{ + struct packet *packet; + struct cb_info *cbinfo; + int ret; + + if (handler->common->request.deleted) { + ErrPrint("Already in-progress\n"); + if (cb) { + cb(handler, DBOX_STATUS_ERROR_NONE, data); + } + return DBOX_STATUS_ERROR_BUSY; + } + + if (!cb) { + cb = default_delete_cb; + } + + packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp); + if (!packet) { + ErrPrint("Failed to build a param\n"); + if (cb) { + cb(handler, DBOX_STATUS_ERROR_FAULT, data); + } + + return DBOX_STATUS_ERROR_FAULT; + } + + cbinfo = dbox_create_cb_info(cb, data); + if (!cbinfo) { + packet_destroy(packet); + ErrPrint("Failed to create cbinfo\n"); + if (cb) { + cb(handler, DBOX_STATUS_ERROR_FAULT, data); + } + + return DBOX_STATUS_ERROR_FAULT; + } + + ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo); + if (ret < 0) { + /*! + * Packet is destroyed by master_rpc_async_request. + */ + dbox_destroy_cb_info(cbinfo); + + if (cb) { + cb(handler, DBOX_STATUS_ERROR_FAULT, data); + } + } else { + handler->common->request.deleted = 1; + } + + return ret; +} + +int dbox_sync_dbox_fb(struct dynamicbox_common *common) +{ + int ret; + + if (fb_type(dbox_get_dbox_fb(common)) == DBOX_FB_TYPE_FILE) { + (void)dynamicbox_service_acquire_lock(common->dbox.lock); + ret = fb_sync(dbox_get_dbox_fb(common), common->dbox.last_damage.x, common->dbox.last_damage.y, common->dbox.last_damage.w, common->dbox.last_damage.h); + (void)dynamicbox_service_release_lock(common->dbox.lock); + } else { + ret = fb_sync(dbox_get_dbox_fb(common), common->dbox.last_damage.x, common->dbox.last_damage.y, common->dbox.last_damage.w, common->dbox.last_damage.h); + } + + return ret; +} + +int dbox_sync_gbar_fb(struct dynamicbox_common *common) +{ + int ret; + + if (fb_type(dbox_get_gbar_fb(common)) == DBOX_FB_TYPE_FILE) { + (void)dynamicbox_service_acquire_lock(common->gbar.lock); + ret = fb_sync(dbox_get_gbar_fb(common), common->gbar.last_damage.x, common->gbar.last_damage.y, common->gbar.last_damage.w, common->gbar.last_damage.h); + (void)dynamicbox_service_release_lock(common->gbar.lock); + } else { + ret = fb_sync(dbox_get_gbar_fb(common), common->gbar.last_damage.x, common->gbar.last_damage.y, common->gbar.last_damage.w, common->gbar.last_damage.h); + } + + return ret; +} + +struct dynamicbox_common *dbox_find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category) +{ + struct dlist *l; + struct dynamicbox_common *common; + + if (!conf_shared_content()) { + /*! + * Shared content option is turnned off. + */ + return NULL; + } + + dlist_foreach(s_info.dynamicbox_common_list, l, common) { + if (common->state != DBOX_STATE_CREATE) { + continue; + } + + if (strcmp(common->pkgname, pkgname)) { + continue; + } + + if (strcmp(common->cluster, cluster)) { + DbgPrint("Cluster mismatched\n"); + continue; + } + + if (strcmp(common->category, category)) { + DbgPrint("Category mismatched\n"); + continue; + } + + if (common->content && content) { + if (strcmp(common->content, content)) { + DbgPrint("%s Content ([%s] <> [%s])\n", common->pkgname, common->content, content); + continue; + } + } else { + int c1_len; + int c2_len; + + /*! + * \note + * We assumes "" (ZERO length string) to NULL + */ + c1_len = common->content ? strlen(common->content) : 0; + c2_len = content ? strlen(content) : 0; + if (c1_len != c2_len) { + DbgPrint("%s Content %p <> %p\n", common->pkgname, common->content, content); + continue; + } + } + + if (common->request.size_changed) { + DbgPrint("Changing size\n"); + /*! + * \note + * Do not re-use resizing instance. + * We will not use predicted size. + */ + continue; + } + + if (common->request.created) { + DbgPrint("Creating now but re-use it (%s)\n", common->pkgname); + } + + if (common->dbox.width != w || common->dbox.height != h) { + DbgPrint("Size mismatched\n"); + continue; + } + + DbgPrint("common handle is found: %p\n", common); + return common; + } + + return NULL; +} + +dynamicbox_h dbox_find_dbox_in_show(struct dynamicbox_common *common) +{ + struct dlist *l; + dynamicbox_h item; + + dlist_foreach(common->dynamicbox_list, l, item) { + if (item->visible == DBOX_SHOW) { + DbgPrint("%s visibility is not changed\n", common->pkgname); + return item; + } + } + + return NULL; +} + +dynamicbox_h dbox_get_dbox_nth(struct dynamicbox_common *common, int nth) +{ + dynamicbox_h item; + struct dlist *l; + + l = dlist_nth(common->dynamicbox_list, nth); + item = dlist_data(l); + + return item; +} + +int dbox_add_event_handler(dynamicbox_event_handler_cb dbox_cb, void *data) +{ + struct event_info *info; + info = malloc(sizeof(*info)); + if (!info) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + info->handler = dbox_cb; + info->user_data = data; + info->is_deleted = 0; + + s_info.event_list = dlist_append(s_info.event_list, info); + return DBOX_STATUS_ERROR_NONE; +} + +void *dbox_remove_event_handler(dynamicbox_event_handler_cb dbox_cb) +{ + struct event_info *info; + struct dlist *l; + + dlist_foreach(s_info.event_list, l, info) { + if (info->handler == dbox_cb) { + void *data; + + data = info->user_data; + + if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) { + info->is_deleted = 1; + } else { + s_info.event_list = dlist_remove(s_info.event_list, l); + free(info); + } + + return data; + } + } + + return NULL; +} + +int dbox_add_fault_handler(dynamicbox_fault_handler_cb dbox_cb, void *data) +{ + struct fault_info *info; + info = malloc(sizeof(*info)); + if (!info) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + info->handler = dbox_cb; + info->user_data = data; + info->is_deleted = 0; + + s_info.fault_list = dlist_append(s_info.fault_list, info); + return DBOX_STATUS_ERROR_NONE; +} + +void *dbox_remove_fault_handler(dynamicbox_fault_handler_cb dbox_cb) +{ + struct fault_info *info; + struct dlist *l; + + dlist_foreach(s_info.fault_list, l, info) { + if (info->handler == dbox_cb) { + void *data; + + data = info->user_data; + + if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) { + info->is_deleted = 1; + } else { + s_info.fault_list = dlist_remove(s_info.fault_list, l); + free(info); + } + + return data; + } + } + + return NULL; +} + +struct cb_info *dbox_create_cb_info(dynamicbox_ret_cb cb, void *data) +{ + struct cb_info *info; + + info = malloc(sizeof(*info)); + if (!info) { + ErrPrint("Heap: %s\n", strerror(errno)); + return NULL; + } + + info->cb = cb; + info->data = data; + return info; +} + +void dbox_destroy_cb_info(struct cb_info *info) +{ + free(info); +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/fb.c b/dynamicbox_viewer/src/fb.c new file mode 100644 index 0000000..6f0d1f6 --- /dev/null +++ b/dynamicbox_viewer/src/fb.c @@ -0,0 +1,674 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include /* For error code */ +#include /* For buffer event data */ +#include + +#include "debug.h" +#include "util.h" +#include "fb.h" + +int errno; + +static struct { + Display *disp; + int screen; + Visual *visual; + int disp_is_opened; +} s_info = { + .disp = NULL, + .disp_is_opened = 0, + .screen = -1, + .visual = NULL, +}; + +int fb_init(void *disp) +{ + s_info.disp = disp; + if (s_info.disp) { + Screen *screen; + + screen = DefaultScreenOfDisplay(s_info.disp); + + s_info.screen = DefaultScreen(s_info.disp); + s_info.visual = DefaultVisualOfScreen(screen); + } + + return DBOX_STATUS_ERROR_NONE; +} + +int fb_fini(void) +{ + if (s_info.disp_is_opened && s_info.disp) { + XCloseDisplay(s_info.disp); + } + + s_info.disp = NULL; + s_info.disp_is_opened = 0; + s_info.visual = NULL; + s_info.screen = -1; + return 0; +} + +static inline void update_fb_size(struct fb_info *info) +{ + info->bufsz = info->w * info->h * info->pixels; +} + +static int sync_for_file(struct fb_info *info, int x, int y, int w, int h) +{ + int fd; + dynamicbox_fb_t buffer; + + buffer = info->buffer; + + if (!buffer) { /* Ignore this sync request */ + return DBOX_STATUS_ERROR_NONE; + } + + if (buffer->state != DBOX_FB_STATE_CREATED) { + ErrPrint("Invalid state of a FB\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (buffer->type != DBOX_FB_TYPE_FILE) { + ErrPrint("Invalid buffer\n"); + return DBOX_STATUS_ERROR_NONE; + } + + fd = open(util_uri_to_path(info->id), O_RDONLY); + if (fd < 0) { + ErrPrint("Failed to open a file (%s) because of (%s)\n", + util_uri_to_path(info->id), strerror(errno)); + + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return DBOX_STATUS_ERROR_NONE; + } + + /** + * @note + * Could we get some advantage if we load a part of file instead of loading all of them? + */ + if (x != 0 || y != 0 || info->w != w || info->h != h) { + int iy; + register int index; + register int width; + + for (iy = y; iy < h; iy++) { + index = iy * info->w + x; + width = w * info->pixels; + + if (lseek(fd, index * info->pixels, SEEK_SET) != index * info->pixels) { + ErrPrint("lseek: %s\n", strerror(errno)); + if (close(fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return DBOX_STATUS_ERROR_NONE; + } + + if (read(fd, ((unsigned int *)buffer->data) + index, width) != width) { + if (close(fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return DBOX_STATUS_ERROR_NONE; + } + } + } else { + if (read(fd, buffer->data, info->bufsz) != info->bufsz) { + ErrPrint("read: %s\n", strerror(errno)); + if (close(fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + + /** + * @note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return DBOX_STATUS_ERROR_NONE; + } + } + + if (close(fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + return DBOX_STATUS_ERROR_NONE; +} + +static int sync_for_pixmap(struct fb_info *info, int x, int y, int w, int h) +{ + dynamicbox_fb_t buffer; + XShmSegmentInfo si; + XImage *xim; + + buffer = info->buffer; + if (!buffer) { /*!< Ignore this sync request */ + return DBOX_STATUS_ERROR_NONE; + } + + if (buffer->state != DBOX_FB_STATE_CREATED) { + ErrPrint("Invalid state of a FB\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (buffer->type != DBOX_FB_TYPE_PIXMAP) { + ErrPrint("Invalid buffer\n"); + return DBOX_STATUS_ERROR_NONE; + } + + if (!s_info.disp) { + s_info.disp = XOpenDisplay(NULL); + if (s_info.disp) { + Screen *screen; + + s_info.disp_is_opened = 1; + + screen = DefaultScreenOfDisplay(s_info.disp); + + s_info.screen = DefaultScreen(s_info.disp); + s_info.visual = DefaultVisualOfScreen(screen); + } else { + ErrPrint("Failed to open a display\n"); + return DBOX_STATUS_ERROR_FAULT; + } + } + + if (info->handle == 0) { + ErrPrint("Pixmap ID is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (info->bufsz == 0) { + /*! + * If the client does not acquire the buffer, + * This function will do nothing. + * It will work only if the buffer is acquired. + * To sync its contents. + */ + DbgPrint("Nothing can be sync\n"); + return DBOX_STATUS_ERROR_NONE; + } + + si.shmid = shmget(IPC_PRIVATE, info->bufsz, IPC_CREAT | 0666); + if (si.shmid < 0) { + ErrPrint("shmget: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_FAULT; + } + + si.readOnly = False; + si.shmaddr = shmat(si.shmid, NULL, 0); + if (si.shmaddr == (void *)-1) { + if (shmctl(si.shmid, IPC_RMID, 0) < 0) { + ErrPrint("shmctl: %s\n", strerror(errno)); + } + + return DBOX_STATUS_ERROR_FAULT; + } + + /*! + * \NOTE + * Use the 24 bits Pixmap for Video player + */ + xim = XShmCreateImage(s_info.disp, s_info.visual, + (info->pixels << 3), ZPixmap, NULL, + &si, + info->w, info->h); + if (xim == NULL) { + if (shmdt(si.shmaddr) < 0) { + ErrPrint("shmdt: %s\n", strerror(errno)); + } + + if (shmctl(si.shmid, IPC_RMID, 0) < 0) { + ErrPrint("shmctl: %s\n", strerror(errno)); + } + + return DBOX_STATUS_ERROR_FAULT; + } + + xim->data = si.shmaddr; + XShmAttach(s_info.disp, &si); + + XShmGetImage(s_info.disp, info->handle, xim, 0, 0, 0xFFFFFFFF); + XSync(s_info.disp, False); + + if (x != 0 || y != 0 || info->w != w || info->h != h) { + int ix; + int iy; + register int index; + + for (iy = y; iy < h; iy++) { + for (ix = x; ix < w; ix++) { + index = iy * info->w + x; + *(((unsigned int *)buffer->data) + index) = *(((unsigned int *)xim->data) + index); + } + } + } else { + memcpy(buffer->data, xim->data, info->bufsz); + } + + XShmDetach(s_info.disp, &si); + XDestroyImage(xim); + + if (shmdt(si.shmaddr) < 0) { + ErrPrint("shmdt: %s\n", strerror(errno)); + } + + if (shmctl(si.shmid, IPC_RMID, 0) < 0) { + ErrPrint("shmctl: %s\n", strerror(errno)); + } + + return DBOX_STATUS_ERROR_NONE; +} + +int fb_sync(struct fb_info *info, int x, int y, int w, int h) +{ + if (!info) { + ErrPrint("FB Handle is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!info->id || info->id[0] == '\0') { + DbgPrint("Ingore sync\n"); + return DBOX_STATUS_ERROR_NONE; + } + + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + return sync_for_file(info, x, y, w, h); + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + return sync_for_pixmap(info, x, y, w, h); + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + /* No need to do sync */ + return DBOX_STATUS_ERROR_NONE; + } + + return DBOX_STATUS_ERROR_INVALID_PARAMETER; +} + +struct fb_info *fb_create(const char *id, int w, int h) +{ + struct fb_info *info; + + if (!id || id[0] == '\0') { + ErrPrint("Invalid ID\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->pixels = sizeof(int); /* Use the default pixels(depth) */ + + if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) { + DbgPrint("SHMID: %d is gotten\n", info->handle); + } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) { + DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels); + } else { + info->handle = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + info->bufsz = 0; + info->buffer = NULL; + info->w = w; + info->h = h; + + return info; +} + +int fb_destroy(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (info->buffer) { + dynamicbox_fb_t buffer; + buffer = info->buffer; + + buffer->info = NULL; + } + + free(info->id); + free(info); + return DBOX_STATUS_ERROR_NONE; +} + +int fb_is_created(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return 0; + } + + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) { + return 1; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) { + return 1; + } else { + const char *path; + path = util_uri_to_path(info->id); + if (path && access(path, F_OK | R_OK) == 0) { + return 1; + } else { + ErrPrint("access: %s (%s)\n", strerror(errno), path); + } + } + + return 0; +} + +void *fb_acquire_buffer(struct fb_info *info) +{ + dynamicbox_fb_t buffer; + + if (!info) { + ErrPrint("info == NIL\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!info->buffer) { + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + update_fb_size(info); + + buffer = calloc(1, sizeof(*buffer) + info->bufsz); + if (!buffer) { + ErrPrint("Heap: %s\n", strerror(errno)); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + info->bufsz = 0; + return NULL; + } + + buffer->type = DBOX_FB_TYPE_PIXMAP; + buffer->refcnt = 0; + buffer->state = DBOX_FB_STATE_CREATED; + buffer->info = info; + info->buffer = buffer; + + /*! + * \note + * Just update from here. + */ + sync_for_pixmap(info, 0, 0, info->w, info->h); + } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + update_fb_size(info); + + buffer = calloc(1, sizeof(*buffer) + info->bufsz); + if (!buffer) { + ErrPrint("Heap: %s\n", strerror(errno)); + info->bufsz = 0; + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return NULL; + } + + buffer->type = DBOX_FB_TYPE_FILE; + buffer->refcnt = 0; + buffer->state = DBOX_FB_STATE_CREATED; + buffer->info = info; + info->buffer = buffer; + + sync_for_file(info, 0, 0, info->w, info->h); + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + buffer = shmat(info->handle, NULL, 0); + if (buffer == (void *)-1) { + ErrPrint("shmat: %s (%d)\n", strerror(errno), info->handle); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT); + return NULL; + } + + return buffer->data; + } else { + ErrPrint("Buffer is not created (%s)\n", info->id); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + } + + buffer = info->buffer; + + switch (buffer->type) { + case DBOX_FB_TYPE_PIXMAP: + buffer->refcnt++; + break; + case DBOX_FB_TYPE_FILE: + buffer->refcnt++; + break; + default: + DbgPrint("Unknwon FP: %d\n", buffer->type); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + break; + } + + return buffer->data; +} + +int fb_release_buffer(void *data) +{ + dynamicbox_fb_t buffer; + + if (!data) { + ErrPrint("buffer data == NIL\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + buffer = container_of(data, struct dynamicbox_fb, data); + + if (buffer->state != DBOX_FB_STATE_CREATED) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case DBOX_FB_TYPE_SHM: + if (shmdt(buffer) < 0) { + ErrPrint("shmdt: %s\n", strerror(errno)); + } + break; + case DBOX_FB_TYPE_PIXMAP: + buffer->refcnt--; + if (buffer->refcnt == 0) { + struct fb_info *info; + info = buffer->info; + + buffer->state = DBOX_FB_STATE_DESTROYED; + + if (info && info->buffer == buffer) { + info->buffer = NULL; + } + free(buffer); + } + break; + case DBOX_FB_TYPE_FILE: + buffer->refcnt--; + if (buffer->refcnt == 0) { + struct fb_info *info; + info = buffer->info; + + buffer->state = DBOX_FB_STATE_DESTROYED; + + if (info && info->buffer == buffer) { + info->buffer = NULL; + } + + free(buffer); + } + break; + default: + ErrPrint("Unknwon buffer type\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + break; + } + + return DBOX_STATUS_ERROR_NONE; +} + +int fb_refcnt(void *data) +{ + dynamicbox_fb_t buffer; + struct shmid_ds buf; + int ret; + + if (!data) { + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + buffer = container_of(data, struct dynamicbox_fb, data); + + if (buffer->state != DBOX_FB_STATE_CREATED) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case DBOX_FB_TYPE_SHM: + if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) { + ErrPrint("Error: %s\n", strerror(errno)); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = buf.shm_nattch; + break; + case DBOX_FB_TYPE_PIXMAP: + ret = buffer->refcnt; + break; + case DBOX_FB_TYPE_FILE: + ret = buffer->refcnt; + break; + default: + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +} + +const char *fb_id(struct fb_info *info) +{ + return info ? info->id : NULL; +} + +int fb_get_size(struct fb_info *info, int *w, int *h) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + *w = info->w; + *h = info->h; + return DBOX_STATUS_ERROR_NONE; +} + +int fb_size(struct fb_info *info) +{ + if (!info) { + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0; + } + + update_fb_size(info); + + return info->bufsz; +} + +int fb_type(struct fb_info *info) +{ + dynamicbox_fb_t buffer; + + if (!info) { + return DBOX_FB_TYPE_ERROR; + } + + buffer = info->buffer; + if (!buffer) { + int type = DBOX_FB_TYPE_ERROR; + /*! + * \note + * Try to get this from SCHEMA + */ + if (info->id) { + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + type = DBOX_FB_TYPE_FILE; + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + type = DBOX_FB_TYPE_PIXMAP; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + type = DBOX_FB_TYPE_SHM; + } + } + + return type; + } + + return buffer->type; +} +/* End of a file */ diff --git a/dynamicbox_viewer/src/fb_wayland.c b/dynamicbox_viewer/src/fb_wayland.c new file mode 100644 index 0000000..786f922 --- /dev/null +++ b/dynamicbox_viewer/src/fb_wayland.c @@ -0,0 +1,451 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include /* For error code */ +#include + +#include "debug.h" +#include "util.h" +#include "fb.h" + +int errno; + +struct fb_info { + char *id; + int w; + int h; + int bufsz; + void *buffer; + + int pixels; + int handle; +}; + +static struct { +} s_info = { +}; + +int fb_init(void *disp) +{ + return 0; +} + +int fb_fini(void) +{ + return 0; +} + +static inline void update_fb_size(struct fb_info *info) +{ + info->bufsz = info->w * info->h * info->pixels; +} + +static inline int sync_for_file(struct fb_info *info) +{ + int fd; + struct buffer *buffer; + + buffer = info->buffer; + + if (!buffer) { /* Ignore this sync request */ + return DBOX_STATUS_ERROR_NONE; + } + + if (buffer->state != CREATED) { + ErrPrint("Invalid state of a FB\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (buffer->type != DBOX_BUFFER_TYPE_FILE) { + ErrPrint("Invalid buffer\n"); + return DBOX_STATUS_ERROR_NONE; + } + + fd = open(util_uri_to_path(info->id), O_RDONLY); + if (fd < 0) { + ErrPrint("Failed to open a file (%s) because of (%s)\n", + util_uri_to_path(info->id), strerror(errno)); + + /*! + * \note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return DBOX_STATUS_ERROR_NONE; + } + + if (read(fd, buffer->data, info->bufsz) != info->bufsz) { + ErrPrint("read: %s\n", strerror(errno)); + if (close(fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + + /*! + * \note + * But return ZERO, even if we couldn't get a buffer file, + * the viewer can draw empty screen. + * + * and then update it after it gots update events + */ + return DBOX_STATUS_ERROR_NONE; + } + + if (close(fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + return DBOX_STATUS_ERROR_NONE; +} + +int fb_sync(struct fb_info *info, int x, int y, int w, int h) +{ + if (!info) { + ErrPrint("FB Handle is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (!info->id || info->id[0] == '\0') { + DbgPrint("Ingore sync\n"); + return DBOX_STATUS_ERROR_NONE; + } + + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + return sync_for_file(info); + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + /* No need to do sync */ + return DBOX_STATUS_ERROR_NONE; + } + + return DBOX_STATUS_ERROR_INVALID_PARAMETER; +} + +struct fb_info *fb_create(const char *id, int w, int h) +{ + struct fb_info *info; + + if (!id || id[0] == '\0') { + ErrPrint("Invalid ID\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->pixels = sizeof(int); /* Use the default pixels(depth) */ + + if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) { + DbgPrint("SHMID: %d is gotten\n", info->handle); + } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) { + DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels); + ErrPrint("Unsupported\n"); + free(info); + return NULL; + } else { + info->handle = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + info->bufsz = 0; + info->buffer = NULL; + info->w = w; + info->h = h; + + return info; +} + +int fb_destroy(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + if (info->buffer) { + struct buffer *buffer; + buffer = info->buffer; + + buffer->info = NULL; + } + + free(info->id); + free(info); + return DBOX_STATUS_ERROR_NONE; +} + +int fb_is_created(struct fb_info *info) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return 0; + } + + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) { + return 1; + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) { + return 1; + } else { + const char *path; + path = util_uri_to_path(info->id); + if (path && access(path, F_OK | R_OK) == 0) { + return 1; + } else { + ErrPrint("access: %s (%s)\n", strerror(errno), path); + } + } + + return 0; +} + +void *fb_acquire_buffer(struct fb_info *info) +{ + struct buffer *buffer; + + if (!info) { + ErrPrint("info == NIL\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + + if (!info->buffer) { + if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + ErrPrint("Unsupported Type\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + update_fb_size(info); + + buffer = calloc(1, sizeof(*buffer) + info->bufsz); + if (!buffer) { + ErrPrint("Heap: %s\n", strerror(errno)); + info->bufsz = 0; + dynamicbox_set_last_status(DBOX_STATUS_ERROR_OUT_OF_MEMORY); + return NULL; + } + + buffer->type = DBOX_BUFFER_TYPE_FILE; + buffer->refcnt = 0; + buffer->state = CREATED; + buffer->info = info; + info->buffer = buffer; + + sync_for_file(info); + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + buffer = shmat(info->handle, NULL, 0); + if (buffer == (void *)-1) { + ErrPrint("shmat: %s (%d)\n", strerror(errno), info->handle); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT); + return NULL; + } + + return buffer->data; + } else { + ErrPrint("Buffer is not created (%s)\n", info->id); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return NULL; + } + } + + buffer = info->buffer; + + switch (buffer->type) { + case DBOX_BUFFER_TYPE_FILE: + buffer->refcnt++; + break; + case DBOX_BUFFER_TYPE_PIXMAP: + default: + DbgPrint("Unknwon FP: %d\n", buffer->type); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + break; + } + + return buffer->data; +} + +int fb_release_buffer(void *data) +{ + struct buffer *buffer; + + if (!data) { + ErrPrint("buffer data == NIL\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + buffer = container_of(data, struct buffer, data); + + if (buffer->state != CREATED) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case DBOX_BUFFER_TYPE_SHM: + if (shmdt(buffer) < 0) { + ErrPrint("shmdt: %s\n", strerror(errno)); + } + break; + case DBOX_BUFFER_TYPE_FILE: + buffer->refcnt--; + if (buffer->refcnt == 0) { + struct fb_info *info; + info = buffer->info; + + buffer->state = DBOX_FB_STATE_DESTROYED; + free(buffer); + + if (info && info->buffer == buffer) { + info->buffer = NULL; + } + } + break; + case DBOX_BUFFER_TYPE_PIXMAP: + default: + ErrPrint("Unknwon buffer type\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + break; + } + + return DBOX_STATUS_ERROR_NONE; +} + +int fb_refcnt(void *data) +{ + struct buffer *buffer; + struct shmid_ds buf; + int ret; + + if (!data) { + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + buffer = container_of(data, struct buffer, data); + + if (buffer->state != CREATED) { + ErrPrint("Invalid handle\n"); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + switch (buffer->type) { + case DBOX_BUFFER_TYPE_SHM: + if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) { + ErrPrint("Error: %s\n", strerror(errno)); + dynamicbox_set_last_status(DBOX_STATUS_ERROR_FAULT); + return DBOX_STATUS_ERROR_FAULT; + } + + ret = buf.shm_nattch; + break; + case DBOX_BUFFER_TYPE_FILE: + ret = buffer->refcnt; + break; + case DBOX_BUFFER_TYPE_PIXMAP: + default: + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + break; + } + + return ret; +} + +const char *fb_id(struct fb_info *info) +{ + return info ? info->id : NULL; +} + +int fb_get_size(struct fb_info *info, int *w, int *h) +{ + if (!info) { + ErrPrint("Handle is not valid\n"); + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + *w = info->w; + *h = info->h; + return DBOX_STATUS_ERROR_NONE; +} + +int fb_size(struct fb_info *info) +{ + if (!info) { + dynamicbox_set_last_status(DBOX_STATUS_ERROR_INVALID_PARAMETER); + return 0; + } + + update_fb_size(info); + + return info->bufsz; +} + +int fb_type(struct fb_info *info) +{ + struct buffer *buffer; + + if (!info) { + return DBOX_BUFFER_TYPE_ERROR; + } + + buffer = info->buffer; + if (!buffer) { + int type = DBOX_BUFFER_TYPE_ERROR; + /*! + * \note + * Try to get this from SCHEMA + */ + if (info->id) { + if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { + type = DBOX_BUFFER_TYPE_FILE; + } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { + /* Unsupported type */ + } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { + type = DBOX_BUFFER_TYPE_SHM; + } + } + + return type; + } + + return buffer->type; +} +/* End of a file */ diff --git a/dynamicbox_viewer/src/file_service.c b/dynamicbox_viewer/src/file_service.c new file mode 100644 index 0000000..12e3000 --- /dev/null +++ b/dynamicbox_viewer/src/file_service.c @@ -0,0 +1,715 @@ +/* + * 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 _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "client.h" +#include "debug.h" +#include "dlist.h" + +#define FILE_SERVICE_PORT 8209 + +#define CRITICAL_SECTION_BEGIN(handle) \ + do { \ + int ret; \ + ret = pthread_mutex_lock(handle); \ + if (ret != 0) { \ + ErrPrint("Failed to lock: %s\n", strerror(ret)); \ + } \ + } while (0) + +#define CRITICAL_SECTION_END(handle) \ + do { \ + int ret; \ + ret = pthread_mutex_unlock(handle); \ + if (ret != 0) { \ + ErrPrint("Failed to unlock: %s\n", strerror(ret)); \ + } \ + } while (0) + +#define CANCEL_SECTION_BEGIN() do { \ + int ret; \ + ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); \ + if (ret != 0) { \ + ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \ + } \ +} while (0) + +#define CANCEL_SECTION_END() do { \ + int ret; \ + ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); \ + if (ret != 0) { \ + ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \ + } \ +} while (0) + +#define CLOSE_PIPE(p) do { \ + int status; \ + status = close(p[PIPE_READ]); \ + if (status < 0) { \ + ErrPrint("close: %s\n", strerror(errno)); \ + } \ + status = close(p[PIPE_WRITE]); \ + if (status < 0) { \ + ErrPrint("close: %s\n", strerror(errno)); \ + } \ +} while (0) + +#define PIPE_READ 0 +#define PIPE_WRITE 1 +#define PIPE_MAX 2 + +#define EVT_END_CH 'c' +#define EVT_CH 'e' + +static struct { + pthread_t file_svc_thid; + pthread_mutex_t file_svc_lock; + int ctrl_pipe[PIPE_MAX]; + int evt_pipe[PIPE_MAX]; + struct dlist *request_list; + int file_service_fd; +} s_info = { + .ctrl_pipe = { -1, -1 }, + .evt_pipe = { -1, -1 }, + .request_list = NULL, + .file_service_fd = -1, +}; + +struct request_item { + char *filename; + char *save_to; + void (*result_cb)(const char *filename, const char *save_to, int ret, void *data); + void *data; + int ret; +}; + +/*! + * File transfer header. + * This must should be shared with client. + */ +struct burst_head { + off_t size; + int flen; + char fname[]; +}; + +struct burst_data { + int size; + char data[]; +}; + +static inline int put_event_ch(int fd, char ch) +{ + int ret; + + ret = write(fd, &ch, sizeof(ch)); + if (ret != sizeof(ch)) { + ErrPrint("write: %s\n", strerror(errno)); + return ret; + } + + return 0; +} + +static inline int get_event_ch(int fd) +{ + int ret; + char ch; + + ret = read(fd, &ch, sizeof(ch)); + if (ret != sizeof(ch)) { + ErrPrint("read: %s\n", strerror(errno)); + return ret; + } + + ret = (int)((unsigned int)ch); + return ret; +} + +static inline int file_service_close(int fd) +{ + return secure_socket_destroy_handle(fd); +} + +static inline int file_service_open(void) +{ + char *addr; + int port; + char *file_addr; + int len; + int fd; + + addr = malloc(strlen(client_addr()) + 1); + if (!addr) { + ErrPrint("Heap: %s\n", strerror(errno)); + return -ENOMEM; + } + + if (sscanf(client_addr(), COM_CORE_REMOTE_SCHEME"%[^:]:%d", addr, &port) != 2) { + ErrPrint("Invalid URL\n"); + free(addr); + return -EINVAL; + } + + len = strlen(COM_CORE_REMOTE_SCHEME); + len+= strlen(addr); + len+= 6; /* Port length? */ + + file_addr = malloc(len); + if (!file_addr) { + ErrPrint("Heap: %s\n", strerror(errno)); + free(addr); + return -ENOMEM; + } + + snprintf(file_addr, len, COM_CORE_REMOTE_SCHEME"%s:%d", addr, FILE_SERVICE_PORT); + DbgPrint("File service: %s\n", file_addr); + fd = secure_socket_create_client(file_addr); + free(file_addr); + free(addr); + + return fd; +} + +/*! + * Service Thread + */ +static void write_item_to_pipe(struct request_item *item, int ret) +{ + item->ret = DBOX_STATUS_ERROR_FAULT; + if (write(s_info.evt_pipe[PIPE_WRITE], &item, sizeof(item)) != sizeof(item)) { + ErrPrint("write: %s\n", strerror(errno)); + free(item->filename); + free(item->save_to); + free(item); + item = NULL; + } +} + +/*! + * Service Thread + */ +static void *file_service_main(void *data) +{ + int ret = 0; + int select_fd; + struct timeval tv; + fd_set set; + int offset; + enum { + RECV_INIT, + RECV_HEADER, + RECV_DATA, + } recv_state; + struct burst_head *head; + struct burst_data *body; + int recvsz; + struct request_item *item; + int file_offset; + int file_fd; + + head = NULL; + item = NULL; + recv_state = RECV_INIT; + select_fd = (s_info.file_service_fd > s_info.ctrl_pipe[PIPE_READ] ? s_info.file_service_fd : s_info.ctrl_pipe[PIPE_READ]) + 1; + while (ret == 0) { + FD_ZERO(&set); + FD_SET(s_info.file_service_fd, &set); + FD_SET(s_info.ctrl_pipe[PIPE_READ], &set); + + tv.tv_sec = 3; + tv.tv_usec = 0; + ret = select(select_fd , &set, NULL, NULL, &tv); + if (ret < 0) { + ret = -errno; + if (errno == EINTR) { + ErrPrint("INTERRUPTED\n"); + ret = 0; + continue; + } + ErrPrint("Error: %s\n", strerror(errno)); + break; + } else if (ret == 0) { + ErrPrint("Timeout\n"); + ret = -ETIMEDOUT; + break; + } + + if (item && FD_ISSET(s_info.file_service_fd, &set)) { + switch (recv_state) { + case RECV_INIT: + if (head == NULL) { + recvsz = sizeof(*head); + + head = malloc(recvsz); + if (!head) { + ErrPrint("Heap: %s\n", strerror(errno)); + ret = DBOX_STATUS_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + offset = 0; + recv_state = RECV_HEADER; + } + case RECV_HEADER: + if (offset < recvsz) { + ret = secure_socket_recv(s_info.file_service_fd, (char *)head + offset, recvsz - offset, NULL); + if (ret > 0) { + offset += ret; + } else { + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = DBOX_STATUS_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + } + + if (offset == sizeof(*head)) { + void *tmp; + + recvsz += head->flen; + + tmp = realloc(head, recvsz); + if (!tmp) { + ErrPrint("Heap: %s\n", strerror(errno)); + + free(head); + head = NULL; + recv_state = RECV_INIT; + + ret = DBOX_STATUS_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + head = tmp; + } else if (offset == recvsz) { + DbgPrint("Filesize: %d, name[%s]\n", head->size, head->fname); + if (strcmp(item->filename, head->fname)) { + ErrPrint("Invalid data sequence (%s <> %s)\n", item->filename, head->fname); + + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = DBOX_STATUS_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + file_fd = open(item->save_to, O_WRONLY|O_CREAT, 0644); + if (file_fd < 0) { + ErrPrint("open: %s\n", strerror(errno)); + free(head); + head = NULL; + recv_state = RECV_INIT; + + ret = DBOX_STATUS_ERROR_IO_ERROR; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + recv_state = RECV_DATA; + body = NULL; + + } else { + ErrPrint("Invalid state\n"); + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + write_item_to_pipe(item, ret); + item = NULL; + } + break; + case RECV_DATA: + if (!body) { + body = malloc(sizeof(*body)); + if (!body) { + free(head); + head = NULL; + recv_state = RECV_INIT; + ret = DBOX_STATUS_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + recvsz = sizeof(*body); + offset = 0; + } + + ret = secure_socket_recv(s_info.file_service_fd, (char *)body + offset, recvsz - offset, NULL); + if (ret > 0) { + offset += ret; + } else { + free(head); + head = NULL; + free(body); + body = NULL; + recv_state = RECV_INIT; + ret = DBOX_STATUS_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + if (offset == sizeof(*body)) { + void *tmp; + + if (body->size < 0) { + ErrPrint("body->size: %d\n", body->size); + free(head); + head = NULL; + free(body); + body = NULL; + recv_state = RECV_INIT; + ret = DBOX_STATUS_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + + recvsz += body->size; + + tmp = realloc(body, recvsz); + if (!tmp) { + ErrPrint("Heap: %s\n", strerror(errno)); + free(head); + head = NULL; + + free(body); + body = NULL; + recv_state = RECV_INIT; + + ret = DBOX_STATUS_ERROR_OUT_OF_MEMORY; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + } else if (offset == recvsz) { + /* Flush this to the file */ + ret = write(file_fd, body->data, body->size); + if (ret < 0) { + ErrPrint("write: %s\n", strerror(errno)); + free(head); + head = NULL; + + free(body); + body = NULL; + recv_state = RECV_INIT; + + ret = DBOX_STATUS_ERROR_IO_ERROR; + write_item_to_pipe(item, ret); + item = NULL; + break; + } else { + if (body->size != ret) { + DbgPrint("Body is not flushed correctly: %d, %d\n", ret, body->size); + ret = body->size; + } + + file_offset += ret; + if (file_offset == head->size) { + if (close(file_fd) < 0) { + ErrPrint("close: %s\n", strerror(errno)); + } + ret = DBOX_STATUS_ERROR_NONE; + write_item_to_pipe(item, ret); + item = NULL; + } + } + + free(body); + body = NULL; + + free(head); + head = NULL; + + recv_state = RECV_INIT; + } else { + ErrPrint("Invalid state\n"); + + ret = -EFAULT; + free(body); + body = NULL; + free(head); + head = NULL; + recv_state = RECV_INIT; + + ret = DBOX_STATUS_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + } + break; + default: + ErrPrint("Unknown event: %d\n", recv_state); + ret = DBOX_STATUS_ERROR_FAULT; + write_item_to_pipe(item, ret); + item = NULL; + break; + } + } else if (item == NULL && recv_state == RECV_INIT && FD_ISSET(s_info.ctrl_pipe[PIPE_READ], &set)) { + int ch; + struct dlist *l; + + /* Only if the recv state is not changed, we can get next request item */ + ch = get_event_ch(s_info.ctrl_pipe[PIPE_READ]); + if (ch == EVT_END_CH) { + DbgPrint("Service thread is canceled\n"); + break; + } + + CRITICAL_SECTION_BEGIN(&s_info.file_svc_lock); + l = dlist_nth(s_info.request_list, 0); + item = dlist_data(l); + s_info.request_list = dlist_remove(s_info.request_list, l); + CRITICAL_SECTION_END(&s_info.file_svc_lock); + } + } + + return (void *)ret; +} + +/* Master */ +static gboolean evt_cb(GIOChannel *src, GIOCondition cond, gpointer data) +{ + int fd; + struct request_item *item; + + fd = g_io_channel_unix_get_fd(src); + + if (!(cond & G_IO_IN)) { + DbgPrint("Client is disconencted\n"); + return FALSE; + } + + if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) { + DbgPrint("Client connection is lost\n"); + return FALSE; + } + + if (read(fd, &item, sizeof(item)) != sizeof(item)) { + ErrPrint("read: %s\n", strerror(errno)); + } else { + if (item->result_cb) { + item->result_cb(item->filename, item->save_to, item->ret, item->data); + } + + free(item->filename); + free(item->save_to); + free(item); + } + + return TRUE; +} + +int file_service_send_request(const char *filename, const char *save_to, void (*result_cb)(const char *filename, const char *save_to, int ret, void *data), void *data) +{ + struct request_item *item; + + item = malloc(sizeof(*item)); + if (!item) { + ErrPrint("Heap: %s\n", strerror(errno)); + return -ENOMEM; + } + + item->filename = strdup(filename); + if (!item->filename) { + ErrPrint("Heap: %s\n", strerror(errno)); + free(item); + return -ENOMEM; + } + + item->save_to = strdup(save_to); + if (!item->save_to) { + ErrPrint("Heap: %s\n", strerror(errno)); + free(item->filename); + free(item); + return -ENOMEM; + } + + item->result_cb = result_cb; + item->data = data; + + CRITICAL_SECTION_BEGIN(&s_info.file_svc_lock); + s_info.request_list = dlist_append(s_info.request_list, item); + CRITICAL_SECTION_END(&s_info.file_svc_lock); + return 0; +} + +int file_service_init(void) +{ + int status; + GIOChannel *gio; + guint id; + + if (strncmp(client_addr(), COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { + return 0; + } + + s_info.file_service_fd = file_service_open(); + if (s_info.file_service_fd < 0) { + return -EFAULT; + } + + if (pipe2(s_info.ctrl_pipe, O_NONBLOCK | O_CLOEXEC) < 0) { + ErrPrint("file service: %s\n", strerror(errno)); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + if (pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC) < 0) { + ErrPrint("file service: %s\n", strerror(errno)); + CLOSE_PIPE(s_info.ctrl_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + status = pthread_mutex_init(&s_info.file_svc_lock, NULL); + if (status != 0) { + ErrPrint("Mutex: %s\n", strerror(status)); + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + gio = g_io_channel_unix_new(s_info.evt_pipe[PIPE_READ]); + if (!gio) { + ErrPrint("io channel new\n"); + status = pthread_mutex_destroy(&s_info.file_svc_lock); + if (status != 0) { + ErrPrint("destroy: %s\n", strerror(status)); + } + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EFAULT; + } + + g_io_channel_set_close_on_unref(gio, FALSE); + + id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)evt_cb, NULL); + if (id <= 0) { + GError *err = NULL; + ErrPrint("Failed to add IO watch\n"); + g_io_channel_shutdown(gio, TRUE, &err); + if (err) { + ErrPrint("Shutdown: %s\n", err->message); + g_error_free(err); + } + g_io_channel_unref(gio); + + status = pthread_mutex_destroy(&s_info.file_svc_lock); + if (status != 0) { + ErrPrint("destroy: %s\n", strerror(status)); + } + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + return -EIO; + } + + status = pthread_create(&s_info.file_svc_thid, NULL, file_service_main, NULL); + if (status != 0) { + GError *err = NULL; + ErrPrint("Failed to add IO watch\n"); + g_io_channel_shutdown(gio, TRUE, &err); + if (err) { + ErrPrint("Shutdown: %s\n", err->message); + g_error_free(err); + } + g_io_channel_unref(gio); + + ErrPrint("file service: %s\n", strerror(status)); + CLOSE_PIPE(s_info.ctrl_pipe); + CLOSE_PIPE(s_info.evt_pipe); + file_service_close(s_info.file_service_fd); + s_info.file_service_fd = -1; + + status = pthread_mutex_destroy(&s_info.file_svc_lock); + if (status != 0) { + ErrPrint("destroy: %s\n", strerror(status)); + } + + return -EFAULT; + } + + g_io_channel_unref(gio); + return 0; +} + +int file_service_fini(void) +{ + void *svc_ret; + int ret; + + if (strncmp(client_addr(), COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { + return 0; + } + + (void)put_event_ch(s_info.ctrl_pipe[PIPE_WRITE], EVT_END_CH); + + ret = pthread_join(s_info.file_svc_thid, &svc_ret); + if (ret != 0) { + ErrPrint("join: %s\n", strerror(ret)); + } else { + DbgPrint("file svc returns: %d\n", (int)svc_ret); + } + + ret = pthread_mutex_destroy(&s_info.file_svc_lock); + if (ret != 0) { + ErrPrint("destroy: %s\n", strerror(ret)); + } + + CLOSE_PIPE(s_info.evt_pipe); + CLOSE_PIPE(s_info.ctrl_pipe); + + return 0; +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/master_rpc.c b/dynamicbox_viewer/src/master_rpc.c new file mode 100644 index 0000000..8e8ea0e --- /dev/null +++ b/dynamicbox_viewer/src/master_rpc.c @@ -0,0 +1,318 @@ +/* + * 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 +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "debug.h" +#include "dlist.h" +#include "dynamicbox.h" +#include "dynamicbox_internal.h" +#include "master_rpc.h" +#include "client.h" +#include "util.h" + +#define DEFAULT_TTL 10 +#define REQUEST_DELAY 10 + +struct command { + int ttl; + struct packet *packet; + dynamicbox_h handler; + void (*ret_cb)(dynamicbox_h handler, const struct packet *result, void *data); + void *data; + enum { + TYPE_ACK, + TYPE_NOACK + } type; +}; + +int errno; + +static struct { + guint cmd_timer; + struct dlist *cmd_list; +} s_info = { + .cmd_timer = 0, + .cmd_list = NULL, +}; + +static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data); + +static inline struct command *pop_command(void) +{ + struct dlist *l; + struct command *command; + + l = dlist_nth(s_info.cmd_list, 0); + if (!l) { + return NULL; + } + + command = dlist_data(l); + s_info.cmd_list = dlist_remove(s_info.cmd_list, l); + return command; +} + +static inline struct command *create_command(dynamicbox_h handler, struct packet *packet) +{ + struct command *command; + + command = malloc(sizeof(*command)); + if (!command) { + ErrPrint("Failed to allocate mem for command\n"); + return NULL; + } + + command->handler = dbox_ref(handler); + command->packet = packet_ref(packet); + return command; +} + +static inline void destroy_command(struct command *command) +{ + packet_unref(command->packet); + dbox_unref(command->handler, 1); + free(command); +} + +static gboolean cmd_consumer(gpointer user_data) +{ + struct command *command; + + command = pop_command(); + if (!command) { + s_info.cmd_timer = 0; + return FALSE; + } + + /*! + * \NOTE: + * Item will be deleted in the "done_cb" + * + * item->param be release by the g_dbus_proxy_call + * so to use it again from the done_cb function, + * increate the reference counter of the item->param + */ + if (command->type == TYPE_NOACK) { + if (com_core_packet_send_only(client_fd(), command->packet) < 0) { + ErrPrint("Failed to send a packet to master\n"); + } + + destroy_command(command); + } else { + if (com_core_packet_async_send(client_fd(), command->packet, 0u, done_cb, command) < 0) { + ErrPrint("Failed to send a packet to master\n"); + if (command->ret_cb) { + command->ret_cb(command->handler, NULL, command->data); + } + destroy_command(command); + } + } + return TRUE; +} + +static inline void prepend_command(struct command *command) +{ + s_info.cmd_list = dlist_prepend(s_info.cmd_list, command); + master_rpc_check_and_fire_consumer(); +} + +void master_rpc_check_and_fire_consumer(void) +{ + if (!s_info.cmd_list || s_info.cmd_timer || client_fd() < 0) { + return; + } + + s_info.cmd_timer = g_timeout_add(REQUEST_DELAY, cmd_consumer, NULL); + if (!s_info.cmd_timer) { + ErrPrint("Failed to add timer\n"); + } +} + +static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data) +{ + struct command *command; + int ret; + + command = data; + + if (!packet) { + /*! \NOTE: + * Release resource even if + * we failed to finish the method call + */ + command->ttl--; + if (command->ttl > 0) { + prepend_command(command); + return 0; + } + + goto out; + } + + if (packet_get(packet, "i", &ret) != 1) { + ErrPrint("Invalid result packet\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + +out: + if (command->ret_cb) { + command->ret_cb(command->handler, packet, command->data); + } + + destroy_command(command); + return 0; +} + +static inline void push_command(struct command *command) +{ + s_info.cmd_list = dlist_append(s_info.cmd_list, command); + master_rpc_check_and_fire_consumer(); +} + +/*! + * \note + * "handler" could be NULL + */ +int master_rpc_async_request(dynamicbox_h handler, struct packet *packet, int urgent, void (*ret_cb)(dynamicbox_h handler, const struct packet *result, void *data), void *data) +{ + struct command *command; + + command = create_command(handler, packet); + if (!command) { + ErrPrint("Failed to create a command\n"); + packet_unref(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + command->ret_cb = ret_cb; + command->data = data; + command->ttl = DEFAULT_TTL; + command->type = TYPE_ACK; + + if (urgent) { + prepend_command(command); + } else { + push_command(command); + } + + packet_unref(packet); + return DBOX_STATUS_ERROR_NONE; +} + +int master_rpc_request_only(dynamicbox_h handler, struct packet *packet) +{ + struct command *command; + + command = create_command(handler, packet); + if (!command) { + ErrPrint("Failed to create a command\n"); + packet_unref(packet); + return DBOX_STATUS_ERROR_FAULT; + } + + command->ret_cb = NULL; + command->data = NULL; + command->ttl = 0; + command->type = TYPE_NOACK; + + push_command(command); + packet_unref(packet); + return DBOX_STATUS_ERROR_NONE; +} + +int master_rpc_clear_fault_package(const char *pkgname) +{ + struct dlist *l; + struct dlist *n; + struct command *command; + + if (!pkgname) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + dlist_foreach_safe(s_info.cmd_list, l, n, command) { + if (!command->handler) { + continue; + } + + if (!strcmp(command->handler->common->pkgname, pkgname)) { + s_info.cmd_list = dlist_remove(s_info.cmd_list, l); + if (command->ret_cb) { + command->ret_cb(command->handler, NULL, command->data); + } + + destroy_command(command); + } + } + + return 0; +} + +int master_rpc_clear_all_request(void) +{ + struct command *command; + struct dlist *l; + struct dlist *n; + + dlist_foreach_safe(s_info.cmd_list, l, n, command) { + s_info.cmd_list = dlist_remove(s_info.cmd_list, l); + + if (command->ret_cb) { + command->ret_cb(command->handler, NULL, command->data); + } + + destroy_command(command); + } + + return 0; +} + +int master_rpc_sync_request(struct packet *packet) +{ + struct packet *result; + int ret; + + result = com_core_packet_oneshot_send(client_addr(), packet, 0.0f); + if (result) { + if (packet_get(result, "i", &ret) != 1) { + ErrPrint("Invalid result packet\n"); + ret = DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + packet_unref(result); + } else { + ErrPrint("Failed to send a sync request\n"); + ret = DBOX_STATUS_ERROR_FAULT; + } + + packet_unref(packet); + return ret; +} + +/* End of a file */ diff --git a/dynamicbox_viewer/src/util.c b/dynamicbox_viewer/src/util.c new file mode 100644 index 0000000..59204ec --- /dev/null +++ b/dynamicbox_viewer/src/util.c @@ -0,0 +1,150 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include /* For error code */ + +#include "debug.h" +#include "util.h" + +int errno; +#if defined(_USE_ECORE_TIME_GET) +static struct { + clockid_t type; +} s_info = { + .type = CLOCK_MONOTONIC, +}; +#endif + +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 DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + check_ptr ++; + } + + return 0; +} + +double util_timestamp(void) +{ +#if defined(_USE_ECORE_TIME_GET) + struct timespec ts; + + do { + if (clock_gettime(s_info.type, &ts) == 0) { + return ts.tv_sec + ts.tv_nsec / 1000000000.0f; + } + + ErrPrint("%d: %s\n", s_info.type, strerror(errno)); + if (s_info.type == CLOCK_MONOTONIC) { + s_info.type = CLOCK_REALTIME; + } else if (s_info.type == CLOCK_REALTIME) { + struct timeval tv; + if (gettimeofday(&tv, NULL) < 0) { + ErrPrint("gettimeofday: %s\n", strerror(errno)); + break; + } + + return tv.tv_sec + tv.tv_usec / 1000000.0f; + } + } while (1); + + return 0.0f; +#else + struct timeval tv; + + if (gettimeofday(&tv, NULL) < 0) { + ErrPrint("gettimeofday: %s\n", strerror(errno)); + tv.tv_sec = 0; + tv.tv_usec = 0; + } + + return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f; +#endif +} + +const char *util_basename(const char *name) +{ + int length; + length = name ? strlen(name) : 0; + if (!length) { + return "."; + } + + while (--length > 0 && name[length] != '/'); + + return length <= 0 ? name : name + length + (name[length] == '/'); +} + +const char *util_uri_to_path(const char *uri) +{ + int len; + + len = strlen(SCHEMA_FILE); + if (strncasecmp(uri, SCHEMA_FILE, len)) { + return NULL; + } + + return uri + len; +} + +int util_unlink(const char *filename) +{ + char *descfile; + int desclen; + int ret; + + if (!filename) { + return DBOX_STATUS_ERROR_INVALID_PARAMETER; + } + + desclen = strlen(filename) + 6; /* .desc */ + descfile = malloc(desclen); + if (!descfile) { + ErrPrint("Heap: %s\n", strerror(errno)); + return DBOX_STATUS_ERROR_OUT_OF_MEMORY; + } + + ret = snprintf(descfile, desclen, "%s.desc", filename); + if (ret < 0) { + ErrPrint("Error: %s\n", strerror(errno)); + free(descfile); + return DBOX_STATUS_ERROR_FAULT; + } + + (void)unlink(descfile); + free(descfile); + (void)unlink(filename); + + return DBOX_STATUS_ERROR_NONE; +} + +/* End of a file */ diff --git a/include/dlist.h b/include/dlist.h deleted file mode 100644 index cd1a421..0000000 --- a/include/dlist.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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); (l) && ((data) = dlist_data(l)); (l) = dlist_next(l)) - -#define dlist_foreach_safe(list, l, n, data) \ - for ((l) = (list), (n) = dlist_next(l); \ - (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 deleted file mode 100644 index 2e00248..0000000 --- a/include/livebox.h +++ /dev/null @@ -1,1753 +0,0 @@ -/* - * 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_H -#define __LIVEBOX_H - -#ifdef __cplusplus -extern "C" { -#endif - -/*! - * \addtogroup CAPI_LIVEBOX_VIEWER_MODULE - * \{ - */ - -/*! - * \brief - * Structure for a Livebox instance - */ -struct livebox; - -/*! - * \brief - * Use the default update period which is defined in the package manifest file of a livebox. - */ -#define DEFAULT_PERIOD -1.0f - -/*! - * \brief - * Mouse & Key event for buffer type Livebox or PD - * Viewer should send these events to livebox. - */ -enum content_event_type { - CONTENT_EVENT_MOUSE_DOWN = 0x00000001, /*!< LB mouse down event for livebox */ - CONTENT_EVENT_MOUSE_UP = 0x00000002, /*!< LB mouse up event for livebox */ - CONTENT_EVENT_MOUSE_MOVE = 0x00000004, /*!< LB mouse move event for livebox */ - CONTENT_EVENT_MOUSE_ENTER = 0x00000008, /*!< LB mouse enter event for livebox */ - CONTENT_EVENT_MOUSE_LEAVE = 0x00000010, /*!< LB mouse leave event for livebox */ - CONTENT_EVENT_MOUSE_SET = 0x00000020, /*!< LB mouse set auto event for livebox */ - CONTENT_EVENT_MOUSE_UNSET = 0x00000040, /*!< LB mouse unset auto event for livebox */ - - CONTENT_EVENT_KEY_DOWN = 0x00000001, /*!< LB key press */ - CONTENT_EVENT_KEY_UP = 0x00000002, /*!< LB key release */ - CONTENT_EVENT_KEY_FOCUS_IN = 0x00000008, /*!< LB key focused in */ - CONTENT_EVENT_KEY_FOCUS_OUT = 0x00000010, /*!< LB key focused out */ - CONTENT_EVENT_KEY_SET = 0x00000020, /*!< LB Key, start feeding event by master */ - CONTENT_EVENT_KEY_UNSET = 0x00000040, /*!< LB key, stop feeding event by master */ - - CONTENT_EVENT_ON_SCROLL = 0x00000080, /*!< LB On scrolling */ - CONTENT_EVENT_ON_HOLD = 0x00000100, /*!< LB On holding */ - CONTENT_EVENT_OFF_SCROLL = 0x00000200, /*!< LB Stop scrolling */ - CONTENT_EVENT_OFF_HOLD = 0x00000400, /*!< LB Stop holding */ - - CONTENT_EVENT_KEY_MASK = 0x80000000, - CONTENT_EVENT_MOUSE_MASK = 0x20000000, - CONTENT_EVENT_PD_MASK = 0x10000000, - CONTENT_EVENT_LB_MASK = 0x40000000, - - LB_MOUSE_ON_SCROLL = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_SCROLL, /*!< Mouse event occurs while scrolling */ - LB_MOUSE_ON_HOLD = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_HOLD, /*!< Mouse event occurs on holding */ - LB_MOUSE_OFF_SCROLL = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_SCROLL, /*!< Scrolling stopped */ - LB_MOUSE_OFF_HOLD = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_HOLD, /*!< Holding stopped */ - - LB_MOUSE_DOWN = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_DOWN, /*!< Mouse down on the livebox */ - LB_MOUSE_UP = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UP, /*!< Mouse up on the livebox */ - LB_MOUSE_MOVE = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_MOVE, /*!< Move move on the livebox */ - LB_MOUSE_ENTER = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_ENTER, /*!< Mouse enter to the livebox */ - LB_MOUSE_LEAVE = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_LEAVE, /*!< Mouse leave from the livebox */ - LB_MOUSE_SET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_SET, /*!< Mouse event, start feeding event by master */ - LB_MOUSE_UNSET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UNSET, /*!< Mouse event, stop feeding event by master */ - - PD_MOUSE_ON_SCROLL = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_SCROLL, /*!< Mouse event occurs while scrolling */ - PD_MOUSE_ON_HOLD = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_HOLD, /*!< Mouse event occurs on holding */ - PD_MOUSE_OFF_SCROLL = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_SCROLL, /*!< Scrolling stopped */ - PD_MOUSE_OFF_HOLD = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_HOLD, /*!< Holding stopped */ - - PD_MOUSE_DOWN = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_DOWN, /*!< Mouse down on the PD */ - PD_MOUSE_UP = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UP, /*!< Mouse up on the PD */ - PD_MOUSE_MOVE = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_MOVE, /*!< Mouse move on the PD */ - PD_MOUSE_ENTER = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_ENTER, /*!< Mouse enter to the PD */ - PD_MOUSE_LEAVE = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_LEAVE, /*!< Mouse leave from the PD */ - PD_MOUSE_SET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_SET, /*!< Mouse event, start feeding event by master */ - PD_MOUSE_UNSET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UNSET, /*!< Mouse event, stop feeding event by master */ - - LB_KEY_DOWN = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_DOWN, /*!< Key down on the livebox */ - LB_KEY_UP = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UP, /*!< Key up on the livebox */ - LB_KEY_SET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_SET, /*!< Key event, start feeding event by master */ - LB_KEY_UNSET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UNSET, /*!< Key event, stop feeding event by master */ - LB_KEY_FOCUS_IN = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_IN, /*!< Key event, focus in */ - LB_KEY_FOCUS_OUT = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_OUT, /*!< Key event, foucs out */ - - PD_KEY_DOWN = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_DOWN, /*!< Key down on the livebox */ - PD_KEY_UP = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UP, /*!< Key up on the livebox */ - PD_KEY_SET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_SET, /*!< Key event, start feeding event by master */ - PD_KEY_UNSET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UNSET, /*!< Key event, stop feeding event by master */ - PD_KEY_FOCUS_IN = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_IN, /*!< Key event, focus in */ - PD_KEY_FOCUS_OUT = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_OUT, /*!< Key event, focus out */ - - CONTENT_EVENT_MAX = 0xFFFFFFFF -}; - -/*! - * \brief - * Accessibility event for buffer type Livebox or PD. - * These event set are sync'd with Tizen accessibility event set. - */ -enum access_event_type { - ACCESS_EVENT_PD_MASK = 0x10000000, - ACCESS_EVENT_LB_MASK = 0x20000000, - - ACCESS_EVENT_HIGHLIGHT = 0x00000100, /*!< LB accessibility: Hightlight a object */ - ACCESS_EVENT_HIGHLIGHT_NEXT = 0x00000200, /*!< LB accessibility: Set highlight to next object */ - ACCESS_EVENT_HIGHLIGHT_PREV = 0x00000400, /*!< LB accessibility: Set highlight to prev object */ - ACCESS_EVENT_UNHIGHLIGHT = 0x00000800, /*!< LB accessibility unhighlight */ - ACCESS_EVENT_ACTIVATE = 0x00001000, /*!< LB accessibility activate */ - ACCESS_EVENT_ACTION_DOWN = 0x00010000, /*!< LB accessibility value changed */ - ACCESS_EVENT_ACTION_UP = 0x00020000, /*!< LB accessibility value changed */ - ACCESS_EVENT_SCROLL_DOWN = 0x00100000, /*!< LB accessibility scroll down */ - ACCESS_EVENT_SCROLL_MOVE = 0x00200000, /*!< LB accessibility scroll move */ - ACCESS_EVENT_SCROLL_UP = 0x00400000, /*!< LB accessibility scroll up */ - - LB_ACCESS_HIGHLIGHT = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_HIGHLIGHT, /*!< Access event - Highlight an object in the livebox */ - LB_ACCESS_HIGHLIGHT_NEXT = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_HIGHLIGHT_NEXT, /*!< Access event - Move highlight to the next object in a livebox */ - LB_ACCESS_HIGHLIGHT_PREV = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_HIGHLIGHT_PREV, /*!< Access event - Move highlight to the prev object in a livebox */ - LB_ACCESS_UNHIGHLIGHT = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_UNHIGHLIGHT, /*!< Access event - Delete highlight from the livebox */ - LB_ACCESS_ACTIVATE = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_ACTIVATE, /*!< Access event - Launch or activate the highlighted object */ - LB_ACCESS_ACTION_DOWN = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_ACTION_DOWN, /*!< Access event - down */ - LB_ACCESS_ACTION_UP = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_ACTION_UP, /*!< Access event - up */ - LB_ACCESS_SCROLL_DOWN = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_SCROLL_DOWN, /*!< Access event - scroll down */ - LB_ACCESS_SCROLL_MOVE = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_SCROLL_MOVE, /*!< Access event - scroll move */ - LB_ACCESS_SCROLL_UP = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_SCROLL_UP, /*!< Access event - scroll up */ - - PD_ACCESS_HIGHLIGHT = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_HIGHLIGHT, /*!< Access event - Highlight an object in the PD */ - PD_ACCESS_HIGHLIGHT_NEXT = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_HIGHLIGHT_NEXT, /*!< Access event - Move highlight to the next object in a PD */ - PD_ACCESS_HIGHLIGHT_PREV = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_HIGHLIGHT_PREV, /*!< Access event - Move highlight to the prev object in a PD */ - PD_ACCESS_UNHIGHLIGHT = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_UNHIGHLIGHT, /*!< Access event - Delet highlight from the PD */ - PD_ACCESS_ACTIVATE = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_ACTIVATE, /*!< Access event - Launch or activate the highlighted object */ - PD_ACCESS_ACTION_DOWN = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_ACTION_DOWN, /*!< Access event - down */ - PD_ACCESS_ACTION_UP = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_ACTION_UP, /*!< Access event - up */ - PD_ACCESS_SCROLL_DOWN = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_SCROLL_DOWN, /*!< Access event - scroll down */ - PD_ACCESS_SCROLL_MOVE = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_SCROLL_MOVE, /*!< Access event - scroll move */ - PD_ACCESS_SCROLL_UP = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_SCROLL_UP /*!< Access event - scroll up */ -}; - -/*! - * \brief - * Livebox LB content type - */ -enum livebox_lb_type { - LB_TYPE_IMAGE = 0x01, /*!< Contents of a livebox is based on the image file */ - LB_TYPE_BUFFER = 0x02, /*!< Contents of a livebox is based on canvas buffer(shared) */ - LB_TYPE_TEXT = 0x04, /*!< Contents of a livebox is based on formatted text file */ - LB_TYPE_PIXMAP = 0x08, /*!< Contens of a livebox is shared by the pixmap(depends on X) */ - - LB_TYPE_INVALID = 0xFF -}; - -/*! - * \brief - * Livebox PD content type - */ -enum livebox_pd_type { - PD_TYPE_BUFFER = 0x01, /*!< Contents of a PD is based on canvas buffer(shared) */ - PD_TYPE_TEXT = 0x02, /*!< Contents of a PD is based on formatted text file */ - PD_TYPE_PIXMAP = 0x04, /*!< Contents of a livebox is shared by the pixmap(depends on X) */ - - PD_TYPE_INVALID = 0xFF -}; - -/*! - * \brief - * Livebox event type. - * These event will be sent from the provider. - */ -enum livebox_event_type { /*!< livebox_event_handler_set Event list */ - LB_EVENT_LB_UPDATED, /*!< Contents of the given livebox is updated */ - LB_EVENT_PD_UPDATED, /*!< Contents of the given pd is updated */ - - LB_EVENT_CREATED, /*!< A new livebox is created */ - LB_EVENT_DELETED, /*!< A livebox is deleted */ - - LB_EVENT_GROUP_CHANGED, /*!< Group (Cluster/Sub-cluster) information is changed */ - LB_EVENT_PINUP_CHANGED, /*!< PINUP status is changed */ - LB_EVENT_PERIOD_CHANGED, /*!< Update period is changed */ - - LB_EVENT_LB_SIZE_CHANGED, /*!< Livebox size is changed */ - LB_EVENT_PD_SIZE_CHANGED, /*!< PD size is changed */ - - LB_EVENT_PD_CREATED, /*!< If a PD is created even if you didn't call the livebox_create_pd API */ - LB_EVENT_PD_DESTROYED, /*!< If a PD is destroyed even if you didn't call the livebox_destroy_pd API */ - - LB_EVENT_HOLD_SCROLL, /*!< If the screen should be freezed */ - LB_EVENT_RELEASE_SCROLL, /*!< If the screen can be scrolled */ - - LB_EVENT_LB_UPDATE_BEGIN, /*!< Livebox LB content update is started */ - LB_EVENT_LB_UPDATE_END, /*!< Livebox LB content update is finished */ - - LB_EVENT_PD_UPDATE_BEGIN, /*!< Livebox PD content update is started */ - LB_EVENT_PD_UPDATE_END, /*!< Livebox PD content update is finished */ - - LB_EVENT_UPDATE_MODE_CHANGED, /*!< Livebox Update mode is changed */ - - LB_EVENT_REQUEST_CLOSE_PD, /*!< Livebox requests to close the PD */ - - LB_EVENT_IGNORED /*!< Request is ignored */ -}; - -enum livebox_option_type { - LB_OPTION_MANUAL_SYNC, /*!< Sync manually */ - LB_OPTION_FRAME_DROP_FOR_RESIZE, /*!< Drop frames while resizing */ - LB_OPTION_SHARED_CONTENT, /*!< Use only one real instance for multiple fake instances if user creates it using same content */ - - LB_OPTION_ERROR = 0xFFFFFFFF /*!< To specify the size of this enumeration type */ -}; - -enum livebox_fault_type { - LB_FAULT_DEACTIVATED, /*!< Livebox is deactivated by its fault operation */ - LB_FAULT_PROVIDER_DISCONNECTED /*!< Provider is disconnected */ -}; - -/*! - * \brief - * Must be sync'd with the provider - */ -enum livebox_visible_state { - LB_SHOW = 0x00, /*!< Livebox is shown. Default state */ - LB_HIDE = 0x01, /*!< Livebox is hidden, Update timer will not be freezed. but you cannot receive any updates events. */ - - LB_HIDE_WITH_PAUSE = 0x02, /*!< Livebix is hidden, it will pause the update timer, but if a livebox updates its contents, update event will be triggered */ - - LB_VISIBLE_ERROR = 0xFFFFFFFF /*!< To specify the size of this enumeration type */ -}; - -/*! - * \brief - * TEXT type livebox contents handling opertators. - */ -struct livebox_script_operators { - int (*update_begin)(struct livebox *handle); /*!< Content parser is started */ - int (*update_end)(struct livebox *handle); /*!< Content parser is finished */ - - /*! - * \brief - * Listed functions will be called when parser meets each typed content - */ - int (*update_text)(struct livebox *handle, const char *id, const char *part, const char *data); /*!< Update text content */ - int (*update_image)(struct livebox *handle, const char *id, const char *part, const char *data, const char *option); /*!< Update image content */ - int (*update_script)(struct livebox *handle, const char *id, const char *new_id, const char *part, const char *file, const char *group); /*!< Update script content */ - int (*update_signal)(struct livebox *handle, const char *id, const char *emission, const char *signal); /*!< Update signal */ - int (*update_drag)(struct livebox *handle, const char *id, const char *part, double dx, double dy); /*!< Update drag info */ - int (*update_info_size)(struct livebox *handle, const char *id, int w, int h); /*!< Update content size */ - int (*update_info_category)(struct livebox *handle, const char *id, const char *category); /*!< Update content category info */ - int (*update_access)(struct livebox *handle, const char *id, const char *part, const char *text, const char *option); /*!< Update access information */ - int (*operate_access)(struct livebox *handle, const char *id, const char *part, const char *operation, const char *option); /*!< Update access operation */ - int (*update_color)(struct livebox *handle, const char *id, const char *part, const char *data); /*!< Update color */ -}; - -/*! - * \brief Prototype of the return callback of every async functions - * \details N/A - * \remarks N/A - * \param[in] handle Handle of the livebox instance - * \param[in] ret Result status of operation. LB_STATUS_XXX defined from liblivebox-service - * \param[in] data data for result callback - * \return void - * \pre N/A - * \post N/A - * \see livebox_add - * \see livebox_add_with_size - * \see livebox_del - * \see livebox_activate - * \see livebox_resize - * \see livebox_set_group - * \see livebox_set_period - * \see livebox_access_event - * \see livebox_set_pinup - * \see livebox_create_pd - * \see livebox_create_pd_with_position - * \see livebox_destroy_pd - * \see livebox_emit_text_signal - * \see livebox_acquire_pd_pixmap - * \see livebox_acquire_lb_pixmap - * \see livebox_set_update_mode - */ -typedef void (*ret_cb_t)(struct livebox *handle, int ret, void *data); - -/*! - * \brief Initialize the livebox system - * \details N/A - * \remarks - * This API uses get/setenv APIs. - * Those APIs are not thread-safe. - * So you have to consider to use the livebox_init_with_options instead of this if you are developing multi-threaded viewer. - * \param[in] disp If you have X Display connection object already, you can re-use it. but you should care its life cycle. - * It must be alive before call the livebox_fini - * \return int - * \retval LB_STATUS_SUCCESS if success - * \pre N/A - * \post N/A - * \see livebox_fini - * \see livebox_init_with_options - */ -extern int livebox_init(void *disp); - -/*! - * \brief Initialize the livebox system with some options - * \details livebox_init function uses environment value to initiate some configurable values - * But some application doesn't want to use the env value. - * For them, this API will give a chance to set default options using given arguments - * \remarks N/A - * \param[in] disp if this display is NULL, the library will try to acquire a new connection with X - * \param[in] prevent_overwrite If the content of image type livebox is updated, don't overwrite it(1) or overwrite old file(0) - * \param[in] event_filter If the next event comes in this period, ignore it. It is too fast to processing it in time. - * \param[in] use_thread Use the receive thread. - * \return int Integer, Livebox status code - * \retval LB_STATUS_SUCCESS if success - * \pre N/A - * \post N/A - * \see livebox_init - * \see livebox_fini - */ -extern int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread); - -/*! - * \brief Finalize the livebox system - * \details N/A - * \remarks N/A - * \return int - * \retval LB_STATUS_SUCCES if success - * \retval LB_STATUS_ERROR_INVALID if livebox_init is not called. - * \pre N/A - * \post N/A - * \see livebox_init - * \see livebox_init_with_options - */ -extern int livebox_fini(void); - -/*! - * \brief Notify the status of client to the provider. "it is paused". - * \details N/A - * \remarks N/A - * \return int - * \retval LB_STATUS_SUCCESS if success - * \retval LB_STATUS_ERROR_FAULT if it failed to send state(paused) info - * \pre N/A - * \post N/A - * \see livebox_client_resumed - */ -extern int livebox_client_paused(void); - -/*! - * \brief Notify the status of client to the provider. "it is resumed". - * \details N/A - * \remarks N/A - * \return int - * \retval LB_STATUS_SUCCESS if success - * \retval LB_STATUS_ERROR_FAULT if it failed to send state(resumed) info - * \pre N/A - * \post N/A - * \see livebox_client_paused - */ -extern int livebox_client_resumed(void); - -/*! - * \brief Add a new livebox - * \details N/A - * \remarks - * Even though you get the livebox handle from return value of this function, - * it is not matured before return callback called. - * You have to use the handle after get the return callback with "ret == LB_STATUS_SUCCESS" - * \param[in] pkgname Livebox Id - * \param[in] content Will be passed to the livebox instance. - * \param[in] cluster Main group - * \param[in] category Sub group - * \param[in] period Update period. if you set DEFAULT_PERIOD, the provider will use the default period which is described in the manifest. - * \param[in] cb After send the request to the provider, its result will be passed - * \param[in] data - * \return handle - * \retval NULL if it fails to add a new instance - * \retval handle livebox handle - * \pre N/A - * \post - * \see ret_cb_t - * \see livebox_add_with_size - */ -extern struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, ret_cb_t cb, void *data); - -/*! - * \brief Add a new livebox - * \details - * If the screen size if "1280x720" - * Below size lists are used for default. - * Or you can find the default sizes in pixel from /usr/share/data-provider-master/resolution.ini - * Size types are defined from the liblivebox-service package. (livebox-service.h) - * - * Normal mode livebox - * 1x1=175x175, LB_SIZE_TYPE_1x1 - * 2x1=354x175, LB_SIZE_TYPE_2x1 - * 2x2=354x354, LB_SIZE_TYPE_2x2 - * 4x1=712x175, LB_SIZE_TYPE_4x1 - * 4x2=712x354, LB_SIZE_TYPE_4x2 - * 4x4=712x712, LB_SIZE_TYPE_4x4 - * - * Extended sizes - * 4x3=712x533, LB_SIZE_TYPE_4x3 - * 4x5=712x891, LB_SIZE_TYPE_4x5 - * 4x6=712x1070, LB_SIZE_TYPE_4x6 - * - * Easy mode livebox - * 21x21=224x215, LB_SIZE_TYPE_EASY_1x1 - * 23x21=680x215, LB_SIZE_TYPE_EASY_3x1 - * 23x23=680x653, LB_SIZE_TYPE_EASY_3x3 - * - * Special livebox - * 0x0=720x1280, LB_SIZE_TYPE_0x0 - * - * \remarks - * Even if you get the handle by return value of this function, it is not created instance. - * So you have to deal it as not initialized handle. - * Only it can be initialized after get the return callback with "ret == LB_STATUS_SUCCESS". - * \param[in] pkgname Livebox Id - * \param[in] content Will be passed to the livebox instance. - * \param[in] cluster Main group - * \param[in] category Sub group - * \param[in] period DEFAULT_PERIOD can be used for this. this argument will be used to specify the period of update content of livebox. - * \param[in] type Size type - which are defined from liblivebox-service package. - * \param[in] cb After the request is sent to the master provider, this callback will be called. - * \param[in] data This data will be passed to the callback. - * \return handle - * \retval handle Livebox handle but not yet initialized - * \retval NULL if it fails to create a handle - * \see ret_cb_t - * \see livebox_add - */ -extern struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data); - -/*! - * \brief Delete a livebox (deprecated) - * \details N/A - * \remarks - * If you call this with uninitialized handle, the return callback will be called synchronously. - * So before return from this function, the return callback will be called first. - * \param[in] handler Handler of a livebox instance - * \param[in] cb return callback - * \param[in] data user data for return callback - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY already in process - * \retval LB_STATUS_ERROR_FAULT failed to create a request packet - * \retval LB_STATUS_SUCCESS successfully sent, return callack will be called - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_del(struct livebox *handler, ret_cb_t cb, void *data); - -/*! - * \brief Delete a livebox (will be replaced with livebox_del) - * \details N/A - * \remarks - * If you call this with uninitialized handle, the return callback will be called synchronously. - * So before return from this function, the return callback will be called first. - * \param[in] handler Handler of a livebox instance - * \param[in] type Deletion type, LB_DELETE_PERMANENTLY or LB_DELETE_TEMPORARY - * \param[in] cb return callback - * \param[in] data user data for return callback - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY already in process - * \retval LB_STATUS_ERROR_FAULT failed to create a request packet - * \retval LB_STATUS_SUCCESS successfully sent, return callack will be called - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data); - -/*! - * \brief Set a livebox events callback - * \details - * To get the events push from the provider, register the event callback using this function - * The callback will be called if there is any events from the provider. - * \remarks N/A - * \param[in] cb Event handler - * \param[in] data User data for the event handler - * \return int - * \retval LB_STATUS_SUCCESS if succeed to set event handler - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_MEMORY Not enough memory - * \pre NULL - * \post NULL - * \see livebox_unset_event_handler - */ -extern int livebox_set_event_handler(int (*cb)(struct livebox *handler, enum livebox_event_type event, void *data), void *data); - -/*! - * \brief Unset the livebox event handler - * \details N/A - * \remarks N/A - * \param[in] cb Event handler - * \return void * Event handler data - * \retval pointer of 'data' which is used with the livebox_set_event_handler - * \pre N/A - * \post N/A - * \see livebox_set_event_handler - */ -extern void *livebox_unset_event_handler(int (*cb)(struct livebox *handler, enum livebox_event_type event, void *data)); - -/*! - * \brief Live box fault event handler registeration function - * argument list - * event, pkgname, filename, funcname - * \details N/A - * \remarks N/A - * \param[in] cb Event handler - * \param[in] data Event handler data - * \return int - * \retval LB_STATUS_SUCCESS if succeed to set fault event handler - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_MEMORY Not enough memory - * \pre N/A - * \post N/A - * \see livebox_unset_fault_handler - */ -extern int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data); - -/*! - * \brief Unset the live box fault event handler - * \details N/A - * \remarks N/A - * \param[in] cb Event handler - * \return void * Callback data which is set via livebox_set_fault_handler - * \retval pointer of 'data' which is used with the livebox_set_fault_handler - * \pre N/A - * \post N/A - * \see livebox_set_fault_handler - */ -extern void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *)); - -/*! - * \brief Activate the faulted livebox. - * \details - * Request result will be back via return callback. - * \remarks - * Even though this function returns SUCCESS, it means just successfully sent a request to provider. - * So you have to check the return callback. and its "ret" argument. - * \param[in] pkgname Package name which should be activated - * \param[in] cb Result callback - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_SUCCESS Successfully sent a request - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Failed to make a request - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_activate(const char *pkgname, ret_cb_t cb, void *data); - -/*! - * \brief Resize the livebox - * \details - * Normal mode livebox size - * 1x1=175x175, LB_SIZE_TYPE_1x1 - * 2x1=354x175, LB_SIZE_TYPE_2x1 - * 2x2=354x354, LB_SIZE_TYPE_2x2 - * 4x1=712x175, LB_SIZE_TYPE_4x1 - * 4x2=712x354, LB_SIZE_TYPE_4x2 - * 4x4=712x712, LB_SIZE_TYPE_4x4 - * - * Extended livebox size - * 4x3=712x533, LB_SIZE_TYPE_4x3 - * 4x5=712x891, LB_SIZE_TYPE_4x5 - * 4x6=712x1070, LB_SIZE_TYPE_4x6 - * - * Easy mode livebox size - * 21x21=224x215, LB_SIZE_TYPE_EASY_1x1 - * 23x21=680x215, LB_SIZE_TYPE_EASY_3x1 - * 23x23=680x653, LB_SIZE_TYPE_EASY_3x3 - * - * Special mode livebox size - * 0x0=720x1280, LB_SIZE_TYPE_0x0 - * \remarks - * You have to check the return callback. - * \param[in] handler Handler of a livebox instance - * \param[in] type Type of a livebox size, LB_SIZE_TYPE_1x1, ... - * \param[in] cb Result callback of the resize operation. - * \param[in] data User data for return callback - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY Previous request of resize is in progress. - * \retval LB_STATUS_ERROR_ALREADY Already resized, there is no differences between current size and requested size. - * \retval LB_STATUS_ERROR_PERMISSION Permission denied, you only have view the content of this box. - * \retval LB_STATUS_ERROR_FAULT Failed to make a request - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data); - -/*! - * \brief Send the click event for a livebox. - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] x Rational X of the content width. - * \param[in] y Rational Y of the content height. - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_click(struct livebox *handler, double x, double y); - -/*! - * \brief Change the cluster/sub-cluster name of given livebox handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] cluster New cluster of a livebox - * \param[in] category New category of a livebox - * \param[in] cb Result callback for changing the cluster/category of a livebox - * \param[in] data User data for the result callback - * \return int - * \retval LB_STATUS_SUCCESS Request is successfully sent. the return callback will be called. - * \retval LB_STATUS_ERROR_BUSY previous request is not finished yet. - * \retval LB_STATUS_ERROR_ALREADY group name is same with current one. - * \retval LB_STATUS_ERROR_PERMISSION you have no permission to change property of this livebox instance. - * \retval LB_STATUS_ERROR_FAULT Failed to make a request. - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data); - -/*! - * \brief Get the cluster and category(sub-cluster) name of given livebox (It is not I18N format, only english) - * \details N/A - * \remarks - * You have to do not release the cluster & category. - * It is allocated inside of given livebox instance, so you can only read it. - * \param[in] handler Handler of a livebox instance - * \param[out] cluster Storage(memory) for containing the cluster name - * \param[out] category Storage(memory) for containing the category name - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_get_group(struct livebox *handler, const char **cluster, const char **category); - -/*! - * \brief Get the period of this livebox handler - * \details N/A - * \remarks - * if this function returns 0.0f, it means the livebox has no update period. - * or the handle is not valid. - * This function only can be works after the return callback of livebox_create fucntion is called. - * \param[in] handler Handler of a livebox instance - * \return double - * \retval Current update period of a livebox - * \retval 0.0f it means the box has no update period, or it can returns 0.0 if the handles is not valid. - * \pre N/A - * \post N/A - * \see N/A - */ -extern double livebox_period(struct livebox *handler); - -/*! - * \brief Change the update period - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] period New update period of a livebox - * \param[in] cb Result callback of changing the update period of this livebox - * \param[in] data User data for the result callback - * \return int - * \retval LB_STATUS_SUCCESS Successfully done - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY - * \retval LB_STATUS_ERROR_ALREADY - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data); - -/*! - * \brief Is this an text type livebox? - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return livebox_lb_type - * \retval LB_TYPE_IMAGE Contents of a livebox is based on the image file - * \retval LB_TYPE_BUFFER Contents of a livebox is based on canvas buffer(shared) - * \retval LB_TYPE_TEXT Contents of a livebox is based on formatted text file - * \retval LB_TYPE_PIXMAP Contens of a livebox is shared by the pixmap(depends on X) - * \retval LB_TYPE_INVALID - * \pre N/A - * \post N/A - * \see livebox_lb_type - */ -extern enum livebox_lb_type livebox_lb_type(struct livebox *handler); - -/*! - * \brief Is this livebox is created by a user? - * \details - * If the livebox instance is created by system this will returns 0. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval 0 automatically created livebox by the provider - * \retval 1 created by user via livebox_add or livebox_add_with_size - * \pre N/A - * \post N/A - * \see livebox_add - * \see livebox_add_with_size - * \see livebox_set_event_handler - */ -extern int livebox_is_user(struct livebox *handler); - -/*! - * \brief Get the content information string of given livebox - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return const char * - * \retval content_info Livebox content info that can be used again via content_info argument of livebox_add or livebox_add_with_size. - * \pre N/A - * \post N/A - * \see livebox_add - * \see livebox_add_with_size - */ -extern const char *livebox_content(struct livebox *handler); - -/*! - * \brief Get the sub cluster title string of given livebox - * \details - * This API is now used for accessibility. - * Each box should set their content as a string to read by TTS. - * So if the box has focus on the homescreen, the homescreen will read a text using this API. - * \remarks - * The title which is returned by this, the TTS should read it. - * But it is just recomended to a homescreen. - * So read it or not is depends on implementation of the homescreen. - * \param[in] handler Handler of a livebox instance - * \return const char * - * \retval sub cluster name - * \retval NULL - * \pre N/A - * \post N/A - * \see N/A - */ -extern const char *livebox_category_title(struct livebox *handler); - -/*! - * \brief Get the filename of given livebox, if it is an IMAGE type livebox - * \details - * If the box is developed as image format to represent its contents, - * The homescreen should know its image file name. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return const char * - * \retval filename if the livebox type is image this function will give you a abspath of an image file (content is rendered) - * \retval NULL if this has no image file or type is not image file. - * \pre N/A - * \post N/A - * \see N/A - */ -extern const char *livebox_filename(struct livebox *handler); - -/*! - * \brief Get the package name of given livebox handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return const char * - * \retval pkgname package name - * \retval NULL if the handler is not valid - * \pre N/A - * \post N/A - * \see N/A - */ -extern const char *livebox_pkgname(struct livebox *handler); - -/*! - * \brief Get the priority of a current content. - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return double - * \retval 0.0f handler is NULL - * \retval -1.0f Handler is not valid (not yet initialized) - * \retval real number between 0.0 and 1.0 - * \pre N/A - * \post N/A - * \see N/A - */ -extern double livebox_priority(struct livebox *handler); - -/*! - * \brief Acquire the buffer of given livebox (Only for the buffer type) - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return void * - * \retval address of a FB - * \retval NULL if it fails to get fb address - * \pre N/A - * \post N/A - * \see N/A - */ -extern void *livebox_acquire_fb(struct livebox *handler); - -/*! - * \brief Release the buffer of a livebox (Only for the buffer type) - * \details N/A - * \remarks N/A - * \param[in] buffer - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see livebox_acquire_fb - */ -extern int livebox_release_fb(void *buffer); - -/*! - * \brief Get the reference count of Livebox buffer (Only for the buffer type) - * \details N/A - * \remarks N/A - * \param[in] buffer - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval refcnt positive integer including ZERO - * \pre N/A - * \post N/A - * \see livebox_pdfb_refcnt - */ -extern int livebox_fb_refcnt(void *buffer); - -/*! - * \brief Acquire the buffer of a PD frame (Only for the buffer type) - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval NULL - * \retval adress of buffer of PD - * \pre N/A - * \post N/A - * \see livebox_release_pdfb - */ -extern void *livebox_acquire_pdfb(struct livebox *handler); - -/*! - * \brief Release the acquired buffer of the PD Frame (Only for the buffer type) - * \details N/A - * \remarks N/A - * \param[in] buffer - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see livebox_acquire_pdfb - */ -extern int livebox_release_pdfb(void *buffer); - -/*! - * \brief Reference count of given PD buffer (Only for the buffer type) - * \details N/A - * \remarks N/A - * \param[in] buffer - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval reference count - * \pre N/A - * \post N/A - * \see livebox_fb_refcnt - */ -extern int livebox_pdfb_refcnt(void *buffer); - -/*! - * \brief Get the size of the Livebox - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_SIZE_TYPE_NxM - * \retval LB_SIZE_TYPE_INVALID - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_size(struct livebox *handler); - -/*! - * \brief Get the size of the Progressive Disclosure - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[out] w - * \param[out] h - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_get_pdsize(struct livebox *handler, int *w, int *h); - -/*! - * \brief List of supported sizes of given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[out] cnt - * \param[out] size_list - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list); - -/*! - * \brief BUFFER SIZE of the livebox if it is a buffer type - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval size of livebox buffer - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_lbfb_bufsz(struct livebox *handler); - -/*! - * \brief BUFFER SIZE of the progiressive disclosure if it is a buffer type - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval size of PD buffer - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_pdfb_bufsz(struct livebox *handler); - -/*! - * \brief Send the content event (for buffer type) to provider(livebox) - * \details N/A - * \remarks DEPRECATED - * Use the livebox_mouse_event function instead of this. - * \param[in] handler Handler of a livebox instance - * \param[in] type Event type - * \param[in] x coordinates of X axis - * \param[in] y coordinates of Y axis - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY Previous operaion is not finished yet - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully sent - * \pre N/A - * \post N/A - * \see livebox_mouse_event - * \see livebox_access_event - * \see livebox_key_event - */ -extern int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y); - -/*! - * \brief Send the content event (for buffer type) to provider(livebox) - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] type Event type - * \param[in] x coordinates of X axis - * \param[in] y coordinates of Y axis - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY Previous operation is not finished yet - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully sent - * \pre N/A - * \post N/A - * \see livebox_content_event - * \see livebox_access_event - * \see livebox_key_event - */ -extern int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y); - -/*! - * \brief Send the access event(for buffer type) to provider(livebox). - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] type Event type - * \param[in] x coordinates of X axsis - * \param[in] y coordinates of Y axsis - * \param[in] cb Result callback function - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY Previous operation is not finished yet - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully sent - * \pre N/A - * \post N/A - * \see livebox_mouse_event - * \see livebox_key_event - */ -extern int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data); - -/*! - * \brief Send the key event(for buffer type) to provider(livebox). - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] type Key event type - * \param[in] keycode Code of key - * \param[in] cb Result callback - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY Previous operation is not finished yet - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully sent - * \pre N/A - * \post N/A - * \see livebox_mouse_event - * \see livebox_access_event - */ -extern int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data); - -/*! - * \brief Do pin up or not. - * \details - * If the livebox supports the pinup feature, - * you can freeze the update of given livebox. - * But it is different with pause. - * The box will be updated and it will decide wheter update its content or not when the pinup is on. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] flag Pinup value - * \param[in] cb Result callback - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid parameters - * \see ret_cb_t - * \see livebox_set_visibility - * \see livebox_is_pinned_up - */ -extern int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data); - -/*! - * \brief Check the PIN-UP status of given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid parameters - * \retval 1 box is pinned up - * \retval 0 box is not pinned up - * \see livebox_set_pinup - */ -extern int livebox_is_pinned_up(struct livebox *handler); - -/*! - * \brief Check the PINUP feature availability of the given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval 1 if the box support Pinup feature - * \retval 0 if the box does not support the Pinup feature - * \pre N/A - * \post N/A - * \see livebox_is_pinned_up - * \see livebox_set_pinup - */ -extern int livebox_has_pinup(struct livebox *handler); - -/*! - * \brief Check the PD existence of given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval 1 if the box support the PD - * \retval 0 if the box has no PD - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_has_pd(struct livebox *handler); - -/*! - * \brief Create the PD of given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] cb Result callback - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_SUCCESS Successfully done - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY Previous operation is not finished yet - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \pre N/A - * \post N/A - * \see ret_cb_t - * \see livebox_create_pd_with_position - * \see livebox_move_pd - * \see livebox_destroy_pd - */ -extern int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data); - -/*! - * \brief Create the PD of given handler with the relative position from livebox - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] x 0.0 ~ 1.0 - * \param[in] y 0.0 ~ 1.0 - * \param[in] cb Result callback - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_SUCCESS Successfully done - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY Previous operation is not finished yet - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \pre N/A - * \post N/A - * \see livebox_create_pd - * \see livebox_destroy_pd - * \see livebox_move_pd - */ -extern int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data); - -/*! - * \brief PD position is updated. - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] x 0.0 ~ 1.0 - * \param[in] y 0.0 ~ 1.0 - * \return int - * \retval LB_STATUS_SUCCESS if succeed to send request for updating position of the PD. - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_move_pd(struct livebox *handler, double x, double y); - -/*! - * \brief Destroy the PD of given handler if it is created. - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] cb - * \param[in] data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data); - -/*! - * \brief Check the create status of given livebox handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval 0 PD is not created - * \retval 1 PD is created - */ -extern int livebox_pd_is_created(struct livebox *handler); - -/*! - * \brief Check the content type of the progressive disclosure of given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval PD_TYPE_BUFFER Contents of a PD is based on canvas buffer(shared) - * \retval PD_TYPE_TEXT Contents of a PD is based on formatted text file - * \retval PD_TYPE_PIXMAP Contents of a livebox is shared by the pixmap(depends on X) - * \retval PD_TYPE_INVALID - * \pre N/A - * \post N/A - * \see livebox_pd_type - */ -extern enum livebox_pd_type livebox_pd_type(struct livebox *handler); - -/*! - * \brief Check the existence of a livebox about given package name - * \details N/A - * \remarks N/A - * \param[in] pkgname - * \return int - * \retval 1 if the box is exists - * \retval 0 if the box is not exists - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_is_exists(const char *pkgname); - -/*! - * \brief Set function table for parsing the text content of a livebox - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] ops - * \return int - * \retval LB_STATUS_SUCCESS Successfully done - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \see livebox_set_pd_text_handler - */ -extern int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops); - -/*! - * \brief Set function table for parsing the text content of a Progressive Disclosure - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] ops - * \return int - * \retval LB_STATUS_SUCCESS Successfully done - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \see livebox_set_text_handler - */ -extern int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops); - -/*! - * \brief Emit a text signal to given livebox only if it is a text type. - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] emission Emission string - * \param[in] source Source string - * \param[in] sx start X - * \param[in] sy start Y - * \param[in] ex end X - * \param[in] ey end Y - * \param[in] cb Result callback - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid parameters - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully emitted - * \see ret_cb_t - */ -extern int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data); - -/*! - * \brief Set a private data pointer to carry it using given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] data data pointer - * \return int - * \retval LB_STATUS_SUCCESS Successfully registered - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \pre N/A - * \post N/A - * \see livebox_get_data - */ -extern int livebox_set_data(struct livebox *handler, void *data); - -/*! - * \brief Get private data pointer which is carried by given handler - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return void * - * \retval data pointer - * \retval NULL if there is not data - * \pre N/A - * \post N/A - * \see livebox_set_data - */ -extern void *livebox_get_data(struct livebox *handler); - -/*! - * \brief Subscribe the event for liveboxes only in given cluster and sub-cluster - * \details - * If you wrote a view-only client. - * you can receive the event of specific liveboxes which are grouped in given cluster/category - * But you cannot modify their attributes (such as size, ...). - * \remarks N/A - * \param[in] cluster "*" can be used for subscribe all cluster's liveboxes event. - * If you use the "*", value in the category will be ignored. - * \param[in] category "*" can be used for subscribe liveboxes events of all category(sub-cluster) in given "cluster" - * \return int - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully requested - * \pre N/A - * \post N/A - * \see livebox_unsubscribe_group - */ -extern int livebox_subscribe_group(const char *cluster, const char *category); - -/*! - * \brief Unsubscribe the event for the liveboxes, but you will receive already added liveboxes event. - * \details N/A - * \remarks N/A - * \param[in] cluster "*" can be used for subscribe all cluster's liveboxes event. - * If you use the "*", value in the category will be ignored. - * \param[in] category "*" can be used for subscribe all sub-cluster's liveboxes event in given "cluster" - * \return int - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully requested - * \pre N/A - * \post N/A - * \see livebox_subscribe_group - */ -extern int livebox_unsubscribe_group(const char *cluster, const char *category); - -/*! - * \brief Refresh the group(cluster/sub-cluser(aka. category)) - * \details - * This function will trigger the update of all liveboxes in given cluster/category group - * \remarks - * Basically default livebox system doesn't use the cluster/category concept. - * But you can use it. so if you decide to use it then you can trigger the update of all liveboxes in given group. - * \param[in] cluster Cluster ID - * \param[in] category Sub-cluster ID - * \param[in] force 1 if the boxes should be updated even if they are paused - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully requested - * \pre N/A - * \post N/A - * \see livebox_refresh - */ -extern int livebox_refresh_group(const char *cluster, const char *category, int force); - -/*! - * \brief Refresh a livebox - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] force 1 if the box should be updated even if it is paused - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully requested - * \pre N/A - * \post N/A - * \see livebox_refresh_group - */ -extern int livebox_refresh(struct livebox *handler, int force); - -/*! - * \brief Pixmap Id of a livebox content - * \details - * This function doesn't guarantees the life-cycle of the pixmap. - * If the service provider destroy the pixmap, you will not know about it. - * So you should validate it before access it. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval 0 if the pixmap is not created - * \retval pixmap Pixmap Id need to be casted to (unsigned int) type - * \pre N/A - * \post N/A - * \see livebox_pd_pixmap - */ -extern int livebox_lb_pixmap(const struct livebox *handler); - -/*! - * \brief Pixmap Id of a PD content - * \details - * This function doesn't guarantees the life-cycle of the pixmap. - * If the service provider destroy the pixmap, you will not know about it. - * So you should validate it before access it. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval 0 if the pixmap is not created - * \retval pixmap Pixmap Id need to be casted to (unsigned int) type - * \pre N/A - * \post N/A - * \see livebox_lb_pixmap - */ -extern int livebox_pd_pixmap(const struct livebox *handler); - -/*! - * \brief Acquire the pixmap of PD - * \details - * After acquire the pixmap of PD, it will not be destroyed - * So if the new update is comming with new pixmap Id, you should release old pixmap manually - * \remarks N/A - * \param[in] handler Handler of a livebox instance. - * \param[in] cb Result callback for acquiring request - * \param[in] data Callback Data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Failed to send a request to the service provider or there is critical error that is unrecoverable - * \retval LB_STATUS_SUCCESS Successfully requested to acquire the pixmap of PD - * \pre N/A - * \post N/A - * \see livebox_release_pd_pixmap - * \see livebox_acquire_lb_pixmap - * \see ret_cb_t - */ -extern int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data); - -/*! - * \brief Release the acquired pixmap ID - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance, This can be NULL, only if the handler is deleted. - * \param[in] pixmap Pixmap Id to release it - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully released (request is sent) - * \pre N/A - * \post N/A - * \see livebox_acquire_pd_pixmap - * \see livebox_release_lb_pixmap - */ -extern int livebox_release_pd_pixmap(struct livebox *handler, int pixmap); - -/*! - * \brief Getting the PIXMAP of a livebox - * \details - * Even if the render process release the pixmap, the pixmap will be kept before released by livebox_release_lb_pixmap - * You should release the pixmap manually. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] cb Callback function which will be called with result of acquiring lb pixmap - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully requested - * \pre - * Livebox service system should support the PIXMAP type buffer. - * The livebox should be designed to use the buffer (script type) - * \post N/A - * \see livebox_release_lb_pixmap - * \see livebox_acquire_pd_pixmap - * \see ret_cb_t - */ -extern int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data); - -/*! - * \brief Release the pixmap of a livebox - * \details - * After the client gets new pixmap or no more need to keep current pixmap, use this to release it. - * If there is no user for given pixmap, the pixmap will be destroyed. - * \remarks N/A - * \param[in] handler Handler of a livebox instance, This can be NULL, only if the handler is deleted. - * \param[in] pixmap Pixmap Id of given livebox handler - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully done - * \pre - * The pixmap should be acquired by livebox_acquire_lb_pixmap - * \post N/A - * \see livebox_acquire_lb_pixmap - * \see livebox_release_pd_pixmap - */ -extern int livebox_release_lb_pixmap(struct livebox *handler, int pixmap); - -/*! - * \brief Update the visible state of a livebox - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] state Configure the current visible state of a livebox - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY - * \retval LB_STATUS_ERROR_PERMISSION - * \retval LB_STATUS_ERROR_ALREADY - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state); - -/*! - * \brief Current visible state of a livebox - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return livebox_visible_state - * \retval LB_SHOW Livebox is showed. Default state - * \retval LB_HIDE Livebox is hide, Update timer is not be freezed. but you cannot receive any updates events. you should refresh(reload) the content of a livebox when you make this show again - * \retval LB_HIDE_WITH_PAUSE Livebix is hide, it will paused the update timer, but if a livebox update its contents, update event will come to you - * \retval LB_VISIBLE_ERROR To enlarge the size of this enumeration type - * \pre N/A - * \post N/A - * \see N/A - */ -extern enum livebox_visible_state livebox_visibility(struct livebox *handler); - -/*! - * \brief Set the update mode of current livebox - * \details N/A - * \remarks N/A - * if you set 1 for active update mode, you should get buffer without updated event from provider. - * But is passive mode, you have to update content of a box when you get updated event. - * Default is Passive mode. - * \param[in] handler Handler of a livebox instance - * \param[in] active_update 1 means active update, 0 means passive update (default) - * \param[in] cb Result callback function - * \param[in] data Callback data - * \return int - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_ERROR_BUSY - * \retval LB_STATUS_ERROR_PERMISSION - * \retval LB_STATUS_ERROR_ALREADY - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see ret_cb_t - */ -extern int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data); - -/*! - * \brief Is this box in the active update mode? - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return int - * \retval 0 if passive mode - * \retval 1 if active mode or error code - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_is_active_update(struct livebox *handler); - -/*! - * \brief Sync manually - * \details N/A - * \remarks N/A - * param[in] handler Handler of a livebox instance - * \return void - * \retval LB_STATUS_SUCCESS If success - * \retval LB_STATUS_ERROR_INVALID Invalid handle - * \pre N/A - * \post N/A - * \see livebox_set_manual_sync - * \see livebox_manual_sync - * \see livebox_sync_lb_fb - */ -extern int livebox_sync_pd_fb(struct livebox *handler); - -/*! - * \brief Sync manually - * \details N/A - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return void - * \retval LB_STATUS_SUCCESS If success - * \retval LB_STATUS_ERROR_INVALID Invalid handle - * \pre N/A - * \post N/A - * \see livebox_set_manual_sync - * \see livebox_manual_sync - * \see livebox_sync_pd_fb - */ -extern int livebox_sync_lb_fb(struct livebox *handler); - -/*! - * \brief Getting the alternative icon of given livebox instance. - * \details If the box should be represented as a shortcut icon, this function will get the alternative icon. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return const char * - * \retval address Absolute path of an alternative icon file - * \retval NULL Livebox has no alternative icon file - * \pre N/A - * \post N/A - * \see livebox_alt_name - */ -extern const char *livebox_alt_icon(struct livebox *handler); - -/*! - * \brief Getting the alternative name of given livebox instance. - * \details If the box should be represented as a shortcut name, this function will get the alternative name. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \return const char * - * \retval name Alternative name of a livebox - * \retval NULL Livebox has no alternative name - * \pre N/A - * \post N/A - * \see livebox_alt_icon - */ -extern const char *livebox_alt_name(struct livebox *handler); - -/*! - * \brief Get the lock for frame buffer. - * \details - * This function should be used to prevent from rendering to the frame buffer while reading it. - * And the locking area should be short and must be released ASAP - * Or the render thread will be hang'd. - * \remarks - * \param[in] handler Handler of a livebox instance - * \param[in] is_pd 1 for PD or 0 - * \return int - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see livebox_release_fb_lock - */ -extern int livebox_acquire_fb_lock(struct livebox *handler, int is_pd); - -/*! - * \brief Release the lock of frame buffer - * \details - * This function should be called ASAP after acquire a lock of FB. - * Or the render process will be blocked. - * \remarks N/A - * \param[in] handler Handler of a livebox instance - * \param[in] is_pd 1 for PD or 0 - * \return int - * \retval LB_STATUS_ERROR_FAULT Unrecoverable error occurred - * \retval LB_STATUS_ERROR_INVALID Invalid argument - * \retval LB_STATUS_SUCCESS Successfully done - * \pre N/A - * \post N/A - * \see livebox_acquire_fb_lock - */ -extern int livebox_release_fb_lock(struct livebox *handler, int is_pd); - -/*! - * \brief Set options for controlling livebox sub-system. - * \details - * LB_OPTION_FRAME_DROP_FOR_RESIZE - * While resizing the box, viewer doesn't want to know the updated frames of old size content anymore, - * In that case, turn this on, the provider will not send the updated event to the viewer about old content. - * So the viewer can reduce its burden to update unnecessary frames - * LB_OPTION_MANUAL_SYNC - * If you don't want updates frame automatically, - * Only you want reload the frames by your hands,(manually) - * Turn it on. - * After turnned it on, you should sync it using - * livebox_sync_pd_fb - * livebox_sync_lb_pfb - * LB_OPTION_SHARED_CONTENT - * If this option is turnned on, even though you create a new livebox, - * If there are already added same instance has same content, the instance will not be created again - * Instead of creating a new instance, viewer will provides old instance with new handle. - * \remarks N/A - * \param[in] option option which will be affected by this call - * \param[in] state new value for given option - * \return int - * \retval LB_STATUS_ERROR_INVALID Unknown option - * \retval LB_STATUS_ERROR_FAULT Failed to change the state of option - * \retval LB_STATUS_SUCCESS Successfully changed - * \pre N/A - * \post N/A - * \see livebox_get_option - * \see livebox_sync_pd_fb - * \see livebox_sync_lb_fb - */ -extern int livebox_set_option(enum livebox_option_type option, int state); - -/*! - * \brief Get options livebox sub-system - * \details N/A - * \remarks N/A - * \param[in] option type of option - * \return int - * \retval LB_STATUS_ERROR_INVALID invalid option - * \retval LB_STATUS_ERROR_FAULT Failed to get option - * \retval >=0 Value of given option. must has to be >=0 - * \pre N/A - * \post N/A - * \see livebox_set_option - */ -extern int livebox_option(enum livebox_option_type option); - - -/*! - * \brief Set a handler for launching an app for auto-launch feature - * \details If a user clicks a box, and the box uses auto-launch option, the launcher_handler will be called. - * \remarks N/A - * \param[in] launch_handler Handler for launching an app manually - * \param[in] data Callback data which will be given a data for launch_handler - * \return int - * \retval - * \pre N/A - * \post N/A - * \see N/A - */ -extern int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data); - -/*! - * \} - */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/livebox_internal.h b/include/livebox_internal.h deleted file mode 100644 index a6f92f9..0000000 --- a/include/livebox_internal.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * 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 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event); -extern void lb_invoke_fault_handler(enum livebox_fault_type type, const char *pkgname, const char *filename, const char *function); - -extern struct livebox_common *lb_find_common_handle(const char *pkgname, const char *filename); -extern struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category); -extern struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp); - -extern int lb_set_group(struct livebox_common *common, const char *cluster, const char *category); -extern void lb_set_size(struct livebox_common *common, int w, int h); -extern void lb_set_pdsize(struct livebox_common *common, int w, int h); -extern void lb_set_default_pdsize(struct livebox_common *common, int w, int h); -extern int lb_set_content(struct livebox_common *common, const char *content); -extern int lb_set_title(struct livebox_common *handler, const char *title); -extern void lb_set_auto_launch(struct livebox_common *handler, const char *auto_launch); -extern void lb_set_id(struct livebox_common *handler, const char *id); -extern void lb_set_size_list(struct livebox_common *handler, int size_list); -extern void lb_set_priority(struct livebox_common *handler, double priority); -extern int lb_set_lb_fb(struct livebox_common *handler, const char *filename); -extern int lb_set_pd_fb(struct livebox_common *handler, const char *filename); -extern struct fb_info *lb_get_pd_fb(struct livebox_common *handler); -extern struct fb_info *lb_get_lb_fb(struct livebox_common *handler); -extern void lb_set_user(struct livebox_common *handler, int user); -extern void lb_set_pinup(struct livebox_common *handler, int pinup); -extern void lb_set_text_lb(struct livebox_common *handler); -extern void lb_set_text_pd(struct livebox_common *handler); -extern int lb_text_lb(struct livebox_common *handler); -extern int lb_text_pd(struct livebox_common *handler); -extern void lb_set_period(struct livebox_common *handler, double period); -extern void lb_set_update_mode(struct livebox_common *handler, int active_mode); -extern void lb_set_filename(struct livebox_common *handler, const char *filename); -extern void lb_set_alt_info(struct livebox_common *handler, const char *icon, const char *name); -extern int lb_destroy_lock_file(struct livebox_common *common, int is_pd); -extern int lb_create_lock_file(struct livebox_common *common, int is_pd); -extern int lb_destroy_common_handle(struct livebox_common *common); -extern struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category); -extern int lb_sync_pd_fb(struct livebox_common *common); -extern int lb_sync_lb_fb(struct livebox_common *common); -extern int lb_common_unref(struct livebox_common *common, struct livebox *handle); -extern int lb_common_ref(struct livebox_common *common, struct livebox *handle); - -extern struct livebox *lb_ref(struct livebox *handler); -extern struct livebox *lb_unref(struct livebox *handler, int destroy_common); -extern int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data); -extern int lb_delete_all(void); - -enum lb_type { /*!< Must have to be sync with data-provider-master */ - _LB_TYPE_NONE = 0x0, - _LB_TYPE_SCRIPT, - _LB_TYPE_FILE, - _LB_TYPE_TEXT, - _LB_TYPE_BUFFER -}; - -enum pd_type { /*!< Must have to be sync with data-provider-master */ - _PD_TYPE_NONE = 0x0, - _PD_TYPE_SCRIPT, - _PD_TYPE_TEXT, - _PD_TYPE_BUFFER -}; - -enum livebox_state { - CREATE = 0xBEEFbeef, - DELETE = 0xDEADdead, /* Delete only for this client */ - DESTROYED = 0x00DEAD00 -}; - -struct livebox_common { - enum livebox_state state; - - struct dlist *livebox_list; - int refcnt; - - char *cluster; - char *category; - - char *pkgname; - char *id; - - char *content; - char *title; - char *filename; - - double timestamp; - - struct alt_info { - char *icon; - char *name; - } alt; - - enum livebox_delete_type delete_type; - - int is_user; - int is_pd_created; - int is_pinned_up; - int is_active_update; - enum livebox_visible_state visible; - - struct { - enum lb_type type; - struct fb_info *fb; - - int size_list; - - int width; - int height; - double priority; - - char *auto_launch; - double period; - int pinup_supported; - int mouse_event; - - /* For the filtering event */ - double x; - double y; - char *lock; - int lock_fd; - } lb; - - struct { - enum pd_type type; - struct fb_info *fb; - - int width; - int height; - - int default_width; - int default_height; - - /* For the filtering event */ - double x; - double y; - char *lock; - int lock_fd; - } pd; - - int nr_of_sizes; - - struct requested_flag { - unsigned int created:1; - unsigned int deleted:1; - unsigned int pinup:1; - unsigned int group_changed:1; - unsigned int period_changed:1; - unsigned int size_changed:1; - unsigned int pd_created:1; - unsigned int pd_destroyed:1; - unsigned int update_mode:1; - unsigned int access_event:1; - unsigned int key_event:1; - - /*! - * \note - * Reserved - */ - unsigned int reserved:21; - } request; -}; - -struct job_item { - struct livebox *handle; - ret_cb_t cb; - int ret; - void *data; -}; - -struct livebox { - enum livebox_state state; - - int refcnt; - int paused_updating; - - enum livebox_visible_state visible; - struct livebox_common *common; - - void *data; - - struct callback_table { - struct livebox_script_operators lb_ops; - struct livebox_script_operators pd_ops; - - struct created { - ret_cb_t cb; - void *data; - } created; - - struct deleted { - ret_cb_t cb; - void *data; - } deleted; - - struct pinup { - ret_cb_t cb; - void *data; - } pinup; - - struct group_changed { - ret_cb_t cb; - void *data; - } group_changed; - - struct period_changed { - ret_cb_t cb; - void *data; - } period_changed; - - struct size_changed { - ret_cb_t cb; - void *data; - } size_changed; - - struct pd_created { - ret_cb_t cb; - void *data; - } pd_created; - - struct pd_destroyed { - ret_cb_t cb; - void *data; - } pd_destroyed; - - struct update_mode { - ret_cb_t cb; - void *data; - } update_mode; - - struct access_event { - ret_cb_t cb; - void *data; - } access_event; - - struct key_event { - ret_cb_t cb; - void *data; - } key_event; - } cbs; -}; - -/* End of a file */ diff --git a/live.viewer/CMakeLists.txt b/live.viewer/CMakeLists.txt deleted file mode 100644 index 9be5a14..0000000 --- a/live.viewer/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ -PROJECT(live-viewer C) -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED - capi-appfw-application - capi-appfw-app-manager - ail - bundle - dlog - elementary - ecore-x - appcore-efl - livebox-viewer - livebox-service -) - -FOREACH(flag ${pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wall -Werror -Winline -g") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") - -SET(PKGROOT "/opt/usr/apps/live.viewer") -ADD_DEFINITIONS("-DNDEBUG") -ADD_DEFINITIONS("-DPKGROOT=\"${PKGROOT}\"") -#ADD_DEFINITIONS("-DFLOG") -ADD_DEFINITIONS("-DLOG_TAG=\"${PROJECT_NAME}\"") -ADD_DEFINITIONS(${pkgs_CFLAGS}) -ADD_DEFINITIONS(${pkgs_LDFLAGS}) - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) - -ADD_EXECUTABLE(${PROJECT_NAME} - src/main.c - src/dlist.c - src/live_scroller.c - src/util.c - src/scroller.c - src/lb.c -) - -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}) -INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${PKGROOT}/bin) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/live.viewer.xml DESTINATION /opt/share/packages) - -ADD_SUBDIRECTORY(res) diff --git a/live.viewer/image/folder b/live.viewer/image/folder deleted file mode 100644 index e69de29..0000000 diff --git a/live.viewer/include/debug.h b/live.viewer/include/debug.h deleted file mode 100644 index 2efc6dc..0000000 --- a/live.viewer/include/debug.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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. - */ - -#if !defined(FLOG) -#define DbgPrint(format, arg...) SECURE_LOGD("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg) -#define ErrPrint(format, arg...) SECURE_LOGE("[%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg) -#else -extern FILE *__file_log_fp; -#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) - -#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) -#endif - -/* End of a file */ diff --git a/live.viewer/include/lb.h b/live.viewer/include/lb.h deleted file mode 100644 index 37c48ac..0000000 --- a/live.viewer/include/lb.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * 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 lb_init(void); -extern int lb_fini(void); -extern int lb_add(Evas_Object *sc, const char *pkgname); - -/* End of a file */ diff --git a/live.viewer/include/live_scroller.h b/live.viewer/include/live_scroller.h deleted file mode 100644 index 02b2450..0000000 --- a/live.viewer/include/live_scroller.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ - -struct live_sc_event_info { - int curidx; - int toidx; -}; - -struct live_sc_drag_info { - int dx; - int dy; -}; - -struct live_sc_move_info { - Evas_Object *item; - Evas_Coord x; - Evas_Coord y; - Evas_Coord w; - Evas_Coord h; - - double relx; - double rely; -}; - -extern Evas_Object *live_scroller_add(Evas_Object *parent); -extern int live_scroller_append(Evas_Object *scroller, Evas_Object *item); -extern Evas_Object *live_scroller_remove(Evas_Object *scroller, int idx); -extern Evas_Object *live_scroller_get_item(Evas_Object *scroller, int idx); -extern int live_scroller_get_current(Evas_Object *scroller); -extern int live_scroller_loop_set(Evas_Object *scroller, int is_loop); - -extern int live_scroller_freeze(Evas_Object *scroller); -extern int live_scroller_thaw(Evas_Object *scroller); - -extern int live_scroller_anim_to(Evas_Object *scroller, double fps, int offset); -extern int live_scroller_go_to(Evas_Object *scroller, int idx); - -extern int live_scroller_update(Evas_Object *scroller); - -extern int live_scroller_remove_by_obj(Evas_Object *scroller, Evas_Object *obj); -extern int live_scroller_get_item_index(Evas_Object *scroller, Evas_Object *item); -extern int live_scroller_get_item_count(Evas_Object *scroller); - -/* End of a file */ diff --git a/live.viewer/include/main.h b/live.viewer/include/main.h deleted file mode 100644 index 3c142be..0000000 --- a/live.viewer/include/main.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * 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 Evas_Object *main_get_window(void); diff --git a/live.viewer/include/scroller.h b/live.viewer/include/scroller.h deleted file mode 100644 index f69575f..0000000 --- a/live.viewer/include/scroller.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 Evas_Object *scroller_create(Evas_Object *parent); -extern Evas_Object *scroller_peek_by_idx(Evas_Object *sc, int idx); -extern int scroller_peek_by_obj(Evas_Object *sc, Evas_Object *obj); -extern int scroller_append(Evas_Object *sc, Evas_Object *child); -extern int scroller_get_current_idx(Evas_Object *sc); -extern int scroller_peek_by_obj(Evas_Object *sc, Evas_Object *obj); -extern Evas_Object *scroller_get_page(Evas_Object *sc, int idx); -extern int scroller_is_scrolling(Evas_Object *sc); - -extern int scroller_add_stop_cb(Evas_Object *scroller, int (*cb)(Evas_Object *sc, void *data), void *data); -extern void scroller_del_stop_cb(Evas_Object *scroller, int (*cb)(Evas_Object *sc, void *data), void *data); - -extern int scroller_get_page_index(Evas_Object *sc, Evas_Object *page); - -extern void scroller_unlock(Evas_Object *sc); -extern void scroller_lock(Evas_Object *sc); - -extern int scroller_get_page_count(Evas_Object *sc); -extern int scroller_scroll_to(Evas_Object *sc, int idx); -extern int scroller_jump_to(Evas_Object *sc, int idx); - -extern int scroller_destroy(Evas_Object *sc); -extern int scroller_update(Evas_Object *sc, void *data); -extern int scroller_fast_scroll(Evas_Object *sc, int idx); -extern void scroller_loop_set(Evas_Object *sc, Eina_Bool val); -extern void scroller_quick_navi(Evas_Object *sc, Eina_Bool val); - -/* End of a file */ diff --git a/live.viewer/include/util.h b/live.viewer/include/util.h deleted file mode 100644 index 79ab46b..0000000 --- a/live.viewer/include/util.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * 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 const char *util_basename(const char *name); - -/* End of a file */ diff --git a/live.viewer/live.viewer.xml b/live.viewer/live.viewer.xml deleted file mode 100644 index 7a55872..0000000 --- a/live.viewer/live.viewer.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - Sung-jae Park - Live box simple viewer (native) - - - live-viewer.png - - - - diff --git a/live.viewer/packaging/live.viewer.spec b/live.viewer/packaging/live.viewer.spec deleted file mode 100644 index f817c32..0000000 --- a/live.viewer/packaging/live.viewer.spec +++ /dev/null @@ -1,41 +0,0 @@ -Name: live.viewer -Summary: viewer -Version: 0.0.1 -Release: 1 -Group: main/app -License: Flora License -Source0: %{name}-%{version}.tar.gz -BuildRequires: cmake, gettext-tools -BuildRequires: pkgconfig(dlog) -BuildRequires: pkgconfig(aul) -BuildRequires: pkgconfig(ail) -BuildRequires: pkgconfig(elementary) -BuildRequires: pkgconfig(appcore-efl) -BuildRequires: pkgconfig(livebox-viewer) -BuildRequires: pkgconfig(ecore-x) -BuildRequires: pkgconfig(livebox-service) -BuildRequires: pkgconfig(bundle) -BuildRequires: pkgconfig(capi-appfw-application) -BuildRequires: pkgconfig(capi-appfw-app-manager) -BuildRequires: edje-bin - -%description -Livebox viewer development library - -%prep -%setup -q - -%build -cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -make %{?jobs:-j%jobs} - -%install -rm -rf %{buildroot} -%make_install - -%post - -%files -%defattr(-,root,root,-) -/opt/usr/apps/live.viewer/* -/opt/share/* diff --git a/live.viewer/res/CMakeLists.txt b/live.viewer/res/CMakeLists.txt deleted file mode 100644 index 5f6447c..0000000 --- a/live.viewer/res/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -ADD_CUSTOM_TARGET(live-viewer.edj ALL - COMMAND edje_cc -id ${CMAKE_SOURCE_DIR}/res/image - ${CMAKE_CURRENT_SOURCE_DIR}/live-viewer.edc live-viewer.edj - DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/live-viewer.edc -) -ADD_DEPENDENCIES(${PROJECT_NAME} live-viewer.edj) -INSTALL(FILES live-viewer.edj DESTINATION ${PKGROOT}/res/edje) diff --git a/live.viewer/res/live-viewer.edc b/live.viewer/res/live-viewer.edc deleted file mode 100644 index fac023d..0000000 --- a/live.viewer/res/live-viewer.edc +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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. - */ - -images { - /* image: "a" COMP; */ -} - -collections { - group { - name: "layout"; - parts { - part { - name: "indicator"; - type: RECT; - mouse_events: 0; - description { - state: "default" 0.0; - rel1 { relative: 0.0 0.0; } - rel2 { relative: 1.0 100/1280; } - color: 0 0 0 0; - } - } - - part { - name: "delete,btn"; - type: SWALLOW; - mouse_events: 1; - description { - state: "default" 0.0; - rel1 { relative: 4/720 1.0; to_y, "viewer"; } - rel2 { relative: 716/720 900/1280; } - } - } - - part { - name: "controller"; /* size list */ - type: SWALLOW; - mouse_events: 1; - description { - state: "default" 0.0; - rel1 { relative: 0.0 1.0; to_y, "delete,btn"; } - rel2 { relative: 0.3 1.0; } - } - } - - part { - name: "logger"; - type: SWALLOW; - mouse_events: 1; - description { - state: "default" 0.0; - rel1 { relative: 1.0 1.0; to_x: "controller"; to_y: "delete,btn"; } - rel2 { relative: 1.0 1.0; } - } - } - - part { - name: "viewer"; - type: RECT; - mouse_events: 1; - description { - state: "default" 0.0; - rel1 { relative: 4/720 1.0; to, "indicator"; } - rel2 { relative: 716/720 800/1280; } - color: 255 255 255 255; - } - } - - part { - name: "event,blocker"; - type: RECT; - mouse_events: 1; - description { - state: "default" 0.0; - rel1 { relative: 0.0 0.0; } - rel2 { relative: 1.0 1.0; } - color: 0 0 0 0; - visible: 0; - } - description { - state: "show" 0.0; - inherit: "default" 0.0; - color: 50 50 50 50; - visible: 1; - } - } - - part { - name: "livebox"; - type: SWALLOW; - mouse_events: 1; - description { - state: "default" 0.0; - rel1 { relative: 0.4 0.4; to, "viewer"; } - rel2 { relative: 0.6 0.6; to, "viewer"; } - } - } - - part { - name: "pd"; - type: SWALLOW; - mouse_events: 1; - description { - state: "default" 0.0; - rel1 { relative: 0.0 0.95; to_y, "livebox"; } - rel2 { relative: 1.0 1.0; to_y, "livebox"; } - visible: 0; - align: 0.0 0.0; - } - - description { - state: "show" 0.0; - rel1 { relative: 0.0 1.0; to_y, "livebox"; } - rel2 { relative: 1.0 1.0; } - visible: 1; - align: 0.0 0.0; - } - } - } - - programs { - program { - name: "open,pd"; - source: "pd"; - signal: "open"; - action: STATE_SET "show" 0.0; - target: "pd"; - target: "event,blocker"; - transition: LINEAR 0.2; - } - program { - name: "hide,pd"; - source: "pd"; - signal: "close"; - action: STATE_SET "default" 0.0; - target: "pd"; - target: "event,blocker"; - transition: LINEAR 0.1; - after: "hide,pd,done"; - } - - program { - name: "hide,pd,done"; - action: SIGNAL_EMIT "hide,done" "pd"; - } - - program { - name: "event,blocker"; - source: "event,blocker"; - signal: "mouse,clicked,1"; - action: SIGNAL_EMIT "close" "pd"; - } - - program { - name: "pd,close,pd"; - source: "viewer"; - signal: "mouse,clicked,1"; - action: SIGNAL_EMIT "close" "pd"; - } - } - } -} diff --git a/live.viewer/src/dlist.c b/live.viewer/src/dlist.c deleted file mode 100644 index fa3082a..0000000 --- a/live.viewer/src/dlist.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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 -#include -#include - -#include "dlist.h" - -/*! - * \brief - * This dlist is called Modified Doubly Linked List. - * - * Noramlly, The dobule linked list contains address of previous and next element. - * This dlist also contains them, but the tail element only contains prev address. - * - * The head element's prev pointer indicates the last element. - * But the last element's next pointer indicates NIL. - * - * So we can find the last element while crawling this DList - * But we have to remember the address of the head element. - */ - -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; - - item->data = data; - - if (!list) { - item->prev = item; - item->next = NULL; - } else { - if (list->prev->next) - list->prev->next = item; - - item->prev = list->prev; - item->next = list; - - list->prev = item; - - } - - return item; -} - -struct dlist *dlist_remove(struct dlist *list, struct dlist *l) -{ - if (!list || !l) - return NULL; - - if (l == list) - list = l->next; - else - l->prev->next = l->next; - - if (l->next) - l->next->prev = l->prev; - /*! - * \note - * If the removed entry 'l' has no next element, it is the last element. - * In this case, check the existence of the list first, - * and if the list is not empty, update the 'prev' of the list (which is a head element of the list) - * - * If we didn't care about this, the head element(list) can indicates the invalid element. - */ - else if (list) - list->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; - - i = 0; - for (n = l; n; n = n->next) { - if (i == nth) - return n; - i++; - } - - return NULL; -} - -/* End of a file */ diff --git a/live.viewer/src/lb.c b/live.viewer/src/lb.c deleted file mode 100644 index 9870b4a..0000000 --- a/live.viewer/src/lb.c +++ /dev/null @@ -1,966 +0,0 @@ -/* - * 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 -#include - -#include - -#include -#include - -#include "main.h" -#include "util.h" -#include "debug.h" -#include "lb.h" -#include "scroller.h" - -#define FLICK_COND 100 - -static Evas_Object *create_canvas(Evas_Object *parent) -{ - Evas_Object *canvas; - - canvas = evas_object_image_add(evas_object_evas_get(parent)); - if (!canvas) - return NULL; - - evas_object_image_content_hint_set(canvas, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); - evas_object_image_colorspace_set(canvas, EVAS_COLORSPACE_ARGB8888); - evas_object_image_alpha_set(canvas, EINA_TRUE); - evas_object_move(canvas, 0, 0); - return canvas; -} - -static int update_pd_canvas(struct livebox *handle, Evas_Object *image) -{ - Evas_Native_Surface surface; - int w; - int h; - - DbgPrint("Updated\n"); - - switch (livebox_pd_type(handle)) { - case PD_TYPE_PIXMAP: - h = w = 0; - livebox_get_pdsize(handle, &w, &h); - if (w <= 0 || h <= 0) - break; - - //evas_object_image_size_set(image, w, h); - - DbgPrint("Update: %dx%d\n", w, h); - surface.version = EVAS_NATIVE_SURFACE_VERSION; - surface.type = EVAS_NATIVE_SURFACE_X11; - surface.data.x11.pixmap = livebox_pd_pixmap(handle); - surface.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get()); - evas_object_image_native_surface_set(image, &surface); - - evas_object_image_data_update_add(image, 0, 0, w, h); - evas_object_size_hint_max_set(image, w, h); - evas_object_resize(image, w, h); - evas_object_show(image); - break; - case PD_TYPE_BUFFER: - livebox_get_pdsize(handle, &w, &h); - if (w > 0 && h > 0) { - void *data; - - data = livebox_acquire_pdfb(handle); - if (data) { - evas_object_image_data_set(image, NULL); - evas_object_image_colorspace_set(image, EVAS_COLORSPACE_ARGB8888); - evas_object_image_alpha_set(image, EINA_TRUE); - evas_object_image_size_set(image, w, h); - evas_object_image_smooth_scale_set(image, EINA_TRUE); - evas_object_image_data_copy_set(image, data); - evas_object_image_data_update_add(image, 0, 0, w, h); - livebox_release_pdfb(data); - } - evas_object_resize(image, w, h); - //evas_object_size_hint_min_set(image, w, h); - evas_object_size_hint_max_set(image, w, h); - } - break; - case PD_TYPE_TEXT: - default: - break; - } - - return 0; -} - -static int update_canvas(struct livebox *handle, Evas_Object *image) -{ - Evas_Native_Surface surface; - const char *filename; - int w; - int h; - int type; - - DbgPrint("Updated\n"); - - switch (livebox_lb_type(handle)) { - case LB_TYPE_PIXMAP: - w = h = 0; - type = livebox_size(handle); - livebox_service_get_size(type, &w, &h); - if (w <= 0 || h <= 0) - break; - - DbgPrint("Update: %dx%d\n", w, h); - - //evas_object_image_size_set(image, w, h); - - surface.version = EVAS_NATIVE_SURFACE_VERSION; - surface.type = EVAS_NATIVE_SURFACE_X11; - surface.data.x11.pixmap = livebox_lb_pixmap(handle); - surface.data.x11.visual = ecore_x_default_visual_get(ecore_x_display_get(), ecore_x_default_screen_get()); - evas_object_image_native_surface_set(image, &surface); - - evas_object_image_data_update_add(image, 0, 0, w, h); - - evas_object_resize(image, w, h); - evas_object_size_hint_min_set(image, w, h); - evas_object_size_hint_max_set(image, w, h); - evas_object_show(image); - break; - case LB_TYPE_BUFFER: - w = h = 0; - type = livebox_size(handle); - livebox_service_get_size(type, &w, &h); - if (w > 0 && h > 0) { - void *data; - data = livebox_acquire_fb(handle); - if (data) { - evas_object_image_data_set(image, NULL); - evas_object_image_colorspace_set(image, EVAS_COLORSPACE_ARGB8888); - evas_object_image_alpha_set(image, EINA_TRUE); - evas_object_image_size_set(image, w, h); - evas_object_image_smooth_scale_set(image, EINA_TRUE); - evas_object_image_data_copy_set(image, data); - evas_object_image_data_update_add(image, 0, 0, w, h); - livebox_release_fb(data); - } - evas_object_resize(image, w, h); - evas_object_size_hint_min_set(image, w, h); - evas_object_size_hint_max_set(image, w, h); - } - break; - case LB_TYPE_IMAGE: - filename = livebox_filename(handle); - if (filename) { - const char *old; - evas_object_image_file_get(image, &old, NULL); - if (old && !strcmp(filename, old)) { - evas_object_image_reload(image); - } else { - evas_object_image_file_set(image, filename, NULL); - } - - w = h = 0; - type = livebox_size(handle); - livebox_service_get_size(type, &w, &h); - if (w > 0 && h > 0) { - evas_object_resize(image, w, h); - evas_object_size_hint_min_set(image, w, h); - evas_object_size_hint_max_set(image, w, h); - } - } - break; - case LB_TYPE_TEXT: - default: - break; - } - - return 0; -} - -static inline void prepend_log(struct livebox *handle, const char *buffer) -{ - Evas_Object *layout; - Evas_Object *logger; - - layout = livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout\n"); - return; - } - - logger = elm_object_part_content_get(layout, "logger"); - if (logger) - elm_list_item_prepend(logger, buffer, NULL, NULL, NULL, NULL); -} - -static int lb_event_cb(struct livebox *handle, enum livebox_event_type event, void *data) -{ - Evas_Object *layout; - Evas_Object *sc; - Evas_Object *pd; - Evas_Object *image; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) - return -EFAULT; - - switch (event) { - case LB_EVENT_LB_UPDATED: - DbgPrint("Contents: [%s]\n", livebox_content(handle)); - image = elm_object_part_content_get(layout, "livebox"); - if (image) - update_canvas(handle, image); - break; - case LB_EVENT_PD_UPDATED: - image = elm_object_part_content_get(layout, "pd"); - if (image) - update_pd_canvas(handle, image); - break; - case LB_EVENT_DELETED: - sc = evas_object_data_del(layout, "sc"); - if (sc) - scroller_peek_by_obj(sc, layout); - - evas_object_del(layout); - break; - case LB_EVENT_PD_DESTROYED: - pd = elm_object_part_content_unset(layout, "pd"); - if (pd) - evas_object_del(pd); - - sc = evas_object_data_del(layout, "sc"); - if (sc) - scroller_unlock(sc); - break; - default: - break; - } - - return 0; -} - -static int lb_fault_cb(enum livebox_fault_type event, - const char *pkgname, const char *filename, - const char *funcname, void *data) -{ - DbgPrint("pkgname: %s\nfilename: %s\n:funcname: %s\n", pkgname, filename, funcname); - return 0; -} - -static void del_cb(struct livebox *handle, int ret, void *data) -{ - Evas_Object *layout = data; - Evas_Object *sc; - - sc = evas_object_data_del(layout, "sc"); - if (sc) { - DbgPrint("Scroller: %p\n", sc); - scroller_peek_by_obj(sc, layout); - } - - DbgPrint("Delete a layout object\n"); - evas_object_del(layout); -} - -static void delete_btn_cb(void *handle, Evas_Object *obj, void *event_info) -{ - int ret; - Evas_Object *layout; - layout = livebox_get_data(handle); - DbgPrint("Livebox Get Data %p - %p\n", handle, layout); - ret = livebox_del(handle, del_cb, layout); - if (ret < 0) { - char buffer[256]; - snprintf(buffer, sizeof(buffer), "Delete returns: %d\n", ret); - prepend_log(handle, buffer); - } -} - -static void error_popup(Evas_Object *parent, struct livebox *handle, int ret) -{ - ErrPrint("Failed to add a box: %d\n", ret); - return; -} - -static void resize_cb(struct livebox *handle, int ret, void *data) -{ - Evas_Object *layout; - Evas_Object *log_list; - char buffer[256]; - - layout = livebox_get_data(handle); - if (!layout) - return; - - log_list = elm_object_part_content_get(layout, "logger"); - if (!log_list) - return; - - snprintf(buffer, sizeof(buffer) - 1, "Resize: %d", ret); - elm_list_item_prepend(log_list, buffer, NULL, NULL, NULL, NULL); -} - -static void resize_click_cb(void *handle, Evas_Object *obj, void *event_info) -{ - Elm_Object_Item *item; - const char *label; - int w; - int h; - int size_type; - - item = elm_list_selected_item_get(obj); - if (!item) - return; - - label = elm_object_item_part_text_get(item, NULL); - if (!label) - return; - - sscanf(label, "%dx%d", &w, &h); - size_type = livebox_service_size_type(w, h); - - livebox_resize(handle, size_type, resize_cb, NULL); -} - -static void create_resize_controller(struct livebox *handle, Evas_Object *layout) -{ - Evas_Object *size_list; - char buffer[256]; - int sizes[NR_OF_SIZE_LIST]; - int cnt; - int i; - int w; - int h; - - size_list = elm_list_add(layout); - cnt = sizeof(sizes) / sizeof(sizes[0]); - livebox_get_supported_sizes(handle, &cnt, sizes); - for (i = 0; i < cnt; i++) { - livebox_service_get_size(sizes[i], &w, &h); - snprintf(buffer, sizeof(buffer) - 1, "%dx%d", w, h); - - elm_list_item_append(size_list, buffer, NULL, NULL, resize_click_cb, handle); - } - evas_object_show(size_list); - elm_list_go(size_list); - evas_object_size_hint_weight_set(size_list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(size_list, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_part_content_set(layout, "controller", size_list); -} - -static void create_logger(struct livebox *handle, Evas_Object *layout) -{ - Evas_Object *log_list; - - log_list = elm_list_add(layout); - if (!log_list) - return; - - elm_list_item_prepend(log_list, "Created", NULL, NULL, NULL, NULL); - evas_object_show(log_list); - elm_list_go(log_list); - - evas_object_size_hint_weight_set(log_list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_size_hint_align_set(log_list, EVAS_HINT_FILL, EVAS_HINT_FILL); - elm_object_part_content_set(layout, "logger", log_list); -} - -struct event_data { - Evas_Coord x; - Evas_Coord y; - - enum flick { - FLICK_UNKNOWN = 0x00, - FLICK_DOWN = 0x01, - FLICK_UP = 0x02, - } flick; -}; - -static void pd_closed_cb(struct livebox *handle, int ret, void *data) -{ - evas_object_del(data); -} - -static void pd_hide_done_cb(void *data, Evas_Object *obj, const char *emission, const char *source) -{ - Evas_Object *pd; - Evas_Object *sc; - - sc = evas_object_data_get(obj, "sc"); - scroller_unlock(sc); - - elm_object_signal_callback_del(obj, emission, source, pd_hide_done_cb); - pd = elm_object_part_content_unset(obj, "pd"); - livebox_destroy_pd(data, pd_closed_cb, pd); -} - -static void pd_mouse_up_cb(void *handle, Evas *e, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Up *up = event_info; - Evas_Coord x, y, w, h; - double rx, ry; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - - rx = (double)(up->canvas.x - x) / (double)w; - ry = (double)(up->canvas.y - y) / (double)h; - DbgPrint("%dx%d - %dx%d, %lfx%lf\n", x, y, w, h, rx, ry); - livebox_content_event(handle, PD_MOUSE_UP, rx, ry); -} - -static void pd_mouse_down_cb(void *handle, Evas *e, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Down *down = event_info; - Evas_Coord x, y, w, h; - double rx, ry; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - rx = (double)(down->canvas.x - x) / (double)w; - ry = (double)(down->canvas.y - y) / (double)h; - DbgPrint("%dx%d - %dx%d, %lfx%lf\n", x, y, w, h, rx, ry); - livebox_content_event(handle, PD_MOUSE_DOWN, rx, ry); -} - -static void pd_mouse_move_cb(void *handle, Evas *e, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Move *move = event_info; - Evas_Coord x, y, w, h; - double rx, ry; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - rx = (double)(move->cur.canvas.x - x) / (double)w; - ry = (double)(move->cur.canvas.y - y) / (double)h; - DbgPrint("%dx%d - %dx%d, %lfx%lf\n", x, y, w, h, rx, ry); - livebox_content_event(handle, PD_MOUSE_MOVE, rx, ry); -} - -static void pd_created_cb(struct livebox *handle, int ret, void *data) -{ - Evas_Object *layout; - Evas_Object *pd_image; - Evas_Object *sc; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) - return; - - sc = evas_object_data_get(layout, "sc"); - - pd_image = create_canvas(layout); - if (!pd_image) - return; - - evas_object_event_callback_add(pd_image, EVAS_CALLBACK_MOUSE_UP, pd_mouse_up_cb, handle); - evas_object_event_callback_add(pd_image, EVAS_CALLBACK_MOUSE_DOWN, pd_mouse_down_cb, handle); - evas_object_event_callback_add(pd_image, EVAS_CALLBACK_MOUSE_MOVE, pd_mouse_move_cb, handle); - - update_pd_canvas(handle, pd_image); - - elm_object_signal_callback_add(layout, "hide,done", "pd", pd_hide_done_cb, handle); - elm_object_part_content_set(layout, "pd", pd_image); - elm_object_signal_emit(layout, "open", "pd"); - scroller_lock(sc); -} - -static void lb_mouse_up_cb(void *handle, Evas *e, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Up *up = event_info; - Evas_Coord x, y, w, h; - struct event_data *evt; - - evt = evas_object_data_del(obj, "evt"); - if (!evt) - return; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - - if (livebox_lb_type(handle) == LB_TYPE_PIXMAP || livebox_lb_type(handle) == LB_TYPE_BUFFER) { - double rx, ry; - rx = (double)(up->canvas.x - x) / (double)w; - ry = (double)(up->canvas.y - y) / (double)h; - livebox_content_event(handle, LB_MOUSE_UP, rx, ry); - } - - if (x < up->canvas.x && up->canvas.x < x + w) { - if (y < up->canvas.y && up->canvas.y < y + h) { - livebox_click(handle, (double)x / (double)w, (double)y / (double)h); - } - } - - if (evt->flick == FLICK_DOWN && (up->canvas.y - evt->y) > (FLICK_COND>>1)) { - int ret; - /* Open PD */ - ret = livebox_create_pd_with_position(handle, 0.5, 0.0, pd_created_cb, NULL); - } - - free(evt); -} - -static void lb_mouse_down_cb(void *handle, Evas *e, Evas_Object *obj, void *event_info) -{ - struct event_data *evt; - Evas_Event_Mouse_Down *down = event_info; - Evas_Object *layout; - Evas_Object *sc; - - layout = livebox_get_data(handle); - if (!layout) - return; - - sc = evas_object_data_get(layout, "sc"); - if (!sc) - return; - - if (scroller_is_scrolling(sc)) - return; - - if (livebox_lb_type(handle) == LB_TYPE_PIXMAP || livebox_lb_type(handle) == LB_TYPE_BUFFER) { - Evas_Coord x, y, w, h; - double rx, ry; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - rx = (double)(down->canvas.x - x) / (double)w; - ry = (double)(down->canvas.y - y) / (double)h; - livebox_content_event(handle, LB_MOUSE_DOWN, rx, ry); - } - - evt = evas_object_data_get(obj, "evt"); - if (evt) { - ErrPrint("Huh?"); - } else { - evt = malloc(sizeof(*evt)); - if (!evt) { - ErrPrint("Heap: %s\n", strerror(errno)); - return; - } - } - - evas_object_data_set(obj, "evt", evt); - - evt->x = down->canvas.x; - evt->y = down->canvas.y; - evt->flick = FLICK_UNKNOWN; -} - -static void lb_mouse_move_cb(void *handle, Evas *e, Evas_Object *obj, void *event_info) -{ - Evas_Event_Mouse_Move *move = event_info; - struct event_data *evt; - - evt = evas_object_data_get(obj, "evt"); - if (!evt) - return; - - if (livebox_lb_type(handle) == LB_TYPE_PIXMAP || livebox_lb_type(handle) == LB_TYPE_BUFFER) { - Evas_Coord x, y, w, h; - double rx, ry; - - evas_object_geometry_get(obj, &x, &y, &w, &h); - rx = (double)(move->cur.canvas.x - x) / (double)w; - ry = (double)(move->cur.canvas.y - y) / (double)h; - livebox_content_event(handle, LB_MOUSE_MOVE, rx, ry); - } - - if ((move->cur.canvas.x - move->prev.canvas.x) > FLICK_COND) { - evt->flick = FLICK_UNKNOWN; - return; - } else if ((move->cur.canvas.x - move->prev.canvas.x) < -FLICK_COND) { - evt->flick = FLICK_UNKNOWN; - return; - } - - if ((move->cur.canvas.y - move->prev.canvas.y) > 0) { - if (evt->flick != FLICK_DOWN) - evt->flick = FLICK_DOWN; - } else if ((move->cur.canvas.y - move->prev.canvas.y) < 0) { - if (evt->flick != FLICK_UP) - evt->flick = FLICK_UP; - } -} - -static int lb_update_begin(struct livebox *handle) -{ - DbgPrint("%p\n", handle); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "begin"); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - - return 0; -} - -static int lb_update_end(struct livebox *handle) -{ - DbgPrint("%p\n", handle); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "end"); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - - return 0; -} - -static int lb_update_text(struct livebox *handle, const char *id, const char *part, const char *data) -{ - DbgPrint("%p\n", handle); - DbgPrint("id: [%s], part[%s], data[%s]\n", id, part, data); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "%s=%s", part, data); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - - return 0; -} - -static int lb_update_image(struct livebox *handle, const char *id, const char *part, const char *data) -{ - DbgPrint("%p\n", handle); - DbgPrint("id: [%s], part[%s], data[%s]\n", id, part, data); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "%s=%s", part, data); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - - return 0; -} - -static int lb_update_script(struct livebox *handle, const char *id, const char *part, const char *file, const char *group) -{ - DbgPrint("%p\n", handle); - DbgPrint("id: [%s], part[%s], file[%s], group[%s]\n", id, part, file, group); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "%s=%s, %s", part, file, group); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - - return 0; -} - -static int lb_update_signal(struct livebox *handle, const char *id, const char *emission, const char *signal) -{ - DbgPrint("%p\n", handle); - DbgPrint("id: [%s], emission[%s], signal[%s]\n", id, emission, signal); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "%s,%s", emission, signal); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - return 0; -} - -static int lb_update_drag(struct livebox *handle, const char *id, const char *part, double dx, double dy) -{ - DbgPrint("%p\n", handle); - DbgPrint("id: [%s], part[%s], pos[%lfx%lf]\n", id, part, dx, dy); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "%s=%lfx%lf", part, dx, dy); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - return 0; -} - -static int lb_update_info_size(struct livebox *handle, const char *id, int w, int h) -{ - DbgPrint("%p\n", handle); - DbgPrint("id: [%s], size[%dx%d]\n", id, w, h); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "%dx%d", w, h); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - return 0; -} - -static int lb_update_info_category(struct livebox *handle, const char *id, const char *category) -{ - DbgPrint("%p\n", handle); - DbgPrint("id: [%s], category: [%s]\n", id, category); - - Evas_Object *layout; - Evas_Object *list; - char buffer[80]; - - layout = (Evas_Object *)livebox_get_data(handle); - if (!layout) { - ErrPrint("Failed to get layout object\n"); - return 0; - } - - list = elm_object_part_content_get(layout, "livebox"); - if (!list) { - ErrPrint("Failed to get list\n"); - return 0; - } - - snprintf(buffer, sizeof(buffer), "%s=%s", id, category); - elm_list_item_prepend(list, buffer, NULL, NULL, NULL, NULL); - return 0; -} - -static void livebox_added_cb(struct livebox *handle, int ret, void *data) -{ - Evas_Object *layout; - Evas_Object *btn; - int w; - int h; - int type; - int idx; - - DbgPrint("%s - %d\n", livebox_pkgname(handle), ret); - - if (ret != 0) { - error_popup(main_get_window(), handle, ret); - return; - } - - layout = elm_layout_add(main_get_window()); - if (!layout) { - ErrPrint("Failed to add a layout\n"); - return; - } - - if (elm_layout_file_set(layout, PKGROOT "/res/edje/live-viewer.edj", "layout") == EINA_FALSE) { - DbgPrint("Failed to add a layout\n"); - evas_object_del(layout); - return; - } - - if (livebox_lb_type(handle) == LB_TYPE_TEXT) { - Evas_Object *list; - static struct livebox_script_operators ops = { - .update_begin = lb_update_begin, - .update_end = lb_update_end, - .update_text = lb_update_text, - .update_image = lb_update_image, - .update_script = lb_update_script, - .update_signal = lb_update_signal, - .update_drag = lb_update_drag, - .update_info_size = lb_update_info_size, - .update_info_category = lb_update_info_category, - }; - - list = elm_list_add(layout); - if (!list) { - evas_object_del(layout); - return; - } - - (void)livebox_set_text_handler(handle, &ops); - elm_object_part_content_set(layout, "livebox", list); - elm_list_go(list); - } else { - Evas_Object *lb_image; - lb_image = create_canvas(layout); - if (!lb_image) { - ErrPrint("Failed to create a canvas\n"); - evas_object_del(layout); - return; - } - - evas_object_event_callback_add(lb_image, EVAS_CALLBACK_MOUSE_UP, lb_mouse_up_cb, handle); - evas_object_event_callback_add(lb_image, EVAS_CALLBACK_MOUSE_DOWN, lb_mouse_down_cb, handle); - evas_object_event_callback_add(lb_image, EVAS_CALLBACK_MOUSE_MOVE, lb_mouse_move_cb, handle); - - w = 0; - h = 0; - type = livebox_size(handle); - if (type != LB_SIZE_TYPE_UNKNOWN) { - livebox_service_get_size(type, &w, &h); - DbgPrint("%dx%d\n", w, h); - } - evas_object_resize(lb_image, w, h); - evas_object_show(lb_image); - - update_canvas(handle, lb_image); - - btn = elm_button_add(main_get_window()); - if (btn) { - elm_object_text_set(btn, "Delete"); - evas_object_smart_callback_add(btn, "clicked", delete_btn_cb, handle); - elm_object_part_content_set(layout, "delete,btn", btn); - } - - elm_object_part_content_set(layout, "livebox", lb_image); - } - evas_object_resize(layout, 720, 1280); - evas_object_show(layout); - - create_resize_controller(handle, layout); - create_logger(handle, layout); - - livebox_set_data(handle, layout); - DbgPrint("Livebox Set Data: %p - %p\n", handle, layout); - evas_object_data_set(layout, "sc", data); - - scroller_append(data, layout); - - idx = scroller_get_page_index(data, layout); - DbgPrint("Scroll to %d\n", idx); - scroller_scroll_to(data, idx); -} - -int lb_add(Evas_Object *sc, const char *pkgname) -{ - int w, h; - struct livebox *handle; - - evas_object_geometry_get(sc, NULL, NULL, &w, &h); - - DbgPrint("sc: %dx%d, package: %s\n", w, h, pkgname); - livebox_activate(pkgname, NULL, NULL); - - handle = livebox_add(pkgname, "default", "user,created", "default", - DEFAULT_PERIOD, livebox_added_cb, sc); - if (!handle) { - ErrPrint("Failed to add a new livebox\n"); - return -EFAULT; - } - - return 0; -} - -int lb_init(void) -{ - livebox_init(ecore_x_display_get()); - livebox_set_event_handler(lb_event_cb, NULL); - livebox_set_fault_handler(lb_fault_cb, NULL); - return 0; -} - -int lb_fini(void) -{ - livebox_fini(); - return 0; -} - -/* End of a file */ diff --git a/live.viewer/src/live_scroller.c b/live.viewer/src/live_scroller.c deleted file mode 100644 index 2b88939..0000000 --- a/live.viewer/src/live_scroller.c +++ /dev/null @@ -1,1457 +0,0 @@ -/* - * 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 - -#include - -#include "live_scroller.h" -#include "util.h" -#include "debug.h" - -#define SAMPLE_MAX 10 -#define EVT_PERIOD 0.016 /* 60 fps */ -#define EVT_SAMPLE_PERIOD 9 -#define DRAG_SENS 100 -#define ANIM_MIN 40 -#define ANIM_UNIT 15 - -struct item_list_entry { - struct item_list_entry *prev; - struct item_list_entry *next; - - Evas_Object *data; - Evas_Coord x; - Evas_Coord y; - Evas_Coord w; - Evas_Coord h; -}; - -struct evt_info { - Evas_Coord x; - unsigned int timestamp; -}; - -struct evt_queue { - struct evt_info ei[SAMPLE_MAX]; - int front; - int rear; - int cnt; - unsigned int old_timestamp; -}; - -struct widget_data { - Eina_Bool is_loop; - Eina_Bool is_freezed; - - struct item_list_entry *item_list; - - int item_cnt; - struct item_list_entry *curlist; - struct item_list_entry *tolist; - - Eina_Bool drag_started; - Eina_Bool is_pressed; - Evas_Coord press_x; - Evas_Coord press_y; - - Ecore_Timer *sc_anim_timer; - int sc_anim_dx; - - Evas_Object *clip; - Evas_Object *evt_layer; - Evas_Object *scroller; - - Evas_Coord clip_bx; - Evas_Coord clip_bw; - - struct evt_queue evtq; - Ecore_Timer *evt_emulator; - Evas_Coord old_x; - unsigned int prev_timestamp; -}; - -#ifdef PROFILE -#define PROFILE_START() \ -static int _exec_cnt = 0; \ -struct timeval _stv, _etv; \ -long _elapsed; \ -gettimeofday(&_stv, NULL); - -#define PROFILE_END() \ -do { \ - _exec_cnt++; \ - gettimeofday(&_etv, NULL); \ - _elapsed = (_etv.tv_sec - _stv.tv_sec) * 1000000l + (_etv.tv_usec - _stv.tv_usec); \ - DbgPrint("[%d] Elapsed time: %lu\n", _exec_cnt, _elapsed); \ -} while (0) -#else -#define PROFILE_START() -#define PROFILE_END() -#endif - -#define LIST_NEXT(list) ((list)->next) -#define LIST_PREV(list) ((list)->prev) -#define LIST_DATA(list) ((list) ? (list)->data : NULL) - -static inline void LIST_ITEM_GEO_SET(struct item_list_entry *list, int x, int y, int w, int h) -{ - list->x = x; - list->y = y; - list->w = w; - list->h = h; -} - -static inline void LIST_ITEM_GEO_GET(struct item_list_entry *list, int *x, int *y, int *w, int *h) -{ - if (x) - *x = list->x; - if (y) - *y = list->y; - if (w) - *w = list->w; - if (h) - *h = list->h; -} - -static inline struct item_list_entry *list_item_append(struct item_list_entry *list, void *obj) -{ - struct item_list_entry *item; - - item = malloc(sizeof(*item)); - if (!item) - return NULL; - - item->data = obj; - - if (list) { - list->prev->next = item; - item->prev = list->prev; - - item->next = list; - list->prev = item; - } else{ - item->prev = item; - item->next = item; - list = item; - } - - return list; -} - -static inline void *list_item_nth(struct item_list_entry *list, int idx) -{ - if (!list) - return NULL; - - while (--idx >= 0) - list = list->next; - - return list->data; -} - -static inline struct item_list_entry *list_item_nth_list(struct item_list_entry *list, int idx) -{ - if (!list) - return NULL; - - while (--idx >= 0) - list = list->next; - - return list; -} - -static inline struct item_list_entry *list_item_find(struct item_list_entry *list, void *data) -{ - struct item_list_entry *item; - - if (!list) - return NULL; - - item = list; - do { - if (LIST_DATA(item) == data) - return item; - - item = LIST_NEXT(item); - } while (item != list); - - return NULL; -} - -static inline struct item_list_entry *list_item_remove(struct item_list_entry *list, void *data) -{ - struct item_list_entry *item; - - if (!list) { - ErrPrint("List is not valid\n"); - return NULL; - } - - DbgPrint("Start\n"); - item = list; - do { - if (LIST_DATA(item) == data) { - DbgPrint("ITEM is removed\n"); - if (item == list) { - if (list == LIST_NEXT(list)) - list = NULL; - else - list = LIST_NEXT(list); - } - - item->prev->next = item->next; - item->next->prev = item->prev; - free(item); - break; - } - - item = LIST_NEXT(item); - } while (item != list); - DbgPrint("End\n"); - - return list; -} - -static inline void *list_item_last(struct item_list_entry *list) -{ - if (!list) - return NULL; - - return list->prev->data; -} - -static inline struct item_list_entry *list_item_last_list(struct item_list_entry *list) -{ - if (!list) - return NULL; - - return list->prev; -} - -static inline int list_item_count(struct item_list_entry *list) -{ - struct item_list_entry *n; - int cnt; - - if (!list) - return 0; - - cnt = 0; - n = list; - do { - cnt++; - n = LIST_NEXT(n); - } while (n != list); - - return cnt; -} - -static inline int list_item_idx(struct widget_data *sc_data, struct item_list_entry *ilist) -{ - int idx; - idx = 0; - - while (ilist != sc_data->item_list) { - idx++; - ilist = LIST_PREV(ilist); - } - - return idx; -} - -static inline void init_evtq(struct evt_queue *evtq) -{ - evtq->front = 0; - evtq->rear = 0; - evtq->cnt = 0; - evtq->old_timestamp = 0; -} - -static inline void dq_evt(struct evt_queue *evtq) -{ - if (evtq->cnt <= 0) - return; - evtq->front++; - if (evtq->front >= SAMPLE_MAX) - evtq->front -= SAMPLE_MAX; - evtq->cnt--; -} - -static inline void enq_evt(struct evt_queue *evtq, Evas_Coord x, unsigned int timestamp) -{ - unsigned int t_diff; - int replace; - - replace = 0; - t_diff = timestamp - evtq->old_timestamp; - - if (evtq->cnt <= 0) - evtq->old_timestamp = timestamp; - else if (t_diff > EVT_SAMPLE_PERIOD) - evtq->old_timestamp += EVT_SAMPLE_PERIOD * (t_diff / EVT_SAMPLE_PERIOD); - else - replace = 1; - - if (!replace) { - if (evtq->cnt >= SAMPLE_MAX) - dq_evt(evtq); - evtq->rear++; - if (evtq->rear >= SAMPLE_MAX) - evtq->rear -= SAMPLE_MAX; - evtq->cnt++; - } - - evtq->ei[evtq->rear].x = x; - evtq->ei[evtq->rear].timestamp = evtq->old_timestamp; -} - -static inline Evas_Coord get_evt_avg(struct evt_queue *evtq) -{ - int i; - int rear; - Evas_Coord x; - int weight; - int t; - - t = (int)(ecore_time_get() * 1000); - rear = evtq->rear; - - x = 0; - for (i = 0; i < evtq->cnt; i += weight) { - weight = (t - evtq->ei[rear].timestamp) / EVT_SAMPLE_PERIOD; - if (weight > (evtq->cnt - i)) - weight = evtq->cnt - i; - else - weight = 1; - - x += evtq->ei[rear].x * weight; - t = evtq->ei[rear].timestamp; - rear--; - if (rear < 0) - rear += SAMPLE_MAX; - } - - x /= evtq->cnt; - return x; -} - -/* Move the item to given direction to fit its coordinates to border */ -static inline int calc_anim_dx_with_dir(struct widget_data *sc_data, int *dir) -{ - Evas_Coord x, w; - - LIST_ITEM_GEO_GET(sc_data->curlist, &x, NULL, &w, NULL); - sc_data->sc_anim_dx = 0; - - if (*dir < 0) { - DbgPrint("MOVE to LEFT\n"); - if (x < sc_data->clip_bx) { - (*dir)++; - - if (sc_data->tolist == sc_data->item_list) { - if (!sc_data->is_loop) { - *dir = 0; - DbgPrint("Looping is disabled\n"); - return -EINVAL; - } - } - - sc_data->tolist = LIST_PREV(sc_data->tolist); - sc_data->sc_anim_dx = sc_data->clip_bx - x /*- w*/; - } else { - sc_data->sc_anim_dx = sc_data->clip_bx - x; - } - } else if (*dir > 0) { - DbgPrint("MOVE to RIGHT\n"); - if (x < sc_data->clip_bx) { - sc_data->sc_anim_dx = sc_data->clip_bx - x; - } else if (x > sc_data->clip_bx) { - struct item_list_entry *newlist; - - (*dir)--; - newlist = LIST_NEXT(sc_data->tolist); - if (newlist == sc_data->item_list) { - if (!sc_data->is_loop) { - *dir = 0; - DbgPrint("Looping is disabled\n"); - return -EINVAL; - } - } - sc_data->tolist = newlist; - sc_data->sc_anim_dx = sc_data->clip_bx - x; /*(sc_data->clip_bx + sc_data->clip_bw) - x;*/ - } - } - - return 0; -} - -static inline void move_item(struct widget_data *sc_data, struct item_list_entry *ilist, int x, int y, int w, int h) -{ - struct live_sc_move_info info; - - info.item = LIST_DATA(ilist); - - info.relx = ((double)x - (double)sc_data->clip_bx) / (double)sc_data->clip_bw; - - LIST_ITEM_GEO_SET(ilist, x, y, w, h); - info.x = x; - info.y = y; - info.w = w; - info.h = h; - - evas_object_smart_callback_call(sc_data->scroller, "item,moved", &info); -} - -static struct item_list_entry *update_items_geo(struct widget_data *sc_data, int dx) -{ - Evas_Coord sx, sw; - Evas_Coord y, w, h; - struct item_list_entry *ilist; - struct item_list_entry *newlist; - struct item_list_entry *boundary; - int bx_bw; - register int x; - - LIST_ITEM_GEO_GET(sc_data->curlist, &sx, &y, &sw, &h); - - bx_bw = sc_data->clip_bx + sc_data->clip_bw; - - sx += dx; - move_item(sc_data, sc_data->curlist, sx, y, sw, h); - - newlist = NULL; - - if (sc_data->item_cnt < 3) { - ilist = LIST_NEXT(sc_data->curlist); - LIST_ITEM_GEO_GET(ilist, NULL, &y, &w, &h); - - if (sx + sw < bx_bw) { - x = sx + sw; - move_item(sc_data, ilist, x, y, w, h); - if (x == sc_data->clip_bx || (x < sc_data->clip_bx && (x + w) > sc_data->clip_bx)) - newlist = ilist; - } else if (sx > 0) { - x = sx - w; - move_item(sc_data, ilist, x, y, w, h); - if (x == sc_data->clip_bx || (x > sc_data->clip_bx && x < bx_bw)) { - newlist = ilist; - } - } - - goto out; - } - - x = sx; - boundary = NULL; - ilist = sc_data->curlist; - do { - if (!sc_data->is_loop && ilist == sc_data->item_list) - break; - - ilist = LIST_PREV(ilist); - if (!ilist) - break; - - LIST_ITEM_GEO_GET(ilist, NULL, &y, &w, &h); - x -= w; - move_item(sc_data, ilist, x, y, w, h); - - if (dx > 0 && !newlist) { - if ((x == sc_data->clip_bx) || (x > sc_data->clip_bx && x < bx_bw)) - newlist = ilist; - } - - boundary = ilist; - } while (x > sc_data->clip_bx); - - x = sx; - w = sw; - ilist = sc_data->curlist; - do { - ilist = LIST_NEXT(ilist); - if (!ilist || (!sc_data->is_loop && ilist == sc_data->item_list) || ilist == boundary) - break; - - x += w; - LIST_ITEM_GEO_GET(ilist, NULL, &y, &w, &h); - move_item(sc_data, ilist, x, y, w, h); - - if (dx < 0 && !newlist) { - if ((x == sc_data->clip_bx) || (x < sc_data->clip_bx && (x + w) > sc_data->clip_bx)) - newlist = ilist; - } - } while (x < bx_bw); - -out: - if (newlist) - sc_data->curlist = newlist; - - return newlist; -} - -static Eina_Bool emulate_evt(void *data) -{ - PROFILE_START(); - struct widget_data *sc_data; - Evas_Coord x; - Evas_Coord dx; - struct item_list_entry *newlist; - - sc_data = data; - - x = get_evt_avg(&sc_data->evtq); - if (x == sc_data->old_x) { - PROFILE_END(); - return ECORE_CALLBACK_RENEW; - } - - dx = x - sc_data->old_x; - sc_data->old_x = x; - - newlist = update_items_geo(sc_data, dx); - if (newlist) { - int idx; - - idx = list_item_idx(sc_data, newlist); - evas_object_smart_callback_call(sc_data->scroller, "page,changed", (void *)idx); - } - PROFILE_END(); - return ECORE_CALLBACK_RENEW; -} - -static void evt_mouse_down_cb(void *data, Evas *e, Evas_Object *evt_layer, void *event_info) -{ - Evas_Event_Mouse_Down *down; - struct widget_data *sc_data; - - sc_data = data; - down = event_info; - - sc_data->is_pressed = EINA_TRUE; - sc_data->press_x = down->canvas.x; - sc_data->press_y = down->canvas.y; - sc_data->old_x = down->canvas.x; - - if (!sc_data->is_freezed) { - init_evtq(&sc_data->evtq); - enq_evt(&sc_data->evtq, down->canvas.x, down->timestamp); - } -} - -static void evt_mouse_up_cb(void *data, Evas *e, Evas_Object *evt_layer, void *event_info) -{ - Evas_Event_Mouse_Up *up; - struct widget_data *sc_data; - struct live_sc_drag_info info; - - sc_data = data; - - if (!sc_data->is_pressed) - return; - - sc_data->is_pressed = EINA_FALSE; - - if (sc_data->evt_emulator) { - ecore_timer_del(sc_data->evt_emulator); - sc_data->evt_emulator = NULL; - } - - if (sc_data->drag_started == EINA_FALSE) { - DbgPrint("drag is not started\n"); - return; - } - - up = event_info; - - info.dx = up->canvas.x - sc_data->press_x; - info.dy = up->canvas.y - sc_data->press_y; - - sc_data->drag_started = EINA_FALSE; - - evas_object_smart_callback_call(sc_data->scroller, "drag,stop", &info); -} - -static void evt_mouse_move_cb(void *data, Evas *e, Evas_Object *evt_layer, void *event_info) -{ - struct widget_data *sc_data; - Evas_Event_Mouse_Move *move; - - sc_data = data; - - if (sc_data->is_pressed == EINA_FALSE) - return; - - if (sc_data->item_cnt <= 1) - return; - - if (sc_data->is_freezed) - return; - - move = event_info; - - if (sc_data->drag_started == EINA_FALSE) { - if (abs(move->cur.canvas.x - sc_data->press_x) < DRAG_SENS) - return; - - if (sc_data->sc_anim_timer) { - ecore_timer_del(sc_data->sc_anim_timer); - sc_data->sc_anim_timer = NULL; - } - - evas_object_smart_callback_call(sc_data->scroller, "drag,start", NULL); - sc_data->drag_started = EINA_TRUE; - } - - sc_data->prev_timestamp = move->timestamp; - enq_evt(&sc_data->evtq, move->cur.canvas.x, move->timestamp); - if (!sc_data->evt_emulator) { - if (!sc_data->curlist) - sc_data->curlist = sc_data->item_list; - - sc_data->evt_emulator = ecore_timer_add(EVT_PERIOD, emulate_evt, sc_data); - } -} - -static inline int prepare_evt_layer(struct widget_data *sc_data) -{ - Evas *e; - - e = evas_object_evas_get(sc_data->scroller); - if (!e) - return -EFAULT; - - sc_data->evt_layer = evas_object_rectangle_add(e); - if (!sc_data->evt_layer) - return -EFAULT; - - evas_object_smart_member_add(sc_data->evt_layer, sc_data->scroller); - - evas_object_color_set(sc_data->evt_layer, 255, 255, 255, 0); - evas_object_show(sc_data->evt_layer); - evas_object_repeat_events_set(sc_data->evt_layer, EINA_TRUE); - - evas_object_event_callback_add(sc_data->evt_layer, - EVAS_CALLBACK_MOUSE_DOWN, evt_mouse_down_cb, sc_data); - - evas_object_event_callback_add(sc_data->evt_layer, - EVAS_CALLBACK_MOUSE_UP, evt_mouse_up_cb, sc_data); - - evas_object_event_callback_add(sc_data->evt_layer, - EVAS_CALLBACK_MOUSE_MOVE, evt_mouse_move_cb, sc_data); - - evas_object_clip_set(sc_data->evt_layer, sc_data->clip); - return 0; -} - -static void live_add(Evas_Object *scroller) -{ - struct widget_data *sc_data; - Evas *e; - int ret; - - sc_data = calloc(1, sizeof(*sc_data)); - if (!sc_data) - return; - - e = evas_object_evas_get(scroller); - if (!e) { - free(sc_data); - return; - } - - evas_object_smart_data_set(scroller, sc_data); - - sc_data->clip = evas_object_rectangle_add(e); - if (!sc_data->clip) { - free(sc_data); - return; - } - - sc_data->is_pressed = EINA_FALSE; - sc_data->drag_started = EINA_FALSE; - sc_data->tolist = NULL; - sc_data->curlist = NULL; - sc_data->item_list = NULL; - sc_data->scroller = scroller; - - evas_object_smart_member_add(sc_data->clip, sc_data->scroller); - - ret = prepare_evt_layer(sc_data); - if (ret < 0) { - evas_object_del(sc_data->clip); - free(sc_data); - } - - return; -} - -static void live_del(Evas_Object *scroller) -{ - struct widget_data *sc_data; - Evas_Object *item; - struct item_list_entry *ilist; - struct item_list_entry *next; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - ilist = sc_data->item_list; - if (ilist) { - do { - next = LIST_NEXT(ilist); - item = LIST_DATA(ilist); - evas_object_clip_unset(item); - evas_object_smart_member_del(item); - free(ilist); - ilist = next; - } while (ilist != sc_data->item_list); - } - - evas_object_del(sc_data->evt_layer); - evas_object_del(sc_data->clip); - free(sc_data); -} - -static void live_move(Evas_Object *scroller, Evas_Coord bx, Evas_Coord by) -{ - struct widget_data *sc_data; - Evas_Coord x, y, w, h; - Evas_Coord bw; - - Evas_Coord dx; - Evas_Coord dy; - - struct item_list_entry *n; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - evas_object_geometry_get(sc_data->clip, &x, &y, &bw, NULL); - - evas_object_move(sc_data->evt_layer, bx, by); - evas_object_move(sc_data->clip, bx, by); - sc_data->clip_bx = bx; - sc_data->clip_bw = bw; - - dx = bx - x; - dy = by - y; - - if (sc_data->item_list) { - n = sc_data->item_list; - do { - evas_object_move(LIST_DATA(n), bx, by); - - LIST_ITEM_GEO_GET(n, &x, &y, &w, &h); - x += dx; - y += dy; - move_item(sc_data, n, x, y, w, h); - n = LIST_NEXT(n); - } while (n != sc_data->item_list); - } -} - -static void live_resize(Evas_Object *scroller, Evas_Coord w, Evas_Coord h) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - evas_object_resize(sc_data->clip, w, h); - evas_object_resize(sc_data->evt_layer, w, h); - - sc_data->clip_bw = w; -} - -static void live_show(Evas_Object *scroller) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - evas_object_show(sc_data->clip); -} - -static void live_hide(Evas_Object *scroller) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - evas_object_hide(sc_data->clip); -} - -static void live_set_color(Evas_Object *scroller, int r, int g, int b, int a) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - evas_object_color_set(sc_data->clip, r, g, b, a); -} - -static void live_set_clip(Evas_Object *scroller, Evas_Object *clip) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - evas_object_clip_set(sc_data->clip, clip); -} - -static void live_unset_clip(Evas_Object *scroller) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return; - } - - evas_object_clip_unset(sc_data->clip); -} - -static inline void rearrange_items(struct widget_data *sc_data) -{ - struct item_list_entry *ilist; - Evas_Coord x, y, w, h; - Evas_Coord sw; - - LIST_ITEM_GEO_GET(sc_data->curlist, NULL, &y, &sw, &h); - move_item(sc_data, sc_data->curlist, sc_data->clip_bx, y, sw, h); - - x = sc_data->clip_bx; - ilist = sc_data->curlist; - while (ilist != sc_data->item_list) { - ilist = LIST_PREV(ilist); - LIST_ITEM_GEO_GET(ilist, NULL, &y, &w, &h); - x -= w; - move_item(sc_data, ilist, x, y, w, h); - } - - w = sw; - x = sc_data->clip_bx; - ilist = LIST_NEXT(sc_data->curlist); - while (ilist != sc_data->item_list) { - x += w; - LIST_ITEM_GEO_GET(ilist, NULL, &y, &w, &h); - move_item(sc_data, ilist, x, y, w, h); - ilist = LIST_NEXT(ilist); - } -} - -static Eina_Bool sc_anim_cb(void *data) -{ - PROFILE_START(); - struct widget_data *sc_data; - Evas_Coord sx, sw; - Evas_Coord y; - Evas_Coord dx; - struct item_list_entry *ilist; - - sc_data = data; - - if (!sc_data->curlist || !sc_data->tolist) { - DbgPrint("cur_list: %p, tolist: %p\n", sc_data->curlist, sc_data->tolist); - goto clean_out; - } - - ilist = sc_data->curlist; - if (sc_data->curlist != sc_data->tolist) { - if (sc_data->sc_anim_dx > 0) - ilist = LIST_PREV(ilist); - else - ilist = LIST_NEXT(ilist); - } - - LIST_ITEM_GEO_GET(ilist, &sx, &y, &sw, NULL); - if (ilist == sc_data->tolist) { - DbgPrint("next list == tolist\n"); - dx = abs(sx - sc_data->clip_bx); - DbgPrint("sx: %d, clip_bx: %d --> %d\n", sx, sc_data->clip_bx, dx); - if (dx < abs(sc_data->sc_anim_dx)) { - if (sc_data->sc_anim_dx < 0) - dx = -dx; - } else { - dx = sc_data->sc_anim_dx; - } - } else { - dx = sc_data->sc_anim_dx; - DbgPrint("dx: %d\n", dx); - } - - if (!dx) { - DbgPrint("dx is 0\n"); - goto clean_out; - } - - ilist = update_items_geo(sc_data, dx); - if (ilist) { - int idx; - - idx = list_item_idx(sc_data, ilist); - evas_object_smart_callback_call(sc_data->scroller,"page,changed", (void *)idx); - } - PROFILE_END(); - return ECORE_CALLBACK_RENEW; - -clean_out: - PROFILE_END(); - evas_object_smart_callback_call(sc_data->scroller, "anim,stop", NULL); - sc_data->sc_anim_timer = NULL; - return ECORE_CALLBACK_CANCEL; -} - -Evas_Object *live_scroller_add(Evas_Object *parent) -{ - static Evas_Smart_Class sc = EVAS_SMART_CLASS_INIT_NAME_VERSION("live,scroller"); - static Evas_Smart *smart = NULL; - Evas_Object *scroller; - Evas *e; - - if (!parent) - return NULL; - - e = evas_object_evas_get(parent); - if (!e) - return NULL; - - if (!smart) { - sc.add = live_add; - sc.del = live_del; - sc.move = live_move; - sc.resize = live_resize; - sc.show = live_show; - sc.hide = live_hide; - sc.color_set = live_set_color; - sc.clip_set = live_set_clip; - sc.clip_unset = live_unset_clip; - - smart = evas_smart_class_new(&sc); - } - - scroller = evas_object_smart_add(e, smart); - - return scroller; -} - -int live_scroller_append(Evas_Object *scroller, Evas_Object *item) -{ - Evas_Coord x, y, w, h; - Evas_Coord bx, by, bw, bh; - struct widget_data *sc_data; - struct item_list_entry *tmplist; - Evas_Coord start_x = 0; - Evas_Coord start_w = 0; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - evas_object_geometry_get(sc_data->clip, &bx, &by, &bw, &bh); - - if (sc_data->item_list) - LIST_ITEM_GEO_GET(sc_data->item_list, &start_x, NULL, &start_w, NULL); - - tmplist = list_item_last_list(sc_data->item_list); - if (tmplist) { - LIST_ITEM_GEO_GET(tmplist, &x, NULL, &w, NULL); - if (x + w == start_x) { - x = start_x - w; - } else { - x += w; - } - } else { - x = bx; - } - - evas_object_geometry_get(item, NULL, NULL, &w, &h); - evas_object_smart_member_add(item, sc_data->scroller); - - y = by + ((bh - h) >> 1); - - tmplist = list_item_append(sc_data->item_list, item); - if (sc_data->item_list == sc_data->curlist) - sc_data->curlist = tmplist; - if (sc_data->item_list == sc_data->tolist) - sc_data->tolist = tmplist; - sc_data->item_list = tmplist; - - sc_data->item_cnt++; - evas_object_clip_set(item, sc_data->clip); - evas_object_stack_below(item, sc_data->clip); - - evas_object_move(item, bx, by); - move_item(sc_data, list_item_find(sc_data->item_list, item), x, y, w, h); - - return 0; -} - -int live_scroller_remove_by_obj(Evas_Object *scroller, Evas_Object *obj) -{ - struct widget_data *sc_data; - struct item_list_entry *tmplist; - Evas_Object *item; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - if (sc_data->curlist) { - if (LIST_DATA(sc_data->curlist) == obj) { - sc_data->curlist = sc_data->item_list; - DbgPrint("Reset curlist\n"); - } - } - - if (sc_data->tolist) { - if (LIST_DATA(sc_data->tolist) == obj) { - sc_data->tolist = sc_data->item_list; - DbgPrint("Reset tolist\n"); - } - } - - tmplist = list_item_remove(sc_data->item_list, obj); - if (sc_data->item_list == sc_data->curlist) { - sc_data->curlist = tmplist; - DbgPrint("Update curlist\n"); - } - if (sc_data->item_list == sc_data->tolist) { - sc_data->tolist = tmplist; - DbgPrint("Update tolist\n"); - } - sc_data->item_list = tmplist; - - sc_data->item_cnt--; - evas_object_clip_unset(obj); - evas_object_smart_member_del(obj); - DbgPrint("Count of items: %d\n", sc_data->item_cnt); - - item = LIST_DATA(sc_data->curlist); - if (item) { - Evas_Coord y, w, h; - int idx; - - LIST_ITEM_GEO_GET(sc_data->curlist, NULL, &y, &w, &h); - DbgPrint("Current GEO: %d, %dx%d\n", y, w, h); - LIST_ITEM_GEO_SET(sc_data->curlist, sc_data->clip_bx, y, w, h); - DbgPrint("sc_data->curlist : %p\n", sc_data->curlist); - update_items_geo(sc_data, 0); - DbgPrint("sc_data->curlist : %p\n", sc_data->curlist); - - idx = list_item_idx(sc_data, sc_data->curlist); - evas_object_smart_callback_call(sc_data->scroller, "page,changed", (void *)idx); - } - - return 0; -} - -Evas_Object *live_scroller_remove(Evas_Object *scroller, int idx) -{ - struct widget_data *sc_data; - struct item_list_entry *tmplist; - Evas_Object *ret; - Evas_Object *item; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return NULL; - } - - if (idx < 0 || idx >= sc_data->item_cnt) - return NULL; - - ret = list_item_nth(sc_data->item_list, idx); - if (!ret) - return NULL; - - if (list_item_nth_list(sc_data->item_list, idx) == sc_data->curlist) { - DbgPrint("Reset curlist\n"); - sc_data->curlist = sc_data->item_list; - } - - if (list_item_nth_list(sc_data->item_list, idx) == sc_data->tolist) { - DbgPrint("Reset tolist\n"); - sc_data->tolist = sc_data->item_list; - } - - tmplist = list_item_remove(sc_data->item_list, ret); - if (sc_data->item_list == sc_data->curlist) - sc_data->curlist = tmplist; - if (sc_data->item_list == sc_data->tolist) - sc_data->tolist = tmplist; - sc_data->item_list = tmplist; - - sc_data->item_cnt--; - evas_object_clip_unset(ret); - evas_object_smart_member_del(ret); - - item = LIST_DATA(sc_data->curlist); - if (item) { - Evas_Coord y, w, h; - int idx; - LIST_ITEM_GEO_GET(sc_data->curlist, NULL, &y, &w, &h); - LIST_ITEM_GEO_SET(sc_data->curlist, sc_data->clip_bx, y, w, h); - update_items_geo(sc_data, 0); - idx = list_item_idx(sc_data, sc_data->curlist); - evas_object_smart_callback_call(sc_data->scroller, "page,changed", (void *)idx); - } - return ret; -} - -Evas_Object *live_scroller_get_item(Evas_Object *scroller, int idx) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return NULL; - } - - if (idx < 0 || idx >= sc_data->item_cnt) - return NULL; - - return list_item_nth(sc_data->item_list, idx); -} - -int live_scroller_get_current(Evas_Object *scroller) -{ - struct widget_data *sc_data; - struct item_list_entry *ilist; - int idx; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - ilist = sc_data->curlist; - idx = 0; - if (ilist) { - while (ilist != sc_data->item_list) { - idx++; - ilist = LIST_PREV(ilist); - } - } - - return idx; -} - -int live_scroller_loop_set(Evas_Object *scroller, int is_loop) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - if (is_loop == EINA_FALSE && sc_data->is_loop == EINA_TRUE) - rearrange_items(sc_data); - - sc_data->is_loop = is_loop; - return 0; -} - -int live_scroller_freeze(Evas_Object *scroller) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - sc_data->is_freezed = EINA_TRUE; - return 0; -} - -int live_scroller_thaw(Evas_Object *scroller) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - sc_data->is_freezed = EINA_FALSE; - return 0; -} - -int live_scroller_anim_to(Evas_Object *scroller, double sec, int offset) -{ - PROFILE_START(); - struct widget_data *sc_data; - Evas_Coord sx, sw; - Evas_Coord y; - struct live_sc_event_info info; - struct item_list_entry *ilist; - double ftmp; - int ret; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - ret = -EINVAL; - goto out; - } - - if (sc_data->is_freezed) { - ErrPrint("Scroller is freezed\n"); - ret = -EBUSY; - goto out; - } - - if (!sc_data->curlist) - sc_data->curlist = sc_data->item_list; - - if (!sc_data->curlist) { - ErrPrint("List is empty\n"); - ret = -ENOENT; - goto out; - } - - if (sc_data->sc_anim_timer) { - ecore_timer_del(sc_data->sc_anim_timer); - sc_data->sc_anim_timer = NULL; - evas_object_smart_callback_call(sc_data->scroller, "anim,stop", NULL); - } else { - sc_data->tolist = sc_data->curlist; - } - - LIST_ITEM_GEO_GET(sc_data->curlist, &sx, &y, &sw, NULL); - - if (!offset) { - sc_data->sc_anim_dx = sc_data->clip_bx - sx; - DbgPrint("offset==0, dx: %d\n", sc_data->sc_anim_dx); - } else { - Evas_Coord tw; - struct item_list_entry *tmplist; - - calc_anim_dx_with_dir(sc_data, &offset); - DbgPrint("Offset: %d\n", offset); - - ilist = sc_data->curlist; - while (offset < 0) { - if (!sc_data->is_loop && ilist == sc_data->item_list) { - DbgPrint("Loop is disabled\n"); - break; - } - - LIST_ITEM_GEO_GET(ilist, NULL, NULL, &tw, NULL); - ilist = LIST_PREV(ilist); - - sc_data->sc_anim_dx += tw; - DbgPrint("tw: %d (%d)\n", tw, sc_data->sc_anim_dx); - - offset++; - if (sc_data->tolist == sc_data->item_list) { - if (!sc_data->is_loop) { - DbgPrint("Looping disabled\n"); - break; - } - } - sc_data->tolist = LIST_PREV(sc_data->tolist); - } - - while (offset > 0) { - LIST_ITEM_GEO_GET(ilist, NULL, NULL, &tw, NULL); - ilist = LIST_NEXT(ilist); - - sc_data->sc_anim_dx -= tw; - DbgPrint("tw: %d (%d)\n", tw, sc_data->sc_anim_dx); - - offset--; - tmplist = LIST_NEXT(sc_data->tolist); - if (tmplist == sc_data->item_list) { - if (!sc_data->is_loop) { - DbgPrint("Looping disabled\n"); - break; - } - } - sc_data->tolist = tmplist; - - if (!sc_data->is_loop && ilist == sc_data->item_list) { - DbgPrint("Destination arrived or loop is disabled"); - break; - } - } - } - - if (abs(sc_data->sc_anim_dx) > ANIM_MIN) { - ftmp = (double)sc_data->sc_anim_dx / ANIM_UNIT; - DbgPrint("ftmp: %lf\n", ftmp); - if (fabs(ftmp) < ANIM_MIN || fabs(ftmp) > abs(sc_data->sc_anim_dx)) - sc_data->sc_anim_dx = ftmp < 0 ? -ANIM_MIN : ANIM_MIN; - else - sc_data->sc_anim_dx = (int)ftmp; - DbgPrint("Result: %d\n", sc_data->sc_anim_dx); - } - - sc_data->sc_anim_timer = ecore_timer_add(sec, sc_anim_cb, sc_data); - if (!sc_data->sc_anim_timer) { - ErrPrint("Failed to add a animator\n"); - ret = -EFAULT; - goto out; - } - - info.curidx = list_item_idx(sc_data, sc_data->curlist); - info.toidx = list_item_idx(sc_data, sc_data->tolist); - DbgPrint("Current index: %d, To index: %d\n", info.curidx, info.toidx); - - evas_object_smart_callback_call(sc_data->scroller, "anim,start", &info); - ret = 0; - -out: - PROFILE_END(); - return ret; -} - -int live_scroller_go_to(Evas_Object *scroller, int idx) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - if (sc_data->is_freezed) - return -EBUSY; - - if (idx < 0 || idx >= sc_data->item_cnt) - return -EINVAL; - - sc_data->curlist = list_item_nth_list(sc_data->item_list, idx); - if (!sc_data->curlist) - return -EFAULT; - - rearrange_items(sc_data); - evas_object_smart_callback_call(sc_data->scroller, "page,changed", (void *)idx); - - return 0; -} - -int live_scroller_update(Evas_Object *scroller) -{ - struct widget_data *sc_data; - struct item_list_entry *n; - Evas_Object *item; - Evas_Coord x, y, w, h; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - if (sc_data->item_list) { - n = sc_data->item_list; - do { - item = LIST_DATA(n); - LIST_ITEM_GEO_GET(n, &x, &y, &w, &h); - move_item(sc_data, n, x, y, w, h); - n = LIST_NEXT(n); - } while (n != sc_data->item_list); - } - - return 0; -} - -int live_scroller_get_item_count(Evas_Object *scroller) -{ - struct widget_data *sc_data; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return 0; - } - - return list_item_count(sc_data->item_list); -} - -int live_scroller_get_item_index(Evas_Object *scroller, Evas_Object *item) -{ - struct widget_data *sc_data; - struct item_list_entry *n; - Evas_Object *tmp; - int idx; - - sc_data = evas_object_smart_data_get(scroller); - if (!sc_data) { - ErrPrint("sc_data is not valid\n"); - return -EINVAL; - } - - if (!sc_data->item_list) - return -ENOENT; - - idx = 0; - n = sc_data->item_list; - do { - tmp = LIST_DATA(n); - n = LIST_NEXT(n); - - if (tmp == item) - return idx; - - idx++; - } while (n != sc_data->item_list); - - return -ENOENT; -} - -/* End of a file */ diff --git a/live.viewer/src/main.c b/live.viewer/src/main.c deleted file mode 100644 index 9f84418..0000000 --- a/live.viewer/src/main.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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 - -#include -#include -#include -#include - -#include -#include - -#include "main.h" -#include "util.h" -#include "debug.h" -#include "scroller.h" -#include "lb.h" - -static struct info { - Evas_Object *window; - Evas_Object *scroller; -} s_info = { - .window = NULL, - .scroller = NULL, -}; - -Evas_Object *main_get_window(void) -{ - return s_info.window; -} - -static void click_cb(void *data, Evas_Object *obj, void *event_info) -{ - Elm_Object_Item *item; - const char *label; - - item = elm_list_selected_item_get(obj); - if (!item) - return; - - label = elm_object_item_part_text_get(item, NULL); - if (!label) - return; - - DbgPrint("Label: %s (%s)\n", label, data); - if (lb_add(s_info.scroller, data) < 0) - ErrPrint("Failed to add a new livebox\n"); -} - -static int append_livebox_cb(const char *appid, const char *lbid, int is_prime, void *data) -{ - char *name; - - DbgPrint("%s - %s\n", appid, lbid); - - name = livebox_service_i18n_name(lbid, NULL); - if (!name) { - name = strdup(lbid); - if (!name) { - ErrPrint("Heap: %s\n", strerror(errno)); - return 0; - } - } - - DbgPrint("Name: %s\n", name); - elm_list_item_append(data, name, NULL, NULL, click_cb, strdup(lbid)); - free(name); - return 0; -} - -static inline void livebox_list_create(void) -{ - Evas_Object *list; - - list = elm_list_add(s_info.window); - if (!list) { - ErrPrint("Failed to create a list\n"); - return; - } - - evas_object_resize(list, 720, 1280); - evas_object_show(list); - - DbgPrint("Get Package list\n"); - livebox_service_get_pkglist(append_livebox_cb, list); - elm_list_go(list); - - scroller_append(s_info.scroller, list); -} - -static bool app_create(void *data) -{ - Evas_Object *bg; - DbgPrint("create"); - lb_init(); - - s_info.window = elm_win_add(NULL, "Box viewer", ELM_WIN_BASIC); - if (!s_info.window) { - ErrPrint("Failed to create a window\n"); - return false; - } - elm_win_autodel_set(s_info.window, EINA_TRUE); - - evas_object_resize(s_info.window, 720, 1280); - evas_object_show(s_info.window); - - bg = elm_bg_add(s_info.window); - elm_win_resize_object_add(s_info.window, bg); - elm_bg_color_set(bg, 0, 0, 255); - evas_object_show(bg); - - s_info.scroller = scroller_create(s_info.window); - if (!s_info.scroller) { - evas_object_del(s_info.window); - s_info.window = NULL; - ErrPrint("Failed to create a scroller\n"); - return false; - } - - evas_object_resize(s_info.scroller, 720, 1280); - evas_object_show(s_info.scroller); - - livebox_list_create(); - - return true; -} - -static void app_terminate(void *data) -{ - DbgPrint("terminate"); - lb_fini(); - /*! - * \TODO - * Delete all objects from the scroller. - */ - - scroller_destroy(s_info.scroller); - evas_object_del(s_info.window); - s_info.window = NULL; -} - -static void app_pause(void *data) -{ - DbgPrint("pause"); -} - -static void app_resume(void *data) -{ - DbgPrint("resume"); -} - -static void app_reset(service_h service, void *data) -{ - DbgPrint("reset"); -} - -int main(int argc, char *argv[]) -{ - app_event_callback_s event_callback; - - setenv("ELM_ENGINE", "gl", 0); - event_callback.create = app_create; - event_callback.terminate = app_terminate; - event_callback.pause = app_pause; - event_callback.resume = app_resume; - event_callback.service = app_reset; - event_callback.low_memory = NULL; - event_callback.low_battery = NULL; - event_callback.device_orientation = NULL; - event_callback.language_changed = NULL; - - return app_efl_main(&argc, &argv, &event_callback, NULL); -} - -/* End of a file */ diff --git a/live.viewer/src/scroller.c b/live.viewer/src/scroller.c deleted file mode 100644 index 7a181fc..0000000 --- a/live.viewer/src/scroller.c +++ /dev/null @@ -1,524 +0,0 @@ -/* - * 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 - -#include - -#include "util.h" -#include "live_scroller.h" -#include "scroller.h" -#include "debug.h" - -#define FOCAL_DIST 800 -#define FLICK_COND 100 - -struct cb_item { - int (*cb)(Evas_Object *sc, void *data); - void *data; -}; - -struct scroll_info { - int locked; - Eina_Bool scrolling; - int focal; - Eina_Bool quick; - - Evas_Map *map; - - Ecore_Idler *bg_changer; - Eina_List *cb_list; -}; - -void scroller_lock(Evas_Object *sc) -{ - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(sc, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return; - } - - if (!scinfo->locked) - live_scroller_freeze(sc); - - scinfo->locked++; -} - -void scroller_unlock(Evas_Object *sc) -{ - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(sc, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return; - } - - if (scinfo->locked == 0) - return; - - scinfo->locked--; - - if (scinfo->locked == 0) - live_scroller_thaw(sc); -} - -static void sc_anim_stop(void *data, Evas_Object *obj, void *event_info) -{ - Eina_List *l; - Eina_List *tmp; - struct cb_item *item; - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(obj, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return; - } - /*! - * \TODO - * Do what you want at here when the scroller is stopped - */ - - scinfo->scrolling = EINA_FALSE; - EINA_LIST_FOREACH_SAFE(scinfo->cb_list, l, tmp, item) { - if (item->cb(obj, item->data) == ECORE_CALLBACK_CANCEL) { - if (eina_list_data_find(scinfo->cb_list, item)) { - scinfo->cb_list = eina_list_remove(scinfo->cb_list, item); - free(item); - } - } - } -} - -static inline void sc_drag_start(void *data, Evas_Object *obj, void *event_info) -{ - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(obj, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return; - } - - scinfo->scrolling = EINA_TRUE; -} - -static inline void sc_drag_stop(void *data, Evas_Object *scroller, void *event_info) -{ - struct live_sc_drag_info *info; - int offset = 0; - int ret; - - info = event_info; - - if (info->dx > FLICK_COND) - offset = -1; - else if (info->dx < -FLICK_COND) - offset = 1; - - ret = live_scroller_anim_to(scroller, 0.016f, offset); - if (ret < 0) { - struct scroll_info *scinfo; - scinfo = evas_object_data_get(scroller, "scinfo"); - if (scinfo) - scinfo->scrolling = EINA_FALSE; - } -} - -static Eina_Bool bg_change_cb(void *data) -{ - Evas_Object *sc = data; - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(sc, "scinfo"); - if (scinfo) - scinfo->bg_changer = NULL; - - /*! - * \note: - * Here, - * Filename of background image handling code is only - * used to demonstrates UX concept and estimates its perfomance. - * So, I'll change this if it should be appled to - * main branch. - */ - DbgPrint("Change the background image (%p)\n", sc); - return ECORE_CALLBACK_CANCEL; -} - -static void sc_anim_start(void *data, Evas_Object *obj, void *event_info) -{ - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(obj, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return; - } - - /*! - * \note - * without drag,start - * anim start can be invoked by the scroller_anim_to - */ - scinfo->scrolling = EINA_TRUE; - - if (scinfo->bg_changer) - ecore_idler_del(scinfo->bg_changer); - - scinfo->bg_changer = ecore_idler_add(bg_change_cb, obj); - if (!scinfo->bg_changer) - DbgPrint("Failed to add an idler\n"); -} - -static void sc_item_moved(void *data, Evas_Object *obj, void *event_info) -{ - struct live_sc_move_info *evt = event_info; - int color; - int focal; - Evas_Coord y, sx, sw; - double ftmp; - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(obj, "scinfo"); - if (!scinfo) { - ErrPrint("Has no scinfo\n"); - return; - } - - ftmp = fabsl(evt->relx); - if (ftmp >= 1.0f) { - evas_object_map_enable_set(evt->item, EINA_FALSE); - evas_object_hide(evt->item); - return; - } - - color = 255 * (1.0f - ftmp); - if (scinfo->quick) { - if (color < 100) - color = 100; - - focal = scinfo->focal; - } else { - if (color == 0) { - evas_object_map_enable_set(evt->item, EINA_FALSE); - evas_object_hide(evt->item); - return; - } - - focal = -ftmp * 200.0f + scinfo->focal; - } - - evas_object_geometry_get(data, &sx, NULL, &sw, NULL); - - /* LEFT */ - evas_map_point_coord_set(scinfo->map, 0, evt->x, evt->y, 0); - evas_map_point_image_uv_set(scinfo->map, 0, 0, 0); - evas_map_point_color_set(scinfo->map, 0, color, color, color, color); - - /* RIGHT */ - evas_map_point_coord_set(scinfo->map, 1, evt->x + evt->w, evt->y, 0); - evas_map_point_image_uv_set(scinfo->map, 1, evt->w, 0); - evas_map_point_color_set(scinfo->map, 1, color, color, color, color); - - /* BOTTOM-RIGHT */ - evas_map_point_coord_set(scinfo->map, 2, evt->x + evt->w, evt->y + evt->h, 0); - evas_map_point_image_uv_set(scinfo->map, 2, evt->w, evt->h); - evas_map_point_color_set(scinfo->map, 2, color, color, color, color); - - /* BOTTOM-LEFT */ - evas_map_point_coord_set(scinfo->map, 3, evt->x, evt->y + evt->h, 0); - evas_map_point_image_uv_set(scinfo->map, 3, 0, evt->h); - evas_map_point_color_set(scinfo->map, 3, color, color, color, color); - - y = evt->y + (evt->h >> 1); - evas_map_util_3d_rotate(scinfo->map, 0.0f, -30.0f * evt->relx, 0.0f, evt->x + (evt->w >> 1), y, 0); - evas_map_util_3d_perspective(scinfo->map, sx + (sw >> 1), y, focal, FOCAL_DIST); - evas_object_map_set(evt->item, scinfo->map); - evas_object_map_enable_set(evt->item, EINA_TRUE); - evas_object_show(evt->item); - return; -} - -static void sc_page_changed(void *data, Evas_Object *obj, void *event_info) -{ - DbgPrint("Page is changed %d\n", (int)event_info); -} - -int scroller_add_stop_cb(Evas_Object *scroller, - int (*cb)(Evas_Object *sc, void *data), void *data) -{ - struct cb_item *item; - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(scroller, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return -EINVAL; - } - - item = calloc(1, sizeof(*item)); - if (!item) { - ErrPrint("Error: %s\n", strerror(errno)); - return EXIT_FAILURE; - } - - item->cb = cb; - item->data = data; - - scinfo->cb_list = eina_list_append(scinfo->cb_list, item); - return EXIT_SUCCESS; -} - -void scroller_del_stop_cb(Evas_Object *scroller, - int (*cb)(Evas_Object *sc, void *data), void *data) -{ - struct cb_item *item; - Eina_List *l; - Eina_List *tmp; - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(scroller, "scinfo"); - if (!scinfo) { - ErrPrint("Failed to get scinfo\n"); - return; - } - - EINA_LIST_FOREACH_SAFE(scinfo->cb_list, l, tmp, item) { - if (item->cb == cb && item->data == data) { - scinfo->cb_list = eina_list_remove(scinfo->cb_list, item); - free(item); - break; - } - } -} - -Evas_Object *scroller_create(Evas_Object *ctrl) -{ - Evas_Object *sc; - struct scroll_info *scinfo; - - scinfo = calloc(1, sizeof(*scinfo)); - if (!scinfo) { - ErrPrint("Heap: %s\n", strerror(errno)); - return NULL; - } - - sc = live_scroller_add(ctrl); - if (!sc) { - DbgPrint("Failed to create flip object\n"); - free(scinfo); - return NULL; - } - - evas_object_data_set(sc, "scinfo", scinfo); - - scinfo->map = evas_map_new(4); - if (!scinfo->map) { - ErrPrint("Failed to create a map object\n"); - evas_object_del(sc); - free(scinfo); - return NULL; - } - - evas_map_smooth_set(scinfo->map, EINA_TRUE); - evas_map_alpha_set(scinfo->map, EINA_TRUE); - - evas_object_size_hint_weight_set(sc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); - evas_object_smart_callback_add(sc, "drag,start", sc_drag_start, NULL); - evas_object_smart_callback_add(sc, "drag,stop", sc_drag_stop, NULL); - evas_object_smart_callback_add(sc, "anim,stop", sc_anim_stop, NULL); - evas_object_smart_callback_add(sc, "anim,start", sc_anim_start, NULL); - evas_object_smart_callback_add(sc, "page,changed", sc_page_changed, NULL); - evas_object_smart_callback_add(sc, "item,moved", sc_item_moved, NULL); - live_scroller_loop_set(sc, EINA_TRUE); - evas_object_show(sc); - - return sc; -} - -int scroller_append(Evas_Object *sc, Evas_Object *child) -{ - return live_scroller_append(sc, child); -} - -int scroller_get_page_index(Evas_Object *sc, Evas_Object *page) -{ - return live_scroller_get_item_index(sc, page); -} - -Evas_Object *scroller_get_page(Evas_Object *sc, int idx) -{ - return live_scroller_get_item(sc, idx); -} - -Evas_Object *scroller_peek_by_idx(Evas_Object *sc, int idx) -{ - return live_scroller_remove(sc, idx); -} - -int scroller_peek_by_obj(Evas_Object *sc, Evas_Object *page) -{ - return live_scroller_remove_by_obj(sc, page); -} - -int scroller_get_current_idx(Evas_Object *sc) -{ - return live_scroller_get_current(sc); -} - -int scroller_is_scrolling(Evas_Object *sc) -{ - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(sc, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return -EINVAL; - } - - return scinfo->scrolling; -} - -int scroller_get_page_count(Evas_Object *sc) -{ - return live_scroller_get_item_count(sc); -} - -int scroller_scroll_to(Evas_Object *sc, int idx) -{ - int curidx; - int cnt; - register int i; - int next_offset; - int prev_offset; - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(sc, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return -EINVAL; - } - - if (scinfo->scrolling) { - DbgPrint("Scroller is scrolling\n"); - return -EINVAL; - } - - curidx = live_scroller_get_current(sc); - cnt = live_scroller_get_item_count(sc); - - i = curidx; - next_offset = 0; - while (i != idx && i >= 0 && i < cnt) { - i++; - if (i >= cnt) - i = 0; - - next_offset++; - } - - i = curidx; - prev_offset = 0; - while (i != idx && i >= 0 && i < cnt) { - i--; - if (i < 0) - i = cnt - 1; - - prev_offset--; - } - - idx = next_offset < -prev_offset ? next_offset : prev_offset; - live_scroller_anim_to(sc, 0.016f, idx); - return 0; -} - -int scroller_jump_to(Evas_Object *sc, int idx) -{ - live_scroller_go_to(sc, idx); - return 0; -} - -int scroller_destroy(Evas_Object *sc) -{ - int cnt; - struct scroll_info *scinfo; - struct cb_item *item; - - scinfo = evas_object_data_del(sc, "scinfo"); - if (!scinfo) - return -EFAULT; - - if (scinfo->bg_changer) - ecore_idler_del(scinfo->bg_changer); - - EINA_LIST_FREE(scinfo->cb_list, item) { - free(item); - } - - cnt = live_scroller_get_item_count(sc); - if (cnt) - DbgPrint("Children is not cleared (%d)\n", cnt); - - evas_object_del(sc); - evas_map_free(scinfo->map); - free(scinfo); - return 0; -} - -int scroller_update(Evas_Object *sc, void *data) -{ - struct scroll_info *scinfo; - - scinfo = evas_object_data_get(sc, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return -EFAULT; - } - - scinfo->focal = (int)data; - live_scroller_update(sc); - return EXIT_SUCCESS; -} - -int scroller_fast_scroll(Evas_Object *sc, int idx) -{ - idx -= scroller_get_current_idx(sc); - live_scroller_anim_to(sc, 0.016f, idx); - return 0; -} - -void scroller_loop_set(Evas_Object *sc, Eina_Bool val) -{ - live_scroller_loop_set(sc, val); -} - -void scroller_quick_navi(Evas_Object *sc, Eina_Bool val) -{ - struct scroll_info *scinfo; - scinfo = evas_object_data_get(sc, "scinfo"); - if (!scinfo) { - ErrPrint("scinfo is not valid\n"); - return; - } - - scinfo->quick = val; -} - -/* End of a file */ diff --git a/live.viewer/src/util.c b/live.viewer/src/util.c deleted file mode 100644 index 8a1c5cb..0000000 --- a/live.viewer/src/util.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - -#include - -#include "debug.h" -#include "util.h" - -int errno; - -const char *util_basename(const char *name) -{ - int length; - length = name ? strlen(name) : 0; - if (!length) - return "."; - - while (--length > 0 && name[length] != '/'); - - return length <= 0 ? name : name + length + (name[length] == '/'); -} - -/* End of a file */ diff --git a/livebox-viewer/CMakeLists.txt b/livebox-viewer/CMakeLists.txt new file mode 100644 index 0000000..da6757a --- /dev/null +++ b/livebox-viewer/CMakeLists.txt @@ -0,0 +1,55 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(livebox-viewer 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 1) +SET(VERSION "${VERSION_MAJOR}.0.0") + +SET(CMAKE_SKIP_BUILD_RPATH true) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) +pkg_check_modules(old_pkgs REQUIRED + dlog + aul + glib-2.0 + gio-2.0 + com-core + sqlite3 + db-util + livebox-service + vconf +) + +SET(BUILD_SOURCE + src/livebox.c +) + +FOREACH(flag ${old_pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall -Werror -Winline -g") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +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} ${old_pkgs_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_CURRENT_SOURCE_DIR}/include/livebox.h DESTINATION include/${PROJECT_NAME}) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION /usr/share/license RENAME "lib${PROJECT_NAME}") + +# End of a file diff --git a/livebox-viewer/LICENSE b/livebox-viewer/LICENSE new file mode 100644 index 0000000..571fe79 --- /dev/null +++ b/livebox-viewer/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/livebox-viewer/include/livebox.h b/livebox-viewer/include/livebox.h new file mode 100644 index 0000000..6429bef --- /dev/null +++ b/livebox-viewer/include/livebox.h @@ -0,0 +1,1471 @@ +/* + * 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_H +#define __LIVEBOX_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file livebox.h + * @brief This file declares API of liblivebox-viewer library + */ + +/** + * @addtogroup CAPI_LIVEBOX_VIEWER_MODULE + * @{ + */ + +/** + * @brief + * Structure for a Livebox instance. + */ +struct livebox; + +/** + * @brief Definition for a default update period for Livebox (defined in the package manifest file). + */ +#define DEFAULT_PERIOD -1.0f + +/** + * @brief Enumeration for Mouse & Key event for buffer type Livebox or PD. + * @details Viewer should send these events to livebox. + */ +enum content_event_type { + CONTENT_EVENT_MOUSE_DOWN = 0x00000001, /**< LB mouse down event for livebox */ + CONTENT_EVENT_MOUSE_UP = 0x00000002, /**< LB mouse up event for livebox */ + CONTENT_EVENT_MOUSE_MOVE = 0x00000004, /**< LB mouse move event for livebox */ + CONTENT_EVENT_MOUSE_ENTER = 0x00000008, /**< LB mouse enter event for livebox */ + CONTENT_EVENT_MOUSE_LEAVE = 0x00000010, /**< LB mouse leave event for livebox */ + CONTENT_EVENT_MOUSE_SET = 0x00000020, /**< LB mouse set auto event for livebox */ + CONTENT_EVENT_MOUSE_UNSET = 0x00000040, /**< LB mouse unset auto event for livebox */ + + CONTENT_EVENT_KEY_DOWN = 0x00000001, /**< LB key press */ + CONTENT_EVENT_KEY_UP = 0x00000002, /**< LB key release */ + CONTENT_EVENT_KEY_FOCUS_IN = 0x00000008, /**< LB key focused in */ + CONTENT_EVENT_KEY_FOCUS_OUT = 0x00000010, /**< LB key focused out */ + CONTENT_EVENT_KEY_SET = 0x00000020, /**< LB Key, start feeding event by master */ + CONTENT_EVENT_KEY_UNSET = 0x00000040, /**< LB key, stop feeding event by master */ + + CONTENT_EVENT_ON_SCROLL = 0x00000080, /**< LB On scrolling */ + CONTENT_EVENT_ON_HOLD = 0x00000100, /**< LB On holding */ + CONTENT_EVENT_OFF_SCROLL = 0x00000200, /**< LB Stop scrolling */ + CONTENT_EVENT_OFF_HOLD = 0x00000400, /**< LB Stop holding */ + + CONTENT_EVENT_KEY_MASK = 0x80000000, /**< Mask value for key event */ + CONTENT_EVENT_MOUSE_MASK = 0x20000000, /**< Mask value for mouse event */ + CONTENT_EVENT_PD_MASK = 0x10000000, /**< Mask value for PD event */ + CONTENT_EVENT_LB_MASK = 0x40000000, /**< Mask value for LB event */ + + LB_MOUSE_ON_SCROLL = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_SCROLL, /**< Mouse event occurs while scrolling */ + LB_MOUSE_ON_HOLD = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_HOLD, /**< Mouse event occurs on holding */ + LB_MOUSE_OFF_SCROLL = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_SCROLL, /**< Scrolling stopped */ + LB_MOUSE_OFF_HOLD = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_HOLD, /**< Holding stopped */ + + LB_MOUSE_DOWN = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_DOWN, /**< Mouse down on the livebox */ + LB_MOUSE_UP = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UP, /**< Mouse up on the livebox */ + LB_MOUSE_MOVE = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_MOVE, /**< Move move on the livebox */ + LB_MOUSE_ENTER = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_ENTER, /**< Mouse enter to the livebox */ + LB_MOUSE_LEAVE = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_LEAVE, /**< Mouse leave from the livebox */ + LB_MOUSE_SET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_SET, /**< Mouse event, start feeding event by master */ + LB_MOUSE_UNSET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UNSET, /**< Mouse event, stop feeding event by master */ + + PD_MOUSE_ON_SCROLL = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_SCROLL, /**< Mouse event occurs while scrolling */ + PD_MOUSE_ON_HOLD = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_ON_HOLD, /**< Mouse event occurs on holding */ + PD_MOUSE_OFF_SCROLL = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_SCROLL, /**< Scrolling stopped */ + PD_MOUSE_OFF_HOLD = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_OFF_HOLD, /**< Holding stopped */ + + PD_MOUSE_DOWN = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_DOWN, /**< Mouse down on the PD */ + PD_MOUSE_UP = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UP, /**< Mouse up on the PD */ + PD_MOUSE_MOVE = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_MOVE, /**< Mouse move on the PD */ + PD_MOUSE_ENTER = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_ENTER, /**< Mouse enter to the PD */ + PD_MOUSE_LEAVE = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_LEAVE, /**< Mouse leave from the PD */ + PD_MOUSE_SET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_SET, /**< Mouse event, start feeding event by master */ + PD_MOUSE_UNSET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_MOUSE_MASK | CONTENT_EVENT_MOUSE_UNSET, /**< Mouse event, stop feeding event by master */ + + LB_KEY_DOWN = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_DOWN, /**< Key down on the livebox */ + LB_KEY_UP = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UP, /**< Key up on the livebox */ + LB_KEY_SET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_SET, /**< Key event, start feeding event by master */ + LB_KEY_UNSET = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UNSET, /**< Key event, stop feeding event by master */ + LB_KEY_FOCUS_IN = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_IN, /**< Key event, focus in */ + LB_KEY_FOCUS_OUT = CONTENT_EVENT_LB_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_OUT, /**< Key event, foucs out */ + + PD_KEY_DOWN = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_DOWN, /**< Key down on the livebox */ + PD_KEY_UP = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UP, /**< Key up on the livebox */ + PD_KEY_SET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_SET, /**< Key event, start feeding event by master */ + PD_KEY_UNSET = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_UNSET, /**< Key event, stop feeding event by master */ + PD_KEY_FOCUS_IN = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_IN, /**< Key event, focus in */ + PD_KEY_FOCUS_OUT = CONTENT_EVENT_PD_MASK | CONTENT_EVENT_KEY_MASK | CONTENT_EVENT_KEY_FOCUS_OUT, /**< Key event, focus out */ + + CONTENT_EVENT_MAX = 0xFFFFFFFF /**< Unknown event */ +}; + +/** + * @brief Enumeration for Accessibility event for buffer type Livebox or PD. + * @details These events are sync'd with Tizen accessibility event set. + */ +enum access_event_type { + ACCESS_EVENT_PD_MASK = 0x10000000, /**< PD Accessibility event mask */ + ACCESS_EVENT_LB_MASK = 0x20000000, /**< LB Accessibility event mask */ + + ACCESS_EVENT_HIGHLIGHT = 0x00000100, /**< LB accessibility: Hightlight a object */ + ACCESS_EVENT_HIGHLIGHT_NEXT = 0x00000200, /**< LB accessibility: Set highlight to next object */ + ACCESS_EVENT_HIGHLIGHT_PREV = 0x00000400, /**< LB accessibility: Set highlight to prev object */ + ACCESS_EVENT_UNHIGHLIGHT = 0x00000800, /**< LB accessibility unhighlight */ + ACCESS_EVENT_ACTIVATE = 0x00001000, /**< LB accessibility activate */ + ACCESS_EVENT_ACTION_DOWN = 0x00010000, /**< LB accessibility value changed */ + ACCESS_EVENT_ACTION_UP = 0x00020000, /**< LB accessibility value changed */ + ACCESS_EVENT_SCROLL_DOWN = 0x00100000, /**< LB accessibility scroll down */ + ACCESS_EVENT_SCROLL_MOVE = 0x00200000, /**< LB accessibility scroll move */ + ACCESS_EVENT_SCROLL_UP = 0x00400000, /**< LB accessibility scroll up */ + + LB_ACCESS_HIGHLIGHT = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_HIGHLIGHT, /**< Access event - Highlight an object in the livebox */ + LB_ACCESS_HIGHLIGHT_NEXT = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_HIGHLIGHT_NEXT, /**< Access event - Move highlight to the next object in a livebox */ + LB_ACCESS_HIGHLIGHT_PREV = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_HIGHLIGHT_PREV, /**< Access event - Move highlight to the prev object in a livebox */ + LB_ACCESS_UNHIGHLIGHT = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_UNHIGHLIGHT, /**< Access event - Delete highlight from the livebox */ + LB_ACCESS_ACTIVATE = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_ACTIVATE, /**< Access event - Launch or activate the highlighted object */ + LB_ACCESS_ACTION_DOWN = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_ACTION_DOWN, /**< Access event - down */ + LB_ACCESS_ACTION_UP = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_ACTION_UP, /**< Access event - up */ + LB_ACCESS_SCROLL_DOWN = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_SCROLL_DOWN, /**< Access event - scroll down */ + LB_ACCESS_SCROLL_MOVE = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_SCROLL_MOVE, /**< Access event - scroll move */ + LB_ACCESS_SCROLL_UP = ACCESS_EVENT_LB_MASK | ACCESS_EVENT_SCROLL_UP, /**< Access event - scroll up */ + + PD_ACCESS_HIGHLIGHT = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_HIGHLIGHT, /**< Access event - Highlight an object in the PD */ + PD_ACCESS_HIGHLIGHT_NEXT = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_HIGHLIGHT_NEXT, /**< Access event - Move highlight to the next object in a PD */ + PD_ACCESS_HIGHLIGHT_PREV = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_HIGHLIGHT_PREV, /**< Access event - Move highlight to the prev object in a PD */ + PD_ACCESS_UNHIGHLIGHT = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_UNHIGHLIGHT, /**< Access event - Delet highlight from the PD */ + PD_ACCESS_ACTIVATE = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_ACTIVATE, /**< Access event - Launch or activate the highlighted object */ + PD_ACCESS_ACTION_DOWN = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_ACTION_DOWN, /**< Access event - down */ + PD_ACCESS_ACTION_UP = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_ACTION_UP, /**< Access event - up */ + PD_ACCESS_SCROLL_DOWN = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_SCROLL_DOWN, /**< Access event - scroll down */ + PD_ACCESS_SCROLL_MOVE = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_SCROLL_MOVE, /**< Access event - scroll move */ + PD_ACCESS_SCROLL_UP = ACCESS_EVENT_PD_MASK | ACCESS_EVENT_SCROLL_UP /**< Access event - scroll up */ +}; + +/** + * @brief Enumeration for Livebox LB content type. + */ +enum livebox_lb_type { + LB_TYPE_IMAGE = 0x01, /**< Contents of a livebox is based on the image file */ + LB_TYPE_BUFFER = 0x02, /**< Contents of a livebox is based on canvas buffer(shared) */ + LB_TYPE_TEXT = 0x04, /**< Contents of a livebox is based on formatted text file */ + LB_TYPE_PIXMAP = 0x08, /**< Contens of a livebox is shared by the pixmap(depends on X) */ + LB_TYPE_ELEMENTARY = 0x10, /**< Using Elementary for sharing content & event */ + LB_TYPE_INVALID = 0xFF /**< Unknown LB type */ +}; + +/** + * @brief Enumeration for Livebox PD content type. + */ +enum livebox_pd_type { + PD_TYPE_BUFFER = 0x01, /**< Contents of a PD is based on canvas buffer(shared) */ + PD_TYPE_TEXT = 0x02, /**< Contents of a PD is based on formatted text file */ + PD_TYPE_PIXMAP = 0x04, /**< Contents of a livebox is shared by the pixmap(depends on X) */ + PD_TYPE_ELEMENTARY = 0x08, /**< Using Elementary for sharing content & event */ + PD_TYPE_INVALID = 0xFF /**< Unknown PD type */ +}; + +/** + * @brief Enumeration for Livebox event type. + * @details These events will be sent from the provider. + */ +enum livebox_event_type { /**< livebox_event_handler_set Event list */ + LB_EVENT_LB_UPDATED, /**< Contents of the given livebox is updated */ + LB_EVENT_PD_UPDATED, /**< Contents of the given pd is updated */ + + LB_EVENT_CREATED, /**< A new livebox is created */ + LB_EVENT_DELETED, /**< A livebox is deleted */ + + LB_EVENT_GROUP_CHANGED, /**< Group (Cluster/Sub-cluster) information is changed */ + LB_EVENT_PINUP_CHANGED, /**< PINUP status is changed */ + LB_EVENT_PERIOD_CHANGED, /**< Update period is changed */ + + LB_EVENT_LB_SIZE_CHANGED, /**< Livebox size is changed */ + LB_EVENT_PD_SIZE_CHANGED, /**< PD size is changed */ + + LB_EVENT_PD_CREATED, /**< If a PD is created even if you didn't call the livebox_create_pd API */ + LB_EVENT_PD_DESTROYED, /**< If a PD is destroyed even if you didn't call the livebox_destroy_pd API */ + + LB_EVENT_HOLD_SCROLL, /**< If the screen should be freezed */ + LB_EVENT_RELEASE_SCROLL, /**< If the screen can be scrolled */ + + LB_EVENT_LB_UPDATE_BEGIN, /**< Livebox LB content update is started */ + LB_EVENT_LB_UPDATE_END, /**< Livebox LB content update is finished */ + + LB_EVENT_PD_UPDATE_BEGIN, /**< Livebox PD content update is started */ + LB_EVENT_PD_UPDATE_END, /**< Livebox PD content update is finished */ + + LB_EVENT_UPDATE_MODE_CHANGED, /**< Livebox Update mode is changed */ + + LB_EVENT_REQUEST_CLOSE_PD, /**< Livebox requests to close the PD */ + + LB_EVENT_IGNORED /**< Request is ignored */ +}; + +/** + * @brief Enumeration for Livebox option types. + */ +enum livebox_option_type { + LB_OPTION_MANUAL_SYNC, /**< Sync manually */ + LB_OPTION_FRAME_DROP_FOR_RESIZE, /**< Drop frames while resizing */ + LB_OPTION_SHARED_CONTENT, /**< Use only one real instance for multiple fake instances if user creates it using same content */ + + LB_OPTION_ERROR = 0xFFFFFFFF /**< To specify the size of this enumeration type */ +}; + +enum livebox_fault_type { + LB_FAULT_DEACTIVATED, /*!< Livebox is deactivated by its fault operation */ + LB_FAULT_PROVIDER_DISCONNECTED /*!< Provider is disconnected */ +}; + +/** + * @brief Enumeration for Livebox visible states. + * @details Must be sync'd with a provider. + */ +enum livebox_visible_state { + LB_SHOW = 0x00, /**< Livebox is shown. Default state */ + LB_HIDE = 0x01, /**< Livebox is hidden, Update timer will not be freezed. but you cannot receive any updates events. */ + + LB_HIDE_WITH_PAUSE = 0x02, /**< Livebix is hidden, it will pause the update timer, but if a livebox updates its contents, update event will be triggered */ + + LB_VISIBLE_ERROR = 0xFFFFFFFF /**< To specify the size of this enumeration type */ +}; + +/** + * @brief Structure for TEXT type livebox contents handling opertators. + */ +struct livebox_script_operators { + int (*update_begin)(struct livebox *handle); /**< Content parser is started */ + int (*update_end)(struct livebox *handle); /**< Content parser is finished */ + + /* Listed functions will be called when parser meets each typed content */ + int (*update_text)(struct livebox *handle, const char *id, const char *part, const char *data); /**< Update text content */ + int (*update_image)(struct livebox *handle, const char *id, const char *part, const char *data, const char *option); /**< Update image content */ + int (*update_script)(struct livebox *handle, const char *id, const char *new_id, const char *part, const char *file, const char *group); /**< Update script content */ + int (*update_signal)(struct livebox *handle, const char *id, const char *emission, const char *signal); /**< Update signal */ + int (*update_drag)(struct livebox *handle, const char *id, const char *part, double dx, double dy); /**< Update drag info */ + int (*update_info_size)(struct livebox *handle, const char *id, int w, int h); /**< Update content size */ + int (*update_info_category)(struct livebox *handle, const char *id, const char *category); /**< Update content category info */ + int (*update_access)(struct livebox *handle, const char *id, const char *part, const char *text, const char *option); /**< Update access information */ + int (*operate_access)(struct livebox *handle, const char *id, const char *part, const char *operation, const char *option); /**< Update access operation */ + int (*update_color)(struct livebox *handle, const char *id, const char *part, const char *data); /**< Update color */ +}; + +/** + * @brief Called for every async function. + * @details Prototype of the return callback of every async functions. + * @param[in] handle Handle of the livebox instance + * @param[in] ret Result status of operation (LB_STATUS_XXX defined from liblivebox-service) + * @param[in] data Data for result callback + * @return void + * @see livebox_add() + * @see livebox_del() + * @see livebox_activate() + * @see livebox_resize() + * @see livebox_set_group() + * @see livebox_set_period() + * @see livebox_access_event() + * @see livebox_set_pinup() + * @see livebox_create_pd() + * @see livebox_create_pd_with_position() + * @see livebox_destroy_pd() + * @see livebox_emit_text_signal() + * @see livebox_acquire_pd_pixmap() + * @see livebox_acquire_lb_pixmap() + * @see livebox_set_update_mode() + */ +typedef void (*ret_cb_t)(struct livebox *handle, int ret, void *data); + +/** + * @brief Initializes the livebox system. + * @remarks This API uses get/setenv APIs. + * Those APIs are not thread-safe. + * So you have to consider to use the livebox_init_with_options instead of this if you are developing multi-threaded viewer. + * @param[in] disp X Display connection object (If you have X Display connection object already, you can re-use it. But you should care its life cycle. + * It must be alive before calling livebox_fini()) + * @return int + * @retval #LB_STATUS_SUCCESS if success + * @see livebox_fini() + * @see livebox_init_with_options() + */ +extern int livebox_init(void *disp); + +/** + * @brief Initializes the livebox system with some options. + * @details livebox_init function uses environment value to initiate some configurable values. + * But some applications do not want to use the env value. + * For them, this API will give a chance to set default options using given arguments. + * @param[in] disp Display (if @a disp is @c NULL, the library will try to acquire a new connection with X) + * @param[in] prevent_overwrite Overwrite flag (when the content of an image type livebox is updated, it will be overwriten (0) or not (1)) + * @param[in] event_filter If the next event comes in this period, ignore it. It is too fast to processing it in time // need to be elaborated + * @param[in] use_thread Use the receive thread // need to be elaborated + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int Integer, Livebox status code + * @retval #LB_STATUS_SUCCESS if success + * @see livebox_init() + * @see livebox_fini() + */ +extern int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread); + +/** + * @brief Finalizes the livebox system. + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCES if success + * @retval #LB_STATUS_ERROR_INVALID if livebox_init is not called + * @see livebox_init() + * @see livebox_init_with_options() + */ +extern int livebox_fini(void); + +/** + * @brief Notifies the status of a client ("it is paused") to the provider. + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCESS if success + * @retval #LB_STATUS_ERROR_FAULT if it failed to send state (paused) info + * @see livebox_client_resumed() + */ +extern int livebox_client_paused(void); + +/** + * @brief Notifies the status of client ("it is resumed") to the provider. + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCESS if success + * @retval #LB_STATUS_ERROR_FAULT if it failed to send state (resumed) info + * @see livebox_client_paused() + */ +extern int livebox_client_resumed(void); + +/** + * @brief Adds a new livebox. + * @details If the screen size is "1280x720", the below size lists are used for default. + * Or you can find the default sizes in pixel from /usr/share/data-provider-master/resolution.ini. + * Size types are defined from the liblivebox-service package (livebox-service.h). + * + * Normal mode livebox + * 1x1=175x175, #LB_SIZE_TYPE_1x1 + * 2x1=354x175, #LB_SIZE_TYPE_2x1 + * 2x2=354x354, #LB_SIZE_TYPE_2x2 + * 4x1=712x175, #LB_SIZE_TYPE_4x1 + * 4x2=712x354, #LB_SIZE_TYPE_4x2 + * 4x4=712x712, #LB_SIZE_TYPE_4x4 + * + * Extended sizes + * 4x3=712x533, #LB_SIZE_TYPE_4x3 + * 4x5=712x891, #LB_SIZE_TYPE_4x5 + * 4x6=712x1070, #LB_SIZE_TYPE_4x6 + * + * Easy mode livebox + * 21x21=224x215, #LB_SIZE_TYPE_EASY_1x1 + * 23x21=680x215, #LB_SIZE_TYPE_EASY_3x1 + * 23x23=680x653, #LB_SIZE_TYPE_EASY_3x3 + * + * Special livebox + * 0x0=720x1280, #LB_SIZE_TYPE_0x0 + * + * @remarks + * Even if you get a handle from the return value of this function, it is not a created instance. + * So you have to consider it as a not initialized handle. + * It can be initialized only after getting the return callback with "ret == #LB_STATUS_SUCCESS" + * @param[in] pkgname Livebox Id + * @param[in] content Contents that will be passed to the livebox instance + * @param[in] cluster Main group + * @param[in] category Sub group + * @param[in] period Update period (@c DEFAULT_PERIOD can be used for this; this argument will be used to specify the period of updating contents of a livebox) + * @param[in] type Size type (defined from liblivebox-service package) + * @param[in] cb After the request is sent to the master provider, this callback will be called + * @param[in] data This data will be passed to the callback + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return handle + * @retval Handle Livebox handle but not yet initialized + * @retval @c NULL if it fails to create a handle + * @see ret_cb_t + */ +extern struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data); + +/** + * @brief Deletes a livebox (will replace livebox_del). + * @remarks If you call this with an uninitialized handle, the return callback will be called synchronously. + * So before returning from this function, the return callback will be called first. + * @param[in] handler Handler of a livebox instance + * @param[in] type Deletion type (LB_DELETE_PERMANENTLY or LB_DELETE_TEMPORARY) + * @param[in] cb Return callback + * @param[in] data User data for return callback + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY Already in process + * @retval #LB_STATUS_ERROR_FAULT Failed to create a request packet + * @retval #LB_STATUS_SUCCESS Successfully sent, return callack will be called + * @see ret_cb_t + */ +extern int livebox_del(struct livebox *handler, int type, ret_cb_t cb, void *data); + +/** + * @brief Sets a livebox events callback. + * @details To get the event push from the provider, register the event callback using this function. + * The callback will be called if there is any event from the provider. + * @param[in] cb Event handler + * @param[in] data User data for the event handler + * @privlevel N/P + * @return int + * @retval #LB_STATUS_SUCCESS If succeed to set event handler + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_MEMORY Not enough memory + * @see livebox_unset_event_handler() + */ +extern int livebox_set_event_handler(int (*cb)(struct livebox *handler, enum livebox_event_type event, void *data), void *data); + +/** + * @brief Unsets the livebox event handler. + * @param[in] cb Event handler + * @privlevel N/P + * @return void * Event handler data + * @retval pointer Pointer of 'data' which is used with the livebox_set_event_handler + * @see livebox_set_event_handler() + */ +extern void *livebox_unset_event_handler(int (*cb)(struct livebox *handler, enum livebox_event_type event, void *data)); + +/** + * @brief Registers the livebox fault event handler. + * @details Argument list: event, pkgname, filename, funcname. + * @param[in] cb Event handler + * @param[in] data Event handler data + * @privlevel N/P + * @return int + * @retval #LB_STATUS_SUCCESS If succeed to set fault event handler + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_MEMORY Not enough memory + * @see livebox_unset_fault_handler() + */ +extern int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data); + +/** + * @brief Unsets the livebox fault event handler. + * @param[in] cb Event handler + * @privlevel N/P + * @return void * Callback data which is set via livebox_set_fault_handler + * @retval pointer Pointer of 'data' which is used with the livebox_set_fault_handler + * @see livebox_set_fault_handler() + */ +extern void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *)); + +/** + * @brief Activates the faulted livebox. + * @details Request result will be returned via return callback. + * @remarks Even though this function returns SUCCESS, it means that it just successfully sent a request to the provider. + * So you have to check the return callback and its "ret" argument. + * @param[in] pkgname Package name which should be activated + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int type + * @retval #LB_STATUS_SUCCESS Successfully sent a request + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Failed to make a request + * @see ret_cb_t + */ +extern int livebox_activate(const char *pkgname, ret_cb_t cb, void *data); + +/** + * @brief Resizes the livebox. + * @details + * Normal mode livebox size + * 1x1=175x175, LB_SIZE_TYPE_1x1 + * 2x1=354x175, LB_SIZE_TYPE_2x1 + * 2x2=354x354, LB_SIZE_TYPE_2x2 + * 4x1=712x175, LB_SIZE_TYPE_4x1 + * 4x2=712x354, LB_SIZE_TYPE_4x2 + * 4x4=712x712, LB_SIZE_TYPE_4x4 + * + * Extended livebox size + * 4x3=712x533, LB_SIZE_TYPE_4x3 + * 4x5=712x891, LB_SIZE_TYPE_4x5 + * 4x6=712x1070, LB_SIZE_TYPE_4x6 + * + * Easy mode livebox size + * 21x21=224x215, LB_SIZE_TYPE_EASY_1x1 + * 23x21=680x215, LB_SIZE_TYPE_EASY_3x1 + * 23x23=680x653, LB_SIZE_TYPE_EASY_3x3 + * + * Special mode livebox size + * 0x0=720x1280, LB_SIZE_TYPE_0x0 + * @remarks You have to check the return callback. + * @param[in] handler Handler of a livebox instance + * @param[in] type Type of a livebox size (e.g., LB_SIZE_TYPE_1x1, ...) + * @param[in] cb Result callback of the resize operation + * @param[in] data User data for return callback + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int type + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY Previous request of resize is in progress + * @retval #LB_STATUS_ERROR_ALREADY Already resized, there is no differences between current size and requested size + * @retval #LB_STATUS_ERROR_PERMISSION Permission denied, you only have view the content of this box + * @retval #LB_STATUS_ERROR_FAULT Failed to make a request + * @see ret_cb_t + */ +extern int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data); + +/** + * @brief Sends the click event for a livebox. + * @param[in] handler Handler of a livebox instance + * @param[in] x Rational X of the content width + * @param[in] y Rational Y of the content height + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully done + */ +extern int livebox_click(struct livebox *handler, double x, double y); + +/** + * @brief Changes the cluster/sub-cluster name of the given livebox handler. + * @param[in] handler Handler of a livebox instance + * @param[in] cluster New cluster of a livebox + * @param[in] category New category of a livebox + * @param[in] cb Result callback for changing the cluster/category of a livebox + * @param[in] data User data for the result callback + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCESS Request is successfully sent. the return callback will be called + * @retval #LB_STATUS_ERROR_BUSY Previous request is not finished yet + * @retval #LB_STATUS_ERROR_ALREADY Group name is same with current one + * @retval #LB_STATUS_ERROR_PERMISSION You have no permission to change property of this livebox instance + * @retval #LB_STATUS_ERROR_FAULT Failed to make a request + * @see ret_cb_t + */ +extern int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data); + +/** + * @brief Gets the cluster and category (sub-cluster) name of the given livebox (it is not I18N format, only English). + * @remarks You have to do not release the cluster & category. + * It is allocated inside of a given livebox instance, so you can only read it. + * @param[in] handler Handler of a livebox instance + * @param[out] cluster Storage(memory) for containing the cluster name + * @param[out] category Storage(memory) for containing the category name + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_SUCCESS Successfully done + */ +extern int livebox_get_group(struct livebox *handler, const char **cluster, const char **category); + +/** + * @brief Gets the period of the livebox handler. + * @remarks If this function returns 0.0f, it means the livebox has no update period or the handle is not valid. + * This function only works after the return callback of livebox_create fucntion is called. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return double + * @retval Current update period of a livebox + * @retval 0.0f This means the box has no update period or the handles is not valid + */ +extern double livebox_period(struct livebox *handler); + +/** + * @brief Changes the update period. + * @param[in] handler Handler of a livebox instance + * @param[in] period New update period of a livebox + * @param[in] cb Result callback of changing the update period of this livebox + * @param[in] data User data for the result callback + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCESS Successfully done + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY + * @retval #LB_STATUS_ERROR_ALREADY + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see ret_cb_t + */ +extern int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data); + +/** + * @brief Checks whether the given livebox is a text type or not. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return livebox_lb_type + * @retval #LB_TYPE_IMAGE Contents of a livebox is based on the image file + * @retval #LB_TYPE_BUFFER Contents of a livebox is based on canvas buffer(shared) + * @retval #LB_TYPE_TEXT Contents of a livebox is based on formatted text file + * @retval #LB_TYPE_PIXMAP Contens of a livebox is shared by the pixmap(depends on X) + * @retval #LB_TYPE_INVALID + * @see livebox_lb_type() + */ +extern enum livebox_lb_type livebox_lb_type(struct livebox *handler); + +/** + * @brief Checks if the given livebox is created by user or not. + * @details If the livebox instance is created by a system this will return 0. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval 0 Automatically created livebox by the provider + * @retval 1 Created by user via livebox_add() + * @see livebox_add() + * @see livebox_set_event_handler() + */ +extern int livebox_is_user(struct livebox *handler); + +/** + * @brief Gets content information string of the given livebox. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return const char * + * @retval content_info Livebox content info that can be used again via content_info argument of livebox_add() + * @see livebox_add() + */ +extern const char *livebox_content(struct livebox *handler); + +/** + * @brief Gets the sub cluster title string of the given livebox. + * @details This API is now used for accessibility. + * Each box should set their content as a string to be read by TTS. + * So if the box has focused on the homescreen, the homescreen will read text using this API. + * @remarks The title returned by this API is read by TTS. + * But it is just recomended to a homescreen. + * So, to read it or not depends on implementation of the homescreen. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return const char * + * @retval sub Cluster name + * @retval @c NULL + */ +extern const char *livebox_category_title(struct livebox *handler); + +/** + * @brief Gets the filename of the given livebox, if it is an IMAGE type livebox. + * @details If the box is developed as image format to represent its contents, the homescreen should know its image file name. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return const char * + * @retval filename If the livebox type is image this function will give you a abs-path of an image file (content is rendered) + * @retval @c NULL If this has no image file or type is not image file. + */ +extern const char *livebox_filename(struct livebox *handler); + +/** + * @brief Gets the package name of the given livebox handler. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return const char * + * @retval pkgname Package name + * @retval @c NULL If the handler is not valid + */ +extern const char *livebox_pkgname(struct livebox *handler); + +/** + * @brief Gets the priority of a current content. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return double + * @retval 0.0f Handler is @c NULL + * @retval -1.0f Handler is not valid (not yet initialized) + * @retval real Number between 0.0 and 1.0 + */ +extern double livebox_priority(struct livebox *handler); + +/** + * @brief Acquires the buffer of a given livebox (only for the buffer type). + * @param[in] handler Handler of a livebox instance + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return void * + * @retval address Address of a FB + * @retval @c NULL If it fails to get fb address + */ +extern void *livebox_acquire_fb(struct livebox *handler); + +/** + * @brief Releases the buffer of a livebox (only for the buffer type). + * @param[in] buffer Buffer + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_SUCCESS Successfully done + * @see livebox_acquire_fb() + */ +extern int livebox_release_fb(void *buffer); + +/** + * @brief Gets the reference count of Livebox buffer (only for the buffer type). + * @param[in] buffer Buffer + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval refcnt Positive integer including ZERO + * @see livebox_pdfb_refcnt() + */ +extern int livebox_fb_refcnt(void *buffer); + +/** + * @brief Acquires the buffer of a PD frame (only for the buffer type). + * @param[in] handler Handler of a livebox instance + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval @c NULL + * @retval adress Address of a buffer of PD + * @see livebox_release_pdfb() + */ +extern void *livebox_acquire_pdfb(struct livebox *handler); + +/** + * @brief Releases the acquired buffer of the PD Frame (only for the buffer type). + * @param[in] buffer Buffer + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_SUCCESS Successfully done + * @see livebox_acquire_pdfb() + */ +extern int livebox_release_pdfb(void *buffer); + +/** + * @brief Gets the reference count of a given PD buffer (only for the buffer type). + * @param[in] buffer Buffer + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval reference Reference count + * @see livebox_fb_refcnt() + */ +extern int livebox_pdfb_refcnt(void *buffer); + +/** + * @brief Gets the size of the Livebox. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_SIZE_TYPE_NxM + * @retval #LB_SIZE_TYPE_INVALID + */ +extern int livebox_size(struct livebox *handler); + +/** + * @brief Gets the size of the Progressive Disclosure. + * @param[in] handler Handler of a livebox instance + * @param[out] w + * @param[out] h + * @privlevel N/P + * @return int type + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_SUCCESS Successfully done + */ +extern int livebox_get_pdsize(struct livebox *handler, int *w, int *h); + +/** + * @brief Gets a list of the supported sizes of a given handler. + * @param[in] handler Handler of a livebox instance + * @param[out] cnt + * @param[out] size_list + * @privlevel N/P + * @return int type + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_SUCCESS Successfully done + */ +extern int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list); + +/** + * @brief Gets BUFFER SIZE of the livebox if it is a buffer type. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval size Size of livebox buffer + */ +extern int livebox_lbfb_bufsz(struct livebox *handler); + +/** + * @brief Gets BUFFER SIZE of the progiressive disclosure if it is a buffer type. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval size Size of PD buffer + */ +extern int livebox_pdfb_bufsz(struct livebox *handler); + +/** + * @brief Sends a content event (for buffer type) to the provider (livebox). + * @param[in] handler Handler of a livebox instance + * @param[in] type Event type + * @param[in] x Coordinates of X axis + * @param[in] y Coordinates of Y axis + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully sent + * @see livebox_access_event() + * @see livebox_key_event() + */ +extern int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y); + +/** + * @brief Sends an access event (for buffer type) to the provider (livebox). + * @param[in] handler Handler of a livebox instance + * @param[in] type Event type + * @param[in] x Coordinates of X axsis + * @param[in] y Coordinates of Y axsis + * @param[in] cb Result callback function + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully sent + * @see livebox_mouse_event() + * @see livebox_key_event() + */ +extern int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data); + +/** + * @brief Sends a key event (for buffer type) to the provider (livebox). + * @param[in] handler Handler of a livebox instance + * @param[in] type Key event type + * @param[in] keycode Code of key + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully sent + * @see livebox_mouse_event() + * @see livebox_access_event() + */ +extern int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data); + +/** + * @brief Sets pin-up status of the given handler. + * @details If the livebox supports the pinup feature, + * you can freeze the update of the given livebox. + * But it is different from pause. + * The box will be updated and it will decide wheter update its content or not when the pinup is on. + * @param[in] handler Handler of a livebox instance + * @param[in] flag Pinup value + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid parameters + * @see ret_cb_t + * @see livebox_set_visibility() + * @see livebox_is_pinned_up() + */ +extern int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data); + +/** + * @brief Checks the PIN-UP status of the given handler. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid parameters + * @retval 1 Box is pinned up + * @retval 0 Box is not pinned up + * @see livebox_set_pinup() + */ +extern int livebox_is_pinned_up(struct livebox *handler); + +/** + * @brief Checks the availability of the PIN-UP feature for the given handler. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval 1 If the box support Pinup feature + * @retval 0 If the box does not support the Pinup feature + * @see livebox_is_pinned_up() + * @see livebox_set_pinup() + */ +extern int livebox_has_pinup(struct livebox *handler); + +/** + * @brief Checks the existence of PD for the given handler. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval 1 If the box support the PD + * @retval 0 If the box has no PD + */ +extern int livebox_has_pd(struct livebox *handler); + +/** + * @brief Creates PD of the given handler. + * @param[in] handler Handler of a livebox instance + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCESS Successfully done + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see ret_cb_t + * @see livebox_create_pd_with_position() + * @see livebox_move_pd() + * @see livebox_destroy_pd() + */ +extern int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data); + +/** + * @brief Creates PD of the given handler with the relative position from livebox. + * @param[in] handler Handler of a livebox instance + * @param[in] x 0.0 ~ 1.0 + * @param[in] y 0.0 ~ 1.0 + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCESS Successfully done + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY Previous operation is not finished yet + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @see livebox_create_pd() + * @see livebox_destroy_pd() + * @see livebox_move_pd() + */ +extern int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data); + +/** + * @brief Updates a position of the given PD. + * @param[in] handler Handler of a livebox instance + * @param[in] x 0.0 ~ 1.0 + * @param[in] y 0.0 ~ 1.0 + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_SUCCESS If sending a request for updating position of the PD has been done successfully + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + */ +extern int livebox_move_pd(struct livebox *handler, double x, double y); + +/** + * @brief Destroys the PD of the given handler if it is created. + * @param[in] handler Handler of a livebox instance + * @param[in] cb + * @param[in] data + * @privlevel platform + * @privilege %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully done + * @see ret_cb_t + */ +extern int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data); + +/** + * @brief Checks the create status of the given livebox handler. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval 0 PD is not created + * @retval 1 PD is created + */ +extern int livebox_pd_is_created(struct livebox *handler); + +/** + * @brief Checks the content type of a progressive disclosure of the given handler. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval #PD_TYPE_BUFFER Contents of a PD is based on canvas buffer(shared) + * @retval #PD_TYPE_TEXT Contents of a PD is based on formatted text file + * @retval #PD_TYPE_PIXMAP Contents of a livebox is shared by the pixmap(depends on X) + * @retval #PD_TYPE_INVALID + * @see livebox_pd_type() + */ +extern enum livebox_pd_type livebox_pd_type(struct livebox *handler); + +/** + * @brief Checks the existence of a livebox about the given package name. + * @param[in] pkgname Package name + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.info + * @return int + * @retval 1 If the box exists + * @retval 0 If the box does not exist + */ +extern int livebox_is_exists(const char *pkgname); + +/** + * @brief Sets a function table for parsing the text content of a livebox. + * @param[in] handler Handler of a livebox instance + * @param[in] ops + * @privlevel N/P + * @return int + * @retval #LB_STATUS_SUCCESS Successfully done + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @see livebox_set_pd_text_handler() + */ +extern int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops); + +/** + * @brief Sets a function table for parsing the text content of a Progressive Disclosure. + * @param[in] handler Handler of a livebox instance + * @param[in] ops + * @privlevel N/P + * @return int + * @retval #LB_STATUS_SUCCESS Successfully done + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @see livebox_set_text_handler() + */ +extern int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops); + +/** + * @brief Emits a text signal to the given livebox only if it is a text type. + * @param[in] handler Handler of a livebox instance + * @param[in] emission Emission string + * @param[in] source Source string + * @param[in] sx Start X + * @param[in] sy Start Y + * @param[in] ex End X + * @param[in] ey End Y + * @param[in] cb Result callback + * @param[in] data Callback data + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid parameters + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully emitted + * @see ret_cb_t + */ +extern int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data); + +/** + * @brief Sets a private data pointer to carry it using the given handler. + * @param[in] handler Handler of a livebox instance + * @param[in] data Data pointer + * @privlevel N/P + * @return int + * @retval #LB_STATUS_SUCCESS Successfully registered + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @see livebox_get_data() + */ +extern int livebox_set_data(struct livebox *handler, void *data); + +/** + * @brief Gets a private data pointer which is carried by a given handler. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return void * + * @retval data Data pointer + * @retval @c NULL If there is no data + * @see livebox_set_data() + */ +extern void *livebox_get_data(struct livebox *handler); + +/** + * @brief Subscribes an event for liveboxes only in a given cluster and sub-cluster. + * @details If you wrote a view-only client, + * you can receive the event of specific liveboxes which belong to a given cluster/category. + * But you cannot modify their attributes (such as size, ...). + * @param[in] cluster Cluster ("*" can be used for subscribe all cluster's liveboxes event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe liveboxes events of all category(sub-cluster) in a given "cluster") + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully requested + * @see livebox_unsubscribe_group() + */ +extern int livebox_subscribe_group(const char *cluster, const char *category); + +/** + * @brief Unsubscribes an event for the liveboxes, but you will receive already added liveboxes events. + * @param[in] cluster Cluster("*" can be used for subscribe all cluster's liveboxes event; If you use the "*", value in the category will be ignored) + * @param[in] category Category ("*" can be used for subscribe all sub-cluster's liveboxes event in a given "cluster") + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully requested + * @see livebox_subscribe_group() + */ +extern int livebox_unsubscribe_group(const char *cluster, const char *category); + +/** + * @brief Refreshes the group (cluster/sub-cluser (aka. category)). + * @details This function will trigger the update of all liveboxes in a given cluster/category group. + * @remarks Basically, a default livebox system doesn't use the cluster/category concept. + * But you can use it. So if you decide to use it, then you can trigger the update of all liveboxes in the given group. + * @param[in] cluster Cluster ID + * @param[in] category Sub-cluster ID + * @param[in] force 1 if the boxes should be updated even if they are paused + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully requested + * @see livebox_refresh() + */ +extern int livebox_refresh_group(const char *cluster, const char *category, int force); + +/** + * @brief Refreshes a livebox. + * @param[in] handler Handler of a livebox instance + * @param[in] force 1 if the box should be updated even if it is paused + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully requested + * @see livebox_refresh_group() + */ +extern int livebox_refresh(struct livebox *handler, int force); + +/** + * @brief Gets Pixmap Id of a livebox content. + * @details This function doesn't guarantee the life-cycle of the pixmap. + * If the service provider destroyed the pixmap, you will not know about it. + * So you should validate it before accessing it. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval 0 If the pixmap is not created + * @retval pixmap Pixmap Id need to be casted to (unsigned int) type + * @see livebox_pd_pixmap() + */ +extern int livebox_lb_pixmap(const struct livebox *handler); + +/** + * @brief Gets Pixmap Id of a PD content. + * @details This function doesn't guarantee the life-cycle of the pixmap. + * If the service provider destroyed the pixmap, you will not know about it. + * So you should validate it before accessing it. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval 0 If the pixmap is not created + * @retval pixmap Pixmap Id need to be casted to (unsigned int) type + * @see livebox_lb_pixmap() + */ +extern int livebox_pd_pixmap(const struct livebox *handler); + +/** + * @brief Acquires the pixmap of PD. + * @details After acquiring the pixmap of PD, it will not be destroyed. + * So if the new update is comming with a new pixmap Id, you should release old pixmap manually. + * @param[in] handler Handler of a livebox instance + * @param[in] cb Result callback for acquiring request + * @param[in] data Callback Data + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Failed to send a request to the service provider or there is critical error that is unrecoverable + * @retval #LB_STATUS_SUCCESS Successfully requested to acquire the pixmap of PD + * @see livebox_release_pd_pixmap() + * @see livebox_acquire_lb_pixmap() + * @see ret_cb_t + */ +extern int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data); + +/** + * @brief Releases the acquired pixmap ID. + * @param[in] handler Handler of a livebox instance + * @param[in] pixmap Pixmap Id to release it + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully released (request is sent) + * @see livebox_acquire_pd_pixmap() + * @see livebox_release_lb_pixmap() + */ +extern int livebox_release_pd_pixmap(struct livebox *handler, int pixmap); + +/** + * @brief Gets the PIXMAP of a livebox. + * @details Even if a render process releases the pixmap, the pixmap will be kept before being released by livebox_release_lb_pixmap. + * You should release the pixmap manually. + * @param[in] handler Handler of a livebox instance + * @param[in] cb Callback function which will be called with result of acquiring lb pixmap + * @param[in] data Callback data + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully requested + * @pre Livebox service system should support the PIXMAP type buffer. + * The livebox should be designed to use the buffer (script type). + * @see livebox_release_lb_pixmap() + * @see livebox_acquire_pd_pixmap() + * @see ret_cb_t + */ +extern int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data); + +/** + * @brief Releases the pixmap of a livebox. + * @details After a client gets a new pixmap or does not need to keep the current pixmap anymore, use this function to release it. + * If there is no user for a given pixmap, the pixmap will be destroyed. + * @param[in] handler Handler of a livebox instance + * @param[in] pixmap Pixmap Id of given livebox handler + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully done + * @pre The pixmap should be acquired by livebox_acquire_lb_pixmap + * @see livebox_acquire_lb_pixmap() + * @see livebox_release_pd_pixmap() + */ +extern int livebox_release_lb_pixmap(struct livebox *handler, int pixmap); + +/** + * @brief Updates a visible state of the livebox. + * @param[in] handler Handler of a livebox instance + * @param[in] state Configure the current visible state of a livebox + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY + * @retval #LB_STATUS_ERROR_PERMISSION + * @retval #LB_STATUS_ERROR_ALREADY + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully done + */ +extern int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state); + +/** + * @brief Gets the current visible state of a livebox. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return livebox_visible_state + * @retval #LB_SHOW Livebox is shown (Default state) + * @retval #LB_HIDE Livebox is hidden, Update timer is not frozen (but a user cannot receive any updated events; a user should refresh(reload) the content of a livebox when a user make this show again) + * @retval #LB_HIDE_WITH_PAUSE Livebox is hidden, it will pause the update timer, but if a livebox updates its contents, update event will occur + * @retval #LB_VISIBLE_ERROR To enlarge the size of this enumeration type + */ +extern enum livebox_visible_state livebox_visibility(struct livebox *handler); + +/** + * @brief Sets an update mode of the current livebox. + * @details If you set 1 for active update mode, you should get a buffer without updated event from provider. + * But if it is passive mode, you have to update content of a box when you get updated events. + * Default is Passive mode. + * @param[in] handler Handler of a livebox instance + * @param[in] active_update 1 means active update, 0 means passive update (default) + * @param[in] cb Result callback function + * @param[in] data Callback data + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_ERROR_BUSY + * @retval #LB_STATUS_ERROR_PERMISSION + * @retval #LB_STATUS_ERROR_ALREADY + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_SUCCESS Successfully done + * @see ret_cb_t + */ +extern int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data); + +/** + * @brief Checks the active update mode of the given livebox. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return int + * @retval 0 If passive mode + * @retval 1 If active mode or error code + */ +extern int livebox_is_active_update(struct livebox *handler); + +/** + * @brief Syncs manually + * param[in] handler Handler of a livebox instance + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return void + * @retval #LB_STATUS_SUCCESS If success + * @retval #LB_STATUS_ERROR_INVALID Invalid handle + * @see livebox_set_manual_sync() + * @see livebox_manual_sync() + * @see livebox_sync_lb_fb() + */ +extern int livebox_sync_pd_fb(struct livebox *handler); + +/** + * @brief Syncs manually + * @param[in] handler Handler of a livebox instance + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return void + * @retval #LB_STATUS_SUCCESS If success + * @retval #LB_STATUS_ERROR_INVALID Invalid handle + * @see livebox_set_manual_sync() + * @see livebox_manual_sync() + * @see livebox_sync_pd_fb() + */ +extern int livebox_sync_lb_fb(struct livebox *handler); + +/** + * @brief Gets an alternative icon of the given livebox instance. + * @details If the box should be represented as a shortcut icon, this function will get the alternative icon. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return const char * + * @retval address Absolute path of an alternative icon file + * @retval @c NULL Livebox has no alternative icon file + * @see livebox_alt_name() + */ +extern const char *livebox_alt_icon(struct livebox *handler); + +/** + * @brief Gets an alternative name of the given livebox instance. + * @details If the box should be represented as a shortcut name, this function will get the alternative name. + * @param[in] handler Handler of a livebox instance + * @privlevel N/P + * @return const char * + * @retval name Alternative name of a livebox + * @retval @c NULL Livebox has no alternative name + * @see livebox_alt_icon() + */ +extern const char *livebox_alt_name(struct livebox *handler); + +/** + * @brief Gets a lock for a frame buffer. + * @details This function should be used to prevent from rendering to the frame buffer while reading it. + * And the locking area should be short and must be released ASAP, or the render thread will be hanged. + * @param[in] handler Handler of a livebox instance + * @param[in] is_pd 1 for PD or 0 + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_SUCCESS Successfully done + * @see livebox_release_fb_lock() + */ +extern int livebox_acquire_fb_lock(struct livebox *handler, int is_pd); + +/** + * @brief Releases a lock of the frame buffer. + * @details This function should be called ASAP after acquiring a lock of FB, or the render process will be blocked. + * @param[in] handler Handler of a livebox instance + * @param[in] is_pd 1 for PD or 0 + * @privlevel platform + * @privileve %http://developer.samsung.com/privilege/core/dynamicbox.viewer + * @return int + * @retval #LB_STATUS_ERROR_FAULT Unrecoverable error occurred + * @retval #LB_STATUS_ERROR_INVALID Invalid argument + * @retval #LB_STATUS_SUCCESS Successfully done + * @see livebox_acquire_fb_lock() + */ +extern int livebox_release_fb_lock(struct livebox *handler, int is_pd); + +/** + * @brief Sets options for controlling a livebox sub-system. + * @details + * LB_OPTION_FRAME_DROP_FOR_RESIZE + * While resizing the box, viewer doesn't want to know the updated frames of an old size content anymore. + * In that case, turn this on, the provider will not send the updated event to the viewer about an old content. + * So the viewer can reduce its burden to update unnecessary frames. + * LB_OPTION_MANUAL_SYNC + * If you don't want to update frames automatically, or you want only reload the frames by your hands, (manually) + * Turn this on. + * After turnning it on, you should sync it using livebox_sync_pd_fb and livebox_sync_lb_pfb. + * LB_OPTION_SHARED_CONTENT + * If this option is turnned on, even though you create a new livebox, + * if there are already added same instances that have same contents, the instance will not be created again. + * Instead of creating a new instance, a viewer will provide an old instance with a new handle. + * @param[in] option Option which will be affected by this call + * @param[in] state New value for given option + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Unknown option + * @retval #LB_STATUS_ERROR_FAULT Failed to change the state of option + * @retval #LB_STATUS_SUCCESS Successfully changed + * @see livebox_get_option() + * @see livebox_sync_pd_fb() + * @see livebox_sync_lb_fb() + */ +extern int livebox_set_option(enum livebox_option_type option, int state); + +/** + * @brief Gets options of a livebox sub-system. + * @param[in] option Type of option + * @privlevel N/P + * @return int + * @retval #LB_STATUS_ERROR_INVALID Invalid option + * @retval #LB_STATUS_ERROR_FAULT Failed to get option + * @retval >=0 Value of given option (must be >=0) + * @see livebox_set_option() + */ +extern int livebox_option(enum livebox_option_type option); + + +/** + * @brief Set a handler for launching an app for auto-launch feature + * @details If a user clicks a box, and the box uses auto-launch option, the launcher_handler will be called. + * @param[in] launch_handler Handler for launching an app manually + * @param[in] data Callback data which will be given a data for launch_handler + * @privlevel N/P + * @return int type + * @retval #LB_STATUS_SUCCESS Succeed to set new handler. there is no other cases + */ +extern int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/livebox-viewer.pc.in b/livebox-viewer/livebox-viewer.pc.in similarity index 87% rename from livebox-viewer.pc.in rename to livebox-viewer/livebox-viewer.pc.in index 06f4891..2899b63 100644 --- a/livebox-viewer.pc.in +++ b/livebox-viewer/livebox-viewer.pc.in @@ -6,6 +6,7 @@ includedir=@INCLUDEDIR@ Name: livebox-viewer Description: livebox supporting library Version: @VERSION@ +Requires.private: dynamicbox_viewer Libs: -L${libdir} -llivebox-viewer Cflags: -I${includedir} cppflags: -I${includedir} diff --git a/livebox-viewer/src/livebox.c b/livebox-viewer/src/livebox.c new file mode 100644 index 0000000..58082a5 --- /dev/null +++ b/livebox-viewer/src/livebox.c @@ -0,0 +1,595 @@ +#include + +#include +#include + +#include "livebox.h" + +#define EAPI __attribute__((visibility("default"))) + +enum lb_type { /*!< Must have to be sync with data-provider-master */ + _LB_TYPE_NONE = 0x0, + _LB_TYPE_SCRIPT, + _LB_TYPE_FILE, + _LB_TYPE_TEXT, + _LB_TYPE_BUFFER, + _LB_TYPE_ELEMENTARY +}; + +enum pd_type { /*!< Must have to be sync with data-provider-master */ + _PD_TYPE_NONE = 0x0, + _PD_TYPE_SCRIPT, + _PD_TYPE_TEXT, + _PD_TYPE_BUFFER, + _PD_TYPE_ELEMENTARY +}; + +enum livebox_state { + CREATE = 0xBEEFbeef, + DELETE = 0xDEADdead, /* Delete only for this client */ + DESTROYED = 0x00DEAD00 +}; + +struct livebox_common { + enum livebox_state state; + + struct dlist *livebox_list; + int refcnt; + + char *cluster; + char *category; + + char *pkgname; + char *id; + + char *content; + char *title; + char *filename; + + double timestamp; + + struct alt_info { + char *icon; + char *name; + } alt; + + enum livebox_delete_type delete_type; + + int is_user; + int is_pd_created; + int is_pinned_up; + int is_active_update; + enum livebox_visible_state visible; + + struct { + enum lb_type type; + struct fb_info *fb; + + int size_list; + + int width; + int height; + double priority; + + char *auto_launch; + double period; + int pinup_supported; + int mouse_event; + + /* For the filtering event */ + double x; + double y; + char *lock; + int lock_fd; + } lb; + + struct { + enum pd_type type; + struct fb_info *fb; + + int width; + int height; + + int default_width; + int default_height; + + /* For the filtering event */ + double x; + double y; + char *lock; + int lock_fd; + } pd; + + int nr_of_sizes; + + struct requested_flag { + unsigned int created:1; + unsigned int deleted:1; + unsigned int pinup:1; + unsigned int group_changed:1; + unsigned int period_changed:1; + unsigned int size_changed:1; + unsigned int pd_created:1; + unsigned int pd_destroyed:1; + unsigned int update_mode:1; + unsigned int access_event:1; + unsigned int key_event:1; + + /*! + * \note + * Reserved + */ + unsigned int reserved:21; + } request; +}; + +struct job_item { + struct livebox *handle; + ret_cb_t cb; + int ret; + void *data; +}; + +struct livebox { + enum livebox_state state; + + int refcnt; + int paused_updating; + + enum livebox_visible_state visible; + struct livebox_common *common; + + void *data; + + struct callback_table { + struct livebox_script_operators lb_ops; + struct livebox_script_operators pd_ops; + + struct created { + ret_cb_t cb; + void *data; + } created; + + struct deleted { + ret_cb_t cb; + void *data; + } deleted; + + struct pinup { + ret_cb_t cb; + void *data; + } pinup; + + struct group_changed { + ret_cb_t cb; + void *data; + } group_changed; + + struct period_changed { + ret_cb_t cb; + void *data; + } period_changed; + + struct size_changed { + ret_cb_t cb; + void *data; + } size_changed; + + struct pd_created { + ret_cb_t cb; + void *data; + } pd_created; + + struct pd_destroyed { + ret_cb_t cb; + void *data; + } pd_destroyed; + + struct update_mode { + ret_cb_t cb; + void *data; + } update_mode; + + struct access_event { + ret_cb_t cb; + void *data; + } access_event; + + struct key_event { + ret_cb_t cb; + void *data; + } key_event; + } cbs; +}; + +EAPI int livebox_init(void *disp) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_fini(void) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_client_paused(void) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_client_resumed(void) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data) +{ + return NULL; +} + +EAPI int livebox_del(struct livebox *handler, int type, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_event_handler(int (*cb)(struct livebox *handler, enum livebox_event_type event, void *data), void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *handler, enum livebox_event_type event, void *data)) +{ + return NULL; +} + +EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *)) +{ + return NULL; +} + +EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_click(struct livebox *handler, double x, double y) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI double livebox_period(struct livebox *handler) +{ + return 0.0f; +} + +EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler) +{ + return LB_TYPE_INVALID; +} + +EAPI int livebox_is_user(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI const char *livebox_content(struct livebox *handler) +{ + return NULL; +} + +EAPI const char *livebox_category_title(struct livebox *handler) +{ + return NULL; +} + +EAPI const char *livebox_filename(struct livebox *handler) +{ + return NULL; +} + +EAPI const char *livebox_pkgname(struct livebox *handler) +{ + return NULL; +} + +EAPI double livebox_priority(struct livebox *handler) +{ + return 0.0f; +} + +EAPI void *livebox_acquire_fb(struct livebox *handler) +{ + return NULL; +} + +EAPI int livebox_release_fb(void *buffer) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_fb_refcnt(void *buffer) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI void *livebox_acquire_pdfb(struct livebox *handler) +{ + return NULL; +} + +EAPI int livebox_release_pdfb(void *buffer) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_pdfb_refcnt(void *buffer) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_size(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_lbfb_bufsz(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_pdfb_bufsz(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_is_pinned_up(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_has_pinup(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_has_pd(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_move_pd(struct livebox *handler, double x, double y) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_pd_is_created(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler) +{ + return PD_TYPE_INVALID; +} + +EAPI int livebox_is_exists(const char *pkgname) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_data(struct livebox *handler, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI void *livebox_get_data(struct livebox *handler) +{ + return NULL; +} + +EAPI int livebox_subscribe_group(const char *cluster, const char *category) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_unsubscribe_group(const char *cluster, const char *category) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_refresh_group(const char *cluster, const char *category, int force) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_refresh(struct livebox *handler, int force) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_lb_pixmap(const struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_pd_pixmap(const struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler) +{ + return LB_VISIBLE_ERROR; +} + +EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_is_active_update(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_sync_pd_fb(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_sync_lb_fb(struct livebox *handler) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI const char *livebox_alt_icon(struct livebox *handler) +{ + return NULL; +} + +EAPI const char *livebox_alt_name(struct livebox *handler) +{ + return NULL; +} + +EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_option(enum livebox_option_type option, int state) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_option(enum livebox_option_type option) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +EAPI int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data) +{ + return LB_STATUS_ERROR_NOT_IMPLEMENTED; +} + +/* End of a file */ diff --git a/packaging/liblivebox-viewer.manifest b/packaging/libdynamicbox_viewer.manifest similarity index 100% rename from packaging/liblivebox-viewer.manifest rename to packaging/libdynamicbox_viewer.manifest diff --git a/packaging/libdynamicbox_viewer.spec b/packaging/libdynamicbox_viewer.spec new file mode 100644 index 0000000..3244b6f --- /dev/null +++ b/packaging/libdynamicbox_viewer.spec @@ -0,0 +1,123 @@ +%bcond_with wayland + +Name: libdynamicbox_viewer +Summary: Library for developing the application +Version: 1.0.0 +Release: 1 +Group: HomeTF/DynamicBox +License: Flora +Source0: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest +BuildRequires: cmake, gettext-tools, coreutils +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) +BuildRequires: pkgconfig(com-core) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(db-util) +BuildRequires: pkgconfig(livebox-service) +BuildRequires: pkgconfig(dynamicbox_service) +BuildRequires: pkgconfig(vconf) +BuildRequires: model-build-features + +%if %{with wayland} +%else +BuildRequires: pkgconfig(x11) +BuildRequires: pkgconfig(xext) +%endif + +%if "%{model_build_feature_livebox}" == "0" +ExclusiveArch: +%endif + +%description +API for creating a new instance of the dynamicbox and managing its life-cycle. + +%package devel +Summary: Development Library for Dynamic Box Viewer Application (dev) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Header and package configuration files for the dynamicbox viewer 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 %{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} -DDYNAMICBOX_ENABLED=On +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} +%make_install + +%post -n %{name} -p /sbin/ldconfig +%postun -n %{name} -p /sbin/ldconfig + +%files -n %{name} +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/libdynamicbox_viewer.so* +%{_datarootdir}/license/libdynamicbox_viewer + +%files devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_includedir}/dynamicbox_viewer/dynamicbox.h +%{_libdir}/pkgconfig/dynamicbox_viewer.pc + +################################################# +# liblivebox-viewer (for old version) +%package -n liblivebox-viewer +Summary: Library for developing the dynamicbox viewer (old version) +Group: HomeTF/Dynamicbox +License: Flora +Requires: libdynamicbox_viewer + +%description -n liblivebox-viewer +Provider APIs to develop the dynamicbox viewer applications. (old version) + +%package -n liblivebox-viewer-devel +Summary: Header & package configuration files to support development of the dynamicbox viewer applications. (old version) +Group: Development/Libraries +Requires: liblivebox-viewer + +%description -n liblivebox-viewer-devel +Dynamicbox provider application development library (dev) (old version) + +%files -n liblivebox-viewer +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_libdir}/liblivebox-viewer.so* +%{_datarootdir}/license/liblivebox-viewer + +%files -n liblivebox-viewer-devel +%manifest %{name}.manifest +%defattr(-,root,root,-) +%{_includedir}/livebox-viewer/livebox.h +%{_libdir}/pkgconfig/livebox-viewer.pc + +# End of a file diff --git a/packaging/liblivebox-viewer.spec b/packaging/liblivebox-viewer.spec deleted file mode 100644 index e92c499..0000000 --- a/packaging/liblivebox-viewer.spec +++ /dev/null @@ -1,91 +0,0 @@ -%bcond_with wayland - -Name: liblivebox-viewer -Summary: Library for developing the application -Version: 0.31.0 -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(aul) -BuildRequires: pkgconfig(glib-2.0) -BuildRequires: pkgconfig(gio-2.0) -BuildRequires: pkgconfig(com-core) -BuildRequires: pkgconfig(sqlite3) -BuildRequires: pkgconfig(db-util) -BuildRequires: pkgconfig(livebox-service) -BuildRequires: pkgconfig(vconf) - -%if %{with wayland} -%else -BuildRequires: pkgconfig(x11) -BuildRequires: pkgconfig(xext) -%endif - -%if "%{sec_product_feature_livebox}" == "0" -ExclusiveArch: -%endif - -%description -API for creating a new instance of the livebox and managing its life-cycle. - -%package devel -Summary: Livebox viewer development library (dev) -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} - -%description devel -Header and package configuration files for the livebox viewer 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 %{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} -make %{?jobs:-j%jobs} - -%install -rm -rf %{buildroot} -%make_install -mkdir -p %{buildroot}/%{_datarootdir}/license - -%post -n liblivebox-viewer -p /sbin/ldconfig -%postun -n liblivebox-viewer -p /sbin/ldconfig - -%files -n liblivebox-viewer -%manifest %{name}.manifest -%defattr(-,root,root,-) -%{_libdir}/*.so* -%{_datarootdir}/license/* - -%files devel -%manifest %{name}.manifest -%defattr(-,root,root,-) -%{_includedir}/livebox-viewer/livebox.h -%{_libdir}/pkgconfig/*.pc - -# End of a file diff --git a/src/client.c b/src/client.c deleted file mode 100644 index b3088fa..0000000 --- a/src/client.c +++ /dev/null @@ -1,1770 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include - -#include "debug.h" -#include "client.h" -#include "livebox.h" -#include "livebox_internal.h" -#include "desc_parser.h" -#include "fb.h" -#include "util.h" -#include "master_rpc.h" -#include "conf.h" -#include "file_service.h" -#include "dlist.h" - -int errno; - -static struct info { - int fd; - guint timer_id; - char *client_addr; -} s_info = { - .fd = -1, - .timer_id = 0, - .client_addr = NULL, -}; - -static struct packet *master_fault_package(pid_t pid, int handle, const struct packet *packet) -{ - const char *pkgname; - const char *id; - const char *function; - - if (packet_get(packet, "sss", &pkgname, &id, &function) != 3) { - ErrPrint("Invalid arguments\n"); - return NULL; - } - - DbgPrint("[%s]\n", pkgname); - master_rpc_clear_fault_package(pkgname); - lb_invoke_fault_handler(LB_FAULT_DEACTIVATED, pkgname, id, function); - return NULL; -} - -static struct packet *master_hold_scroll(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox_common *common; - struct livebox *livebox; - const char *pkgname; - const char *id; - int seize; - int ret; - struct dlist *l; - - ret = packet_get(packet, "ssi", &pkgname, &id, &seize); - if (ret != 3) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance(%s) is not exists\n", id); - goto out; - } - - DbgPrint("HOLD: [%s] seize(%d)\n", id, seize); - seize = seize ? LB_EVENT_HOLD_SCROLL : LB_EVENT_RELEASE_SCROLL; - dlist_foreach(common->livebox_list, l, livebox) { - lb_invoke_event_handler(livebox, seize); - } - -out: - return NULL; -} - -static struct packet *master_pinup(pid_t pid, int handle, const struct packet *packet) -{ - const char *pkgname; - const char *id; - const char *content; - struct livebox *handler; - struct dlist *l; - struct dlist *n; - struct livebox_common *common; - char *new_content; - int ret; - int status; - int pinup; - - ret = packet_get(packet, "iisss", &status, &pinup, &pkgname, &id, &content); - if (ret != 5) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance (%s) is not exists\n", id); - goto out; - } - - if (status == (int)LB_STATUS_SUCCESS) { - new_content = strdup(content); - if (new_content) { - free(common->content); - common->content = new_content; - common->is_pinned_up = pinup; - } else { - ErrPrint("Heap: %s\n", strerror(errno)); - status = LB_STATUS_ERROR_MEMORY; - } - } - - common->request.pinup = 0; - - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.pinup.cb) { - ret_cb_t cb; - void *cbdata; - - /* Make sure that user can call pinup API in its result callback */ - cb = handler->cbs.pinup.cb; - cbdata = handler->cbs.pinup.data; - - handler->cbs.pinup.cb = NULL; - handler->cbs.pinup.data = NULL; - - cb(handler, status, cbdata); - } else if (status == (int)LB_STATUS_SUCCESS) { - lb_invoke_event_handler(handler, LB_EVENT_PINUP_CHANGED); - } - } - -out: - return NULL; -} - -static struct packet *master_deleted(pid_t pid, int handle, const struct packet *packet) -{ - const char *pkgname; - const char *id; - double timestamp; - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - struct dlist *n; - int reason; - - if (packet_get(packet, "ssdi", &pkgname, &id, ×tamp, &reason) != 4) { - ErrPrint("Invalid arguemnt\n"); - goto out; - } - - DbgPrint("[%s]\n", pkgname); - common = lb_find_common_handle_by_timestamp(timestamp); - if (!common) { - /*! - * \note - * This can be happens only if the user delete a livebox - * right after create it before receive created event. - */ - goto out; - } - - /*!< Check validity of this "handler" */ - if (common->state != CREATE) { - if (common->state != DELETE) { - /*! - * \note - * This is not possible - */ - ErrPrint("Already deleted handler (%s - %s)\n", pkgname, id); - return NULL; - } - } - - common->request.deleted = 0; - /*! - * We should change the state of "common handler' before handling the callbacks. - * Because if user tries to create a new handle in the callbacks, - * find_sharable_common_handle will returns destroying object. - * Then we will get panic. - * To prevent it, we should change its state first. - */ - common->state = DELETE; - - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.created.cb) { - ret_cb_t cb; - void *cbdata; - /*! - * \note - * - * "if (handler->id == NULL) {" - * - * The instance is not created yet. - * But the master forcely destroy it and send destroyed event to this - * without the created event. - * - * It could be destroyed when a slave has critical error(fault) - * before creating an instance successfully. - */ - if (handler->cbs.created.cb == handler->cbs.deleted.cb) { - if (handler->cbs.created.data != handler->cbs.deleted.data) { - DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id); - } - - handler->cbs.deleted.cb = NULL; - handler->cbs.deleted.data = NULL; - } - - cb = handler->cbs.created.cb; - cbdata = handler->cbs.created.data; - - handler->cbs.created.cb = NULL; - handler->cbs.created.data = NULL; - - if (reason == (int)LB_STATUS_SUCCESS) { - reason = LB_STATUS_ERROR_CANCEL; - } - - cb(handler, reason, cbdata); - } else if (common->id) { - if (handler->cbs.deleted.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.deleted.cb; - cbdata = handler->cbs.deleted.data; - - handler->cbs.deleted.cb = NULL; - handler->cbs.deleted.data = NULL; - - cb(handler, reason, cbdata); - } else { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - } - } - - /* Just try to delete it, if a user didn't remove it from the live box list */ - lb_unref(handler, 1); - } - -out: - return NULL; -} - -static struct packet *master_lb_update_begin(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - const char *pkgname; - const char *id; - const char *content; - const char *title; - const char *fbfile; - double priority; - int ret; - - ret = packet_get(packet, "ssdsss", &pkgname, &id, &priority, &content, &title, &fbfile); - if (ret != 6) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance[%s] is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("(%s) is not created\n", id); - goto out; - } - - lb_set_priority(common, priority); - lb_set_content(common, content); - lb_set_title(common, title); - - /*! - * \NOTE - * Width & Height is not changed in this case. - * If the active update is began, the size should not be changed, - * And if the size is changed, the provider should finish the updating first. - * And then begin updating again after change its size. - */ - if (lb_get_lb_fb(common)) { - (void)lb_set_lb_fb(common, fbfile); - - ret = lb_sync_lb_fb(common); - - if (ret != (int)LB_STATUS_SUCCESS) { - ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret); - } else { - struct dlist *l; - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_BEGIN); - } - } - } else { - ErrPrint("Invalid request[%s], %s\n", id, fbfile); - } - -out: - return NULL; -} - -static struct packet *master_pd_update_begin(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - const char *pkgname; - const char *id; - const char *fbfile; - int ret; - - ret = packet_get(packet, "sss", &pkgname, &id, &fbfile); - if (ret != 2) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance[%s] is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("[%s] is not created\n", id); - goto out; - } - - if (lb_get_pd_fb(common)) { - (void)lb_set_pd_fb(common, fbfile); - - ret = lb_sync_pd_fb(common); - if (ret != (int)LB_STATUS_SUCCESS) { - ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret); - } else { - struct dlist *l; - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_BEGIN); - } - } - } else { - ErrPrint("Invalid request[%s], %s\n", id, fbfile); - } - -out: - return NULL; -} - -static struct packet *master_lb_update_end(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - const char *pkgname; - const char *id; - int ret; - - ret = packet_get(packet, "ss", &pkgname, &id); - if (ret != 2) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance[%s] is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("[%s] is not created\n", id); - goto out; - } - - if (lb_get_lb_fb(common)) { - struct dlist *l; - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_END); - } - } else { - ErrPrint("Invalid request[%s]\n", id); - } - -out: - return NULL; -} - -static struct packet *master_key_status(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - const char *pkgname; - const char *id; - int ret; - int status; - - ret = packet_get(packet, "ssi", &pkgname, &id, &status); - if (ret != 3) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance[%s] is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("[%s] is not created\n", id); - goto out; - } - - common->request.key_event = 0; - dlist_foreach(common->livebox_list, l, handler) { - if (handler->cbs.key_event.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.key_event.cb; - cbdata = handler->cbs.key_event.data; - - handler->cbs.key_event.cb = NULL; - handler->cbs.key_event.data = NULL; - - cb(handler, status, cbdata); - } else { - ErrPrint("Invalid event[%s]\n", id); - } - } - -out: - return NULL; -} - -static struct packet *master_request_close_pd(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - const char *pkgname; - const char *id; - int ret; - int reason; - - ret = packet_get(packet, "ssi", &pkgname, &id, &reason); - if (ret != 3) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance[%s] is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("[%s] is not created\n", id); - goto out; - } - - if (!common->is_pd_created) { - DbgPrint("PD is not created, closing what?(%s)\n", id); - goto out; - } - - DbgPrint("Reason: %d\n", reason); - - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_REQUEST_CLOSE_PD); - } -out: - return NULL; -} - -static struct packet *master_access_status(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - const char *pkgname; - const char *id; - int ret; - int status; - - ret = packet_get(packet, "ssi", &pkgname, &id, &status); - if (ret != 3) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance[%s] is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("[%s] is not created\n", id); - goto out; - } - - common->request.access_event = 0; - dlist_foreach(common->livebox_list, l, handler) { - if (handler->cbs.access_event.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.access_event.cb; - cbdata = handler->cbs.access_event.data; - - handler->cbs.access_event.cb = NULL; - handler->cbs.access_event.data = NULL; - - cb(handler, status, cbdata); - } - } -out: - return NULL; -} - -static struct packet *master_pd_update_end(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - const char *pkgname; - const char *id; - int ret; - - ret = packet_get(packet, "ss", &pkgname, &id); - if (ret != 2) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance[%s] is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("[%s] is not created\n", id); - goto out; - } - - if (lb_get_lb_fb(common)) { - struct dlist *l; - - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_END); - } - } else { - ErrPrint("Invalid request[%s]", id); - } - -out: - return NULL; -} - -static struct packet *master_lb_updated(pid_t pid, int handle, const struct packet *packet) -{ - const char *pkgname; - const char *id; - const char *fbfile; - const char *content; - const char *title; - const char *safe_file; - const char *icon; - const char *name; - struct livebox *handler; - struct livebox_common *common; - int lb_w; - int lb_h; - double priority; - int ret; - - ret = packet_get(packet, "sssiidsssss", - &pkgname, &id, - &fbfile, &lb_w, &lb_h, - &priority, &content, &title, - &safe_file, &icon, &name); - if (ret != 11) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("instance(%s) is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - /*! - * \note - * Already deleted by the user. - * Don't try to notice anything with this, Just ignore all events - * Beacuse the user doesn't wants know about this anymore - */ - ErrPrint("(%s) is not exists, but updated\n", id); - goto out; - } - - lb_set_priority(common, priority); - lb_set_content(common, content); - lb_set_title(common, title); - lb_set_size(common, lb_w, lb_h); - lb_set_filename(common, safe_file); - - if (lb_text_lb(common)) { - const char *common_filename; - - common_filename = common->filename ? common->filename : util_uri_to_path(common->id); - - (void)parse_desc(common, common_filename, 0); - /*! - * \note - * DESC parser will call the "text event callback". - * Don't need to call global event callback in this case. - */ - goto out; - } else if (lb_get_lb_fb(common)) { - /*! - * \todo - * replace this with "flag" instead of "callback address" - */ - if (conf_frame_drop_for_resizing() && common->request.size_changed) { - /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ - DbgPrint("Discards obsoloted update event\n"); - ret = LB_STATUS_ERROR_BUSY; - } else { - (void)lb_set_lb_fb(common, fbfile); - - if (!conf_manual_sync()) { - ret = lb_sync_lb_fb(common); - if (ret != (int)LB_STATUS_SUCCESS) { - ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret); - } - } else { - ret = LB_STATUS_SUCCESS; - } - } - } else { - ret = LB_STATUS_SUCCESS; - } - - if (ret == (int)LB_STATUS_SUCCESS) { - struct dlist *l; - struct dlist *n; - - dlist_foreach_safe(common->livebox_list, l, n, handler) { - lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED); - } - } - -out: - return NULL; -} - -static struct packet *master_pd_created(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - const char *pkgname; - const char *id; - const char *buf_id; - struct dlist *l; - struct dlist *n; - int width; - int height; - int ret; - int status; - - ret = packet_get(packet, "sssiii", &pkgname, &id, &buf_id, &width, &height, &status); - if (ret != 6) { - ErrPrint("Invalid argument\n"); - goto out; - } - - DbgPrint("[%s]\n", pkgname); - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance(%s) is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("Instance(%s) is not created\n", id); - goto out; - } - - if (!common->request.pd_created) { - ErrPrint("PD create request is canceled\n"); - goto out; - } - - common->is_pd_created = (status == (int)LB_STATUS_SUCCESS); - common->request.pd_created = 0; - - if (common->is_pd_created) { - lb_set_pdsize(common, width, height); - if (lb_text_pd(common)) { - DbgPrint("Text TYPE does not need to handle this\n"); - } else { - (void)lb_set_pd_fb(common, buf_id); - - switch (common->pd.type) { - case _PD_TYPE_SCRIPT: - case _PD_TYPE_BUFFER: - switch (fb_type(lb_get_pd_fb(common))) { - case BUFFER_TYPE_FILE: - case BUFFER_TYPE_SHM: - lb_create_lock_file(common, 1); - break; - case BUFFER_TYPE_PIXMAP: - case BUFFER_TYPE_ERROR: - default: - break; - } - break; - case _PD_TYPE_TEXT: - default: - break; - } - - ret = lb_sync_pd_fb(common); - if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); - } - } - } - - DbgPrint("PERF_DBOX\n"); - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.pd_created.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.pd_created.cb; - cbdata = handler->cbs.pd_created.data; - - handler->cbs.pd_created.cb = NULL; - handler->cbs.pd_created.data = NULL; - - /*! - * Before call the Callback function, - * pd_create_cb must be reset. - * Because, in the create callback, user can call create_pd function again. - */ - cb(handler, status, cbdata); - } else if (status == (int)LB_STATUS_SUCCESS) { - lb_invoke_event_handler(handler, LB_EVENT_PD_CREATED); - } - } - -out: - return NULL; -} - -static struct packet *master_pd_destroyed(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct dlist *l; - struct livebox_common *common; - const char *pkgname; - const char *id; - int ret; - int status; - - ret = packet_get(packet, "ssi", &pkgname, &id, &status); - if (ret != 3) { - ErrPrint("Invalid argument\n"); - goto out; - } - - DbgPrint("[%s]\n", pkgname); - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance(%s) is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("Instance(%s) is not created\n", id); - goto out; - } - - if (common->is_pd_created == 0) { - ErrPrint("PD is not created, event is ignored\n"); - goto out; - } - - common->is_pd_created = 0; - common->request.pd_destroyed = 0; - - dlist_foreach(common->livebox_list, l, handler) { - if (handler->cbs.pd_destroyed.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.pd_destroyed.cb; - cbdata = handler->cbs.pd_destroyed.data; - - handler->cbs.pd_destroyed.cb = NULL; - handler->cbs.pd_destroyed.data = NULL; - - /*! - * Before call the Callback function, - * pd_destroyed_cb must be reset. - * Because, in the create callback, user can call destroy_pd function again. - */ - cb(handler, status, cbdata); - } else if (status == (int)LB_STATUS_SUCCESS) { - lb_invoke_event_handler(handler, LB_EVENT_PD_DESTROYED); - } - } - - /*! - * \note - * Lock file should be deleted after all callbacks are processed. - */ - switch (common->pd.type) { - case _PD_TYPE_SCRIPT: - case _PD_TYPE_BUFFER: - switch (fb_type(lb_get_pd_fb(common))) { - case BUFFER_TYPE_FILE: - case BUFFER_TYPE_SHM: - lb_destroy_lock_file(common, 1); - break; - case BUFFER_TYPE_PIXMAP: - case BUFFER_TYPE_ERROR: - default: - break; - } - break; - case _PD_TYPE_TEXT: - default: - break; - } - -out: - return NULL; -} - -static struct packet *master_pd_updated(pid_t pid, int handle, const struct packet *packet) -{ - const char *pkgname; - const char *id; - const char *descfile; - const char *fbfile; - int ret; - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - int pd_w; - int pd_h; - - ret = packet_get(packet, "ssssii", - &pkgname, &id, - &descfile, &fbfile, - &pd_w, &pd_h); - if (ret != 6) { - ErrPrint("Invalid argument\n"); - goto out; - } - - DbgPrint("[%s]\n", pkgname); - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Instance(%s) is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - /*! - * \note - * This handler is already deleted by the user. - * So don't try to notice anything about this anymore. - * Just ignore all events. - */ - ErrPrint("Instance(%s) is not created\n", id); - goto out; - } - - lb_set_pdsize(common, pd_w, pd_h); - - if (lb_text_pd(common)) { - (void)parse_desc(common, descfile, 1); - } else { - if (conf_frame_drop_for_resizing() && common->request.size_changed) { - /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */ - DbgPrint("Discards obsoloted update event\n"); - } else { - (void)lb_set_pd_fb(common, fbfile); - - if (!conf_manual_sync()) { - ret = lb_sync_pd_fb(common); - if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret); - } else { - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED); - } - } - } else { - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED); - } - } - } - } - -out: - return NULL; -} - -static struct packet *master_update_mode(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - struct dlist *n; - const char *pkgname; - const char *id; - int active_mode; - int status; - int ret; - - if (!packet) { - ErrPrint("Invalid packet\n"); - goto out; - } - - ret = packet_get(packet, "ssii", &pkgname, &id, &status, &active_mode); - if (ret != 4) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Livebox(%s) is not found\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("Livebox(%s) is not created yet\n", id); - goto out; - } - - if (status == (int)LB_STATUS_SUCCESS) { - lb_set_update_mode(common, active_mode); - } - - common->request.update_mode = 0; - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.update_mode.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.update_mode.cb; - cbdata = handler->cbs.update_mode.data; - - handler->cbs.update_mode.cb = NULL; - handler->cbs.update_mode.data = NULL; - - cb(handler, status, cbdata); - } else if (status == (int)LB_STATUS_SUCCESS) { - lb_invoke_event_handler(handler, LB_EVENT_UPDATE_MODE_CHANGED); - } - } - -out: - return NULL; -} - -static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - const char *pkgname; - const char *id; - const char *fbfile; - int status; - int ret; - int w; - int h; - int is_pd; - - if (!packet) { - ErrPrint("Invalid packet\n"); - goto out; - } - - ret = packet_get(packet, "sssiiii", &pkgname, &id, &fbfile, &is_pd, &w, &h, &status); - if (ret != 7) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Livebox(%s) is not found\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("Livebox(%s) is not created yet\n", id); - goto out; - } - - common->request.size_changed = 0; - if (is_pd) { - /*! - * \NOTE - * PD is not able to resized by the client. - * PD is only can be managed by the provider. - * So the PD has no private resized event handler. - * Notify it via global event handler only. - */ - if (status == (int)LB_STATUS_SUCCESS) { - struct dlist *l; - - lb_set_pdsize(common, w, h); - dlist_foreach(common->livebox_list, l, handler) { - lb_invoke_event_handler(handler, LB_EVENT_PD_SIZE_CHANGED); - } - } else { - ErrPrint("This is not possible. PD Size is changed but the return value is not ZERO (%d)\n", status); - } - } else { - struct dlist *l; - struct dlist *n; - - if (status == (int)LB_STATUS_SUCCESS) { - lb_set_size(common, w, h); - - /*! - * \NOTE - * If there is a created LB FB, - * Update it too. - */ - if (lb_get_lb_fb(common)) { - (void)lb_set_lb_fb(common, fbfile); - - ret = lb_sync_lb_fb(common); - if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); - } - - /* Just update the size info only. */ - } - } - - /*! - * \NOTE - * I cannot believe client. - * So I added some log before & after call the user callback. - */ - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.size_changed.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.size_changed.cb; - cbdata = handler->cbs.size_changed.data; - - handler->cbs.size_changed.cb = NULL; - handler->cbs.size_changed.data = NULL; - - cb(handler, status, cbdata); - } else if (status == (int)LB_STATUS_SUCCESS) { - lb_invoke_event_handler(handler, LB_EVENT_LB_SIZE_CHANGED); - } - } - } - -out: - return NULL; -} - -static struct packet *master_period_changed(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - struct dlist *n; - const char *pkgname; - const char *id; - int ret; - double period; - int status; - - ret = packet_get(packet, "idss", &status, &period, &pkgname, &id); - if (ret != 4) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Livebox(%s) is not found\n", id); - goto out; - } - - if (common->state != CREATE) { - ErrPrint("Livebox(%s) is not created\n", id); - goto out; - } - - if (status == (int)LB_STATUS_SUCCESS) { - lb_set_period(common, period); - } - - common->request.period_changed = 0; - - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.period_changed.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.period_changed.cb; - cbdata = handler->cbs.period_changed.data; - - handler->cbs.period_changed.cb = NULL; - handler->cbs.period_changed.data = NULL; - - cb(handler, status, cbdata); - } else if (status == (int)LB_STATUS_SUCCESS) { - lb_invoke_event_handler(handler, LB_EVENT_PERIOD_CHANGED); - } - } - -out: - return NULL; -} - -static struct packet *master_group_changed(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - struct dlist *n; - const char *pkgname; - const char *id; - int ret; - const char *cluster; - const char *category; - int status; - - ret = packet_get(packet, "ssiss", &pkgname, &id, &status, &cluster, &category); - if (ret != 5) { - ErrPrint("Invalid argument\n"); - goto out; - } - - common = lb_find_common_handle(pkgname, id); - if (!common) { - ErrPrint("Livebox(%s) is not exists\n", id); - goto out; - } - - if (common->state != CREATE) { - /*! - * \note - * Do no access this handler, - * You cannot believe this handler anymore. - */ - ErrPrint("Livebox(%s) is not created\n", id); - goto out; - } - - if (status == (int)LB_STATUS_SUCCESS) { - (void)lb_set_group(common, cluster, category); - } - - common->request.group_changed = 0; - - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.group_changed.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.group_changed.cb; - cbdata = handler->cbs.group_changed.data; - - handler->cbs.group_changed.cb = NULL; - handler->cbs.group_changed.data = NULL; - - cb(handler, status, cbdata); - } else if (status == (int)LB_STATUS_SUCCESS) { - lb_invoke_event_handler(handler, LB_EVENT_GROUP_CHANGED); - } - } - -out: - return NULL; -} - -static struct packet *master_created(pid_t pid, int handle, const struct packet *packet) -{ - struct livebox *handler; - struct livebox_common *common; - struct dlist *l; - - int lb_w; - int lb_h; - int pd_w; - int pd_h; - const char *pkgname; - const char *id; - - const char *content; - const char *cluster; - const char *category; - const char *lb_fname; - const char *pd_fname; - const char *title; - - double timestamp; - const char *auto_launch; - double priority; - int size_list; - int user; - int pinup_supported; - enum lb_type lb_type; - enum pd_type pd_type; - double period; - int is_pinned_up; - - int old_state = DESTROYED; - - int ret; - - ret = packet_get(packet, "dsssiiiisssssdiiiiidsi", - ×tamp, - &pkgname, &id, &content, - &lb_w, &lb_h, &pd_w, &pd_h, - &cluster, &category, &lb_fname, &pd_fname, - &auto_launch, &priority, &size_list, &user, &pinup_supported, - &lb_type, &pd_type, &period, &title, &is_pinned_up); - if (ret != 22) { - ErrPrint("Invalid argument\n"); - ret = LB_STATUS_ERROR_INVALID; - goto out; - } - - ErrPrint("[%lf] pkgname: %s, id: %s, content: %s, " - "pd_w: %d, pd_h: %d, lb_w: %d, lb_h: %d, " - "cluster: %s, category: %s, lb_fname: \"%s\", pd_fname: \"%s\", " - "auto_launch: %s, priority: %lf, size_list: %d, user: %d, pinup: %d, " - "lb_type: %d, pd_type: %d, period: %lf, title: [%s], is_pinned_up: %d\n", - timestamp, pkgname, id, content, - pd_w, pd_h, lb_w, lb_h, - cluster, category, lb_fname, pd_fname, - auto_launch, priority, size_list, user, pinup_supported, - lb_type, pd_type, period, title, is_pinned_up); - - common = lb_find_common_handle_by_timestamp(timestamp); - if (!common) { - handler = lb_new_livebox(pkgname, id, timestamp, cluster, category); - if (!handler) { - ErrPrint("Failed to create a new livebox\n"); - ret = LB_STATUS_ERROR_FAULT; - goto out; - } - common = handler->common; - old_state = common->state; - } else { - if (common->state != CREATE) { - if (common->state != DELETE) { - /*! - * \note - * This is not possible!!! - */ - ErrPrint("Invalid handler\n"); - ret = LB_STATUS_ERROR_INVALID; - goto out; - } - - /*! - * \note - * After get the delete states, - * call the create callback with deleted result. - */ - } - - old_state = common->state; - - if (common->id) { - ErrPrint("Already created: timestamp[%lf] " - "pkgname[%s], id[%s] content[%s] " - "cluster[%s] category[%s] lb_fname[%s] pd_fname[%s]\n", - timestamp, pkgname, id, - content, cluster, category, - lb_fname, pd_fname); - - ret = LB_STATUS_ERROR_ALREADY; - goto out; - } - - lb_set_id(common, id); - } - - common->request.created = 0; - lb_set_size(common, lb_w, lb_h); - common->lb.type = lb_type; - common->is_pinned_up = is_pinned_up; - - switch (lb_type) { - case _LB_TYPE_FILE: - break; - case _LB_TYPE_SCRIPT: - case _LB_TYPE_BUFFER: - if (!strlen(lb_fname)) { - break; - } - (void)lb_set_lb_fb(common, lb_fname); - - /*! - * \note - * Livebox should create the lock file from here. - * Even if the old_state == DELETE, - * the lock file will be deleted from deleted event callback. - */ - switch (fb_type(lb_get_lb_fb(common))) { - case BUFFER_TYPE_FILE: - case BUFFER_TYPE_SHM: - lb_create_lock_file(common, 0); - break; - case BUFFER_TYPE_PIXMAP: - case BUFFER_TYPE_ERROR: - default: - break; - } - - ret = lb_sync_lb_fb(common); - if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); - } - break; - case _LB_TYPE_TEXT: - lb_set_text_lb(common); - break; - default: - break; - } - - common->pd.type = pd_type; - lb_set_pdsize(common, pd_w, pd_h); - lb_set_default_pdsize(common, pd_w, pd_h); - switch (pd_type) { - case _PD_TYPE_SCRIPT: - case _PD_TYPE_BUFFER: - if (!strlen(pd_fname)) { - break; - } - - lb_set_pd_fb(common, pd_fname); - - ret = lb_sync_pd_fb(common); - if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); - } - - /*! - * \brief - * PD doesn't need to create the lock file from here. - * Just create it from PD_CREATED event. - */ - - break; - case _PD_TYPE_TEXT: - lb_set_text_pd(common); - break; - default: - break; - } - - lb_set_priority(common, priority); - - lb_set_size_list(common, size_list); - lb_set_group(common, cluster, category); - - lb_set_content(common, content); - lb_set_title(common, title); - - lb_set_user(common, user); - - lb_set_auto_launch(common, auto_launch); - lb_set_pinup(common, pinup_supported); - - lb_set_period(common, period); - - ret = 0; - - if (common->state == CREATE) { - dlist_foreach(common->livebox_list, l, handler) { - /*! - * \note - * These callback can change the handler->state. - * So we have to use the "old_state" which stored state before call these callbacks - */ - - if (handler->cbs.created.cb) { - ret_cb_t cb; - void *cbdata; - - cb = handler->cbs.created.cb; - cbdata = handler->cbs.created.data; - - handler->cbs.created.cb = NULL; - handler->cbs.created.data = NULL; - - cb(handler, ret, cbdata); - } else { - lb_invoke_event_handler(handler, LB_EVENT_CREATED); - } - } - } - -out: - if (ret == 0 && old_state == DELETE) { - struct dlist *n; - - DbgPrint("Take place an unexpected case [%d]\n", common->refcnt); - dlist_foreach_safe(common->livebox_list, l, n, handler) { - if (handler->cbs.created.cb) { - if (!handler->common->request.deleted) { - if (lb_send_delete(handler, common->delete_type, handler->cbs.created.cb, handler->cbs.created.data) < 0) { - /*! - * \note - * Already sent or something else happens. - * Callback will be called in any cases - */ - } - } else if (handler->state != DELETE) { - handler->cbs.created.cb(handler, LB_STATUS_ERROR_CANCEL, handler->cbs.created.data); - lb_unref(handler, 1); - } - } else { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } - } - - /*! - * \note - * handler->cbs.created.cb = NULL; - * handler->cbs.created.data = NULL; - * - * Do not clear this to use this from the deleted event callback. - * if this value is not cleared when the deleted event callback check it, - * it means that the created function is not called yet. - * Then the call the deleted event callback with LB_STATUS_ERROR_CANCEL errno. - */ - } - - return NULL; -} - -static struct method s_table[] = { - { - .cmd = "lb_updated", /* pkgname, id, lb_w, lb_h, priority, ret */ - .handler = master_lb_updated, - }, - { - .cmd = "pd_updated", /* pkgname, id, descfile, pd_w, pd_h, ret */ - .handler = master_pd_updated, - }, - { - .cmd = "pd_created", - .handler = master_pd_created, - }, - { - .cmd = "pd_destroyed", - .handler = master_pd_destroyed, - }, - { - .cmd = "fault_package", /* pkgname, id, function, ret */ - .handler = master_fault_package, - }, - { - .cmd = "deleted", /* pkgname, id, timestamp, ret */ - .handler = master_deleted, - }, - { - .cmd = "created", /* timestamp, pkgname, id, content, lb_w, lb_h, pd_w, pd_h, cluster, category, lb_file, pd_file, auto_launch, priority, size_list, is_user, pinup_supported, text_lb, text_pd, period, ret */ - .handler = master_created, - }, - { - .cmd = "group_changed", - .handler = master_group_changed, - }, - { - .cmd = "period_changed", - .handler = master_period_changed, - }, - { - .cmd = "size_changed", - .handler = master_size_changed, - }, - { - .cmd = "pinup", - .handler = master_pinup, - }, - { - .cmd = "scroll", - .handler = master_hold_scroll, - }, - - { - .cmd = "update_mode", - .handler = master_update_mode, - }, - - { - .cmd = "lb_update_begin", - .handler = master_lb_update_begin, - }, - { - .cmd = "lb_update_end", - .handler = master_lb_update_end, - }, - - { - .cmd = "pd_update_begin", - .handler = master_pd_update_begin, - }, - { - .cmd = "pd_update_end", - .handler = master_pd_update_end, - }, - - { - .cmd = "access_status", - .handler = master_access_status, - }, - { - .cmd = "key_status", - .handler = master_key_status, - }, - { - .cmd = "close_pd", - .handler = master_request_close_pd, - }, - - { - .cmd = NULL, - .handler = NULL, - }, -}; - -static void acquire_cb(struct livebox *handler, const struct packet *result, void *data) -{ - if (!result) { - DbgPrint("Result packet is not valid\n"); - } else { - int ret; - - if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid argument\n"); - } else { - DbgPrint("Acquire returns: %d\n", ret); - } - } - - return; -} - -static inline int make_connection(void) -{ - struct packet *packet; - int ret; - - DbgPrint("Let's making connection!\n"); - - s_info.fd = com_core_packet_client_init(client_addr(), 0, s_table); - if (s_info.fd < 0) { - ErrPrint("Try this again later\n"); - return LB_STATUS_ERROR_IO; - } - - packet = packet_create("acquire", "d", util_timestamp()); - if (!packet) { - com_core_packet_client_fini(s_info.fd); - s_info.fd = -1; - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(NULL, packet, 1, acquire_cb, NULL); - if (ret < 0) { - ErrPrint("Master RPC returns %d\n", ret); - com_core_packet_client_fini(s_info.fd); - s_info.fd = -1; - return LB_STATUS_ERROR_IO; - } - - return LB_STATUS_SUCCESS; -} - -static int connected_cb(int handle, void *data) -{ - master_rpc_check_and_fire_consumer(); - return 0; -} - -static void master_started_cb(keynode_t *node, void *data) -{ - int state = 0; - - if (vconf_get_bool(VCONFKEY_MASTER_STARTED, &state) < 0) { - ErrPrint("Unable to get [%s]\n", VCONFKEY_MASTER_STARTED); - } - - DbgPrint("Master state: %d\n", state); - if (state == 1 && make_connection() == (int)LB_STATUS_SUCCESS) { - int ret; - ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb); - if (ret < 0) { - DbgPrint("master_started vconf key de-registered [%d]\n", ret); - } - } -} - -static gboolean timeout_cb(gpointer data) -{ - if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) { - ErrPrint("Failed to add vconf for monitoring service state\n"); - } else { - DbgPrint("vconf event callback is registered\n"); - } - - master_started_cb(NULL, NULL); - - s_info.timer_id = 0; - return FALSE; -} - -static int disconnected_cb(int handle, void *data) -{ - if (s_info.fd != handle) { - /*!< This handle is not my favor */ - return 0; - } - - s_info.fd = -1; /*!< Disconnected */ - - master_rpc_clear_all_request(); - lb_invoke_fault_handler(LB_FAULT_PROVIDER_DISCONNECTED, MASTER_PKGNAME, "default", "disconnected"); - - lb_delete_all(); - - /* Try to reconnect after 1 sec later */ - if (!s_info.timer_id) { - DbgPrint("Reconnecting timer is added\n"); - s_info.timer_id = g_timeout_add(1000, timeout_cb, NULL); - if (s_info.timer_id == 0) { - ErrPrint("Unable to add reconnecting timer\n"); - return 0; - } - } else { - ErrPrint("Reconnecting timer is already exists\n"); - } - - return 0; -} - -int client_init(int use_thread) -{ - com_core_packet_use_thread(use_thread); - - s_info.client_addr = vconf_get_str(VCONFKEY_MASTER_CLIENT_ADDR); - if (!s_info.client_addr) { - s_info.client_addr = strdup(CLIENT_SOCKET); - if (!s_info.client_addr) { - ErrPrint("Heap: %s\n", strerror(errno)); - return -ENOMEM; - } - } - - (void)file_service_init(); - - DbgPrint("Server Address: %s\n", s_info.client_addr); - - com_core_add_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL); - com_core_add_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL); - if (vconf_notify_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb, NULL) < 0) { - ErrPrint("Failed to add vconf for service state\n"); - } else { - DbgPrint("vconf event callback is registered\n"); - } - - master_started_cb(NULL, NULL); - return 0; -} - -int client_fd(void) -{ - return s_info.fd; -} - -const char *client_addr(void) -{ - return s_info.client_addr; -} - -int client_fini(void) -{ - int ret; - - (void)file_service_fini(); - - ret = vconf_ignore_key_changed(VCONFKEY_MASTER_STARTED, master_started_cb); - if (ret < 0) { - DbgPrint("Ignore vconf key: %d\n", ret); - } - - com_core_del_event_callback(CONNECTOR_DISCONNECTED, disconnected_cb, NULL); - com_core_del_event_callback(CONNECTOR_CONNECTED, connected_cb, NULL); - com_core_packet_client_fini(s_info.fd); - s_info.fd = -1; - free(s_info.client_addr); - s_info.client_addr = NULL; - return LB_STATUS_SUCCESS; -} - -/* End of a file */ diff --git a/src/conf.c b/src/conf.c deleted file mode 100644 index 1c1f898..0000000 --- a/src/conf.c +++ /dev/null @@ -1,57 +0,0 @@ -#include - -static struct info { - int manual_sync; - int frame_drop_for_resizing; - int shared_content; - - double event_filter; -} s_info = { - .manual_sync = 0, - .frame_drop_for_resizing = 1, - .shared_content = 0, - - .event_filter = 0.01f, -}; - -void conf_set_manual_sync(int flag) -{ - s_info.manual_sync = flag; -} - -int conf_manual_sync(void) -{ - return s_info.manual_sync; -} - -void conf_set_frame_drop_for_resizing(int flag) -{ - s_info.frame_drop_for_resizing = flag; -} - -int conf_frame_drop_for_resizing(void) -{ - return s_info.frame_drop_for_resizing; -} - -void conf_set_shared_content(int flag) -{ - s_info.shared_content = flag; -} - -int conf_shared_content(void) -{ - return s_info.shared_content; -} - -double conf_event_filter(void) -{ - return s_info.event_filter; -} - -void conf_set_event_filter(double filter) -{ - s_info.event_filter = filter; -} - -/* End of a file */ diff --git a/src/desc_parser.c b/src/desc_parser.c deleted file mode 100644 index ac056ac..0000000 --- a/src/desc_parser.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * 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 -#include -#include /* malloc */ -#include /* strdup */ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "debug.h" -#include "livebox.h" -#include "livebox_internal.h" -#include "desc_parser.h" -#include "dlist.h" -#include "util.h" - -#define INFO_SIZE "size" -#define INFO_CATEGORY "category" - -static const char *type_list[] = { - "access", - "access,operation", - "color", - "drag", - "image", - "info", - "script", - "signal", - "text", - NULL -}; - -static const char *field_list[] = { - "type", - "part", - "data", - "option", - "id", - "target", - "file", - NULL -}; - -enum block_type { - TYPE_ACCESS, - TYPE_ACCESS_OP, - TYPE_COLOR, - TYPE_DRAG, - TYPE_IMAGE, - TYPE_INFO, - TYPE_SCRIPT, - TYPE_SIGNAL, - TYPE_TEXT, - TYPE_MAX -}; - -enum field_type { - FIELD_TYPE, - FIELD_PART, - FIELD_DATA, - FIELD_OPTION, - FIELD_ID, - FIELD_TARGET, - FIELD_FILE -}; - -struct block { - enum block_type type; - char *part; - char *data; - char *option; - char *id; - char *target; - char *file; - - /* Should be released */ - char *filebuf; - const char *filename; -}; - -static int update_text(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block || !block->part || !block->data) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_text) { - ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data); - } - - return 0; -} - -static int update_image(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block || !block->part) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_image) { - ops->update_image(handle, block->id, block->part, block->data, block->option); - } - - return 0; -} - -static int update_script(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block || !block->part) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_script) { - ops->update_script(handle, block->id, block->target, block->part, block->data, block->option); - } - - return 0; -} - -static int update_signal(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_signal) { - ops->update_signal(handle, block->id, block->data, block->part); - } - - return 0; -} - -static int update_drag(struct livebox *handle, struct block *block, int is_pd) -{ - double dx, dy; - struct livebox_script_operators *ops; - - if (!block || !block->data || !block->part) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) { - ErrPrint("Invalid format of data\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_drag) { - ops->update_drag(handle, block->id, block->part, dx, dy); - } - - return 0; -} - -static int update_info(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block || !block->part || !block->data) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (!strcasecmp(block->part, INFO_SIZE)) { - int w, h; - - if (sscanf(block->data, "%dx%d", &w, &h) != 2) { - ErrPrint("Invalid format (%s)\n", block->data); - return LB_STATUS_ERROR_INVALID; - } - - if (ops->update_info_size) { - ops->update_info_size(handle, block->id, w, h); - } - } else if (!strcasecmp(block->part, INFO_CATEGORY)) { - if (ops->update_info_category) { - ops->update_info_category(handle, block->id, block->data); - } - } - - return 0; -} - -static int update_access(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_access) { - ops->update_access(handle, block->id, block->part, block->data, block->option); - } - - return 0; -} - -static int operate_access(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->operate_access) { - ops->operate_access(handle, block->id, block->part, block->data, block->option); - } - - return 0; -} - -static int update_color(struct livebox *handle, struct block *block, int is_pd) -{ - struct livebox_script_operators *ops; - - if (!block) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_color) { - ops->update_color(handle, block->id, block->part, block->data); - } - - return 0; -} - -static inline int update_begin(struct livebox *handle, int is_pd) -{ - struct livebox_script_operators *ops; - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_begin) { - ops->update_begin(handle); - } - - return 0; -} - -static inline int update_end(struct livebox *handle, int is_pd) -{ - struct livebox_script_operators *ops; - - ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops; - if (ops->update_end) { - ops->update_end(handle); - } - - return 0; -} - -static inline void delete_block(struct block *block) -{ - free(block->filebuf); - free(block); -} - -static inline void consuming_parsed_block(struct livebox *handle, int is_pd, struct block *block) -{ - typedef int (*update_function_t)(struct livebox *handle, struct block *block, int is_pd); - static update_function_t updators[] = { - update_access, - operate_access, - update_color, - update_drag, - update_image, - update_info, - update_script, - update_signal, - update_text, - NULL - }; - - if (block->type >= 0 || block->type < TYPE_MAX) { - (void)updators[block->type](handle, block, is_pd); - } else { - ErrPrint("Block type[%d] is not valid\n", block->type); - } -} - -static inline char *load_file(const char *filename) -{ - char *filebuf = NULL; - int fd; - off_t filesize; - int ret; - size_t readsize = 0; - - fd = open(filename, O_RDONLY); - if (fd < 0) { - ErrPrint("open: %s\n", strerror(errno)); - return NULL; - } - - filesize = lseek(fd, 0L, SEEK_END); - if (filesize == (off_t)-1) { - ErrPrint("lseek: %s\n", strerror(errno)); - goto errout; - } - - if (lseek(fd, 0L, SEEK_SET) < 0) { - ErrPrint("lseek: %s\n", strerror(errno)); - goto errout; - } - - filebuf = malloc(filesize + 1); - if (!filebuf) { - ErrPrint("malloc: %s\n", strerror(errno)); - goto errout; - } - - while (readsize < filesize) { - ret = read(fd, filebuf + readsize, (size_t)filesize - readsize); - if (ret < 0) { - if (errno == EINTR) { - DbgPrint("Read is interrupted\n"); - continue; - } - - ErrPrint("read: %s\n", strerror(errno)); - free(filebuf); - filebuf = NULL; - break; - } - - readsize += ret; - } - - if (filebuf) { - filebuf[readsize] = '\0'; - } - - /*! - * \note - * Now, we are ready to parse the filebuf. - */ - -errout: - if (close(fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - - return filebuf; -} - -int parse_desc(struct livebox_common *common, const char *filename, int is_pd) -{ - int type_idx = 0; - int type_len = 0; - int field_idx = 0; - int field_len = 0; - char *filebuf; - char *fileptr; - char *ptr = NULL; - struct block *block = NULL; - struct dlist *block_list = NULL; - struct dlist *l; - struct dlist *n; - struct dlist *handle_iterator; - struct livebox *handler; - enum state { - BEGIN, - FIELD, - DATA, - END, - DONE, - ERROR, - } state; - - filebuf = load_file(filename); - if (!filebuf) { - return LB_STATUS_ERROR_IO; - } - - fileptr = filebuf; - - state = BEGIN; - while (*fileptr && state != ERROR) { - switch (state) { - case BEGIN: - if (*fileptr == '{') { - block = calloc(1, sizeof(*block)); - if (!block) { - ErrPrint("calloc: %s\n", strerror(errno)); - state = ERROR; - continue; - } - state = FIELD; - ptr = NULL; - } - break; - case FIELD: - if (isspace(*fileptr)) { - if (ptr != NULL) { - *fileptr = '\0'; - } - } else if (*fileptr == '=') { - *fileptr = '\0'; - ptr = NULL; - state = DATA; - } else if (ptr == NULL) { - ptr = fileptr; - field_idx = 0; - field_len = 0; - - while (field_list[field_idx]) { - if (field_list[field_idx][field_len] == *fileptr) { - break; - } - field_idx++; - } - - if (!field_list[field_idx]) { - ErrPrint("Invalid field\n"); - state = ERROR; - continue; - } - - field_len++; - } else { - if (field_list[field_idx][field_len] != *fileptr) { - field_idx++; - while (field_list[field_idx]) { - if (!strncmp(field_list[field_idx], fileptr - field_len, field_len)) { - break; - } else { - field_idx++; - } - } - - if (!field_list[field_idx]) { - state = ERROR; - ErrPrint("field is not valid\n"); - continue; - } - } - - field_len++; - } - break; - case DATA: - switch (field_idx) { - case FIELD_TYPE: - if (ptr == NULL) { - if (isspace(*fileptr)) { - break; - } - - if (*fileptr == '\0') { - state = ERROR; - ErrPrint("Type is not valid\n"); - continue; - } - - ptr = fileptr; - type_idx = 0; - type_len = 0; - } - - if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { - *fileptr = '\0'; - } - - if (type_list[type_idx][type_len] != *fileptr) { - type_idx++; - while (type_list[type_idx]) { - if (!strncmp(type_list[type_idx], fileptr - type_len, type_len)) { - break; - } else { - type_idx++; - } - } - - if (!type_list[type_idx]) { - state = ERROR; - ErrPrint("type is not valid (%s)\n", fileptr - type_len); - continue; - } - } - - if (!*fileptr) { - block->type = type_idx; - state = DONE; - ptr = NULL; - } - - type_len++; - break; - case FIELD_PART: - if (ptr == NULL) { - ptr = fileptr; - } - - if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { - *fileptr = '\0'; - } - - if (!*fileptr) { - block->part = ptr; - state = DONE; - ptr = NULL; - } - break; - case FIELD_DATA: - if (ptr == NULL) { - ptr = fileptr; - } - - if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { - *fileptr = '\0'; - } - - if (!*fileptr) { - block->data = ptr; - state = DONE; - ptr = NULL; - } - break; - case FIELD_OPTION: - if (ptr == NULL) { - ptr = fileptr; - } - - if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { - *fileptr = '\0'; - } - - if (!*fileptr) { - block->option = ptr; - state = DONE; - ptr = NULL; - } - break; - case FIELD_ID: - if (ptr == NULL) { - ptr = fileptr; - } - - if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { - *fileptr = '\0'; - } - - if (!*fileptr) { - block->id = ptr; - state = DONE; - ptr = NULL; - } - break; - case FIELD_TARGET: - if (ptr == NULL) { - ptr = fileptr; - } - - if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { - *fileptr = '\0'; - } - - if (!*fileptr) { - block->target = ptr; - state = DONE; - ptr = NULL; - } - break; - case FIELD_FILE: - if (ptr == NULL) { - ptr = fileptr; - } - - if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) { - *fileptr = '\0'; - } - - if (!*fileptr) { - block->target = ptr; - state = DONE; - ptr = NULL; - } - default: - break; - } - - break; - case DONE: - if (isspace(*fileptr)) { - } else if (*fileptr == '}') { - state = BEGIN; - block->filename = filename; - block_list = dlist_append(block_list, block); - block = NULL; - } else { - state = FIELD; - continue; - } - break; - case END: - default: - break; - } - - fileptr++; - } - - if (state != BEGIN) { - struct dlist *l; - struct dlist *n; - ErrPrint("State %d\n", state); - - free(filebuf); - free(block); - - dlist_foreach_safe(block_list, l, n, block) { - free(block); - block_list = dlist_remove(block_list, l); - } - - return LB_STATUS_ERROR_FAULT; - } - - - block = dlist_data(dlist_prev(block_list)); - if (block) { - block->filebuf = filebuf; - } else { - ErrPrint("Last block is not exists (There is no parsed block)\n"); - free(filebuf); - } - - ErrPrint("Begin: Set content for object\n"); - dlist_foreach(common->livebox_list, l, handler) { - update_begin(handler, is_pd); - } - - dlist_foreach_safe(block_list, l, n, block) { - dlist_foreach(common->livebox_list, handle_iterator, handler) { - consuming_parsed_block(handler, is_pd, block); - } - - block_list = dlist_remove(block_list, l); - delete_block(block); - } - - dlist_foreach(common->livebox_list, l, handler) { - update_end(handler, is_pd); - } - ErrPrint("End: Set content for object\n"); - - return LB_STATUS_SUCCESS; -} - -/* End of a file */ diff --git a/src/dlist.c b/src/dlist.c deleted file mode 100644 index 3ae571b..0000000 --- a/src/dlist.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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 -#include -#include - -#include "dlist.h" - -/*! - * \brief - * This dlist is called Modified Doubly Linked List. - * - * Noramlly, The dobule linked list contains address of previous and next element. - * This dlist also contains them, but the tail element only contains prev address. - * - * The head element's prev pointer indicates the last element. - * But the last element's next pointer indicates NIL. - * - * So we can find the last element while crawling this DList - * But we have to remember the address of the head element. - */ - -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; - } - - item->data = data; - - if (!list) { - item->prev = item; - item->next = NULL; - } else { - if (list->prev->next) { - list->prev->next = item; - } - - item->prev = list->prev; - item->next = list; - - list->prev = item; - - } - - return item; -} - -struct dlist *dlist_remove(struct dlist *list, struct dlist *l) -{ - if (!list || !l) { - return NULL; - } - - if (l == list) { - list = l->next; - } else { - l->prev->next = l->next; - } - - if (l->next) { - l->next->prev = l->prev; - } - /*! - * \note - * If the removed entry 'l' has no next element, it is the last element. - * In this case, check the existence of the list first, - * and if the list is not empty, update the 'prev' of the list (which is a head element of the list) - * - * If we didn't care about this, the head element(list) can indicates the invalid element. - */ - else if (list) { - list->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; - - i = 0; - for (n = l; n; n = n->next) { - if (i == nth) { - return n; - } - i++; - } - - return NULL; -} - -/* End of a file */ diff --git a/src/fb.c b/src/fb.c deleted file mode 100644 index 0e90ad1..0000000 --- a/src/fb.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include /* For error code */ - -#include "debug.h" -#include "util.h" -#include "fb.h" - -int errno; - -struct fb_info { - char *id; - int w; - int h; - int bufsz; - void *buffer; - - int pixels; - int handle; -}; - -struct buffer { /*!< Must has to be sync with slave & provider */ - enum { - CREATED = 0x00beef00, - DESTROYED = 0x00dead00 - } state; - enum buffer_type type; - int refcnt; - void *info; - char data[]; -}; - -static struct { - Display *disp; - int screen; - Visual *visual; - int disp_is_opened; -} s_info = { - .disp = NULL, - .disp_is_opened = 0, - .screen = -1, - .visual = NULL, -}; - -int fb_init(void *disp) -{ - s_info.disp = disp; - if (s_info.disp) { - Screen *screen; - - screen = DefaultScreenOfDisplay(s_info.disp); - - s_info.screen = DefaultScreen(s_info.disp); - s_info.visual = DefaultVisualOfScreen(screen); - } - - return 0; -} - -int fb_fini(void) -{ - if (s_info.disp_is_opened && s_info.disp) { - XCloseDisplay(s_info.disp); - } - - s_info.disp = NULL; - s_info.disp_is_opened = 0; - s_info.visual = NULL; - s_info.screen = -1; - return 0; -} - -static inline void update_fb_size(struct fb_info *info) -{ - info->bufsz = info->w * info->h * info->pixels; -} - -static inline int sync_for_file(struct fb_info *info) -{ - int fd; - struct buffer *buffer; - - buffer = info->buffer; - - if (!buffer) { /* Ignore this sync request */ - return LB_STATUS_SUCCESS; - } - - if (buffer->state != CREATED) { - ErrPrint("Invalid state of a FB\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (buffer->type != BUFFER_TYPE_FILE) { - ErrPrint("Invalid buffer\n"); - return LB_STATUS_SUCCESS; - } - - fd = open(util_uri_to_path(info->id), O_RDONLY); - if (fd < 0) { - ErrPrint("Failed to open a file (%s) because of (%s)\n", - util_uri_to_path(info->id), strerror(errno)); - - /*! - * \note - * But return ZERO, even if we couldn't get a buffer file, - * the viewer can draw empty screen. - * - * and then update it after it gots update events - */ - return LB_STATUS_SUCCESS; - } - - if (read(fd, buffer->data, info->bufsz) != info->bufsz) { - ErrPrint("read: %s\n", strerror(errno)); - if (close(fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - - /*! - * \note - * But return ZERO, even if we couldn't get a buffer file, - * the viewer can draw empty screen. - * - * and then update it after it gots update events - */ - return LB_STATUS_SUCCESS; - } - - if (close(fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - return LB_STATUS_SUCCESS; -} - -static inline __attribute__((always_inline)) int sync_for_pixmap(struct fb_info *info) -{ - struct buffer *buffer; - XShmSegmentInfo si; - XImage *xim; - - buffer = info->buffer; - if (!buffer) { /*!< Ignore this sync request */ - return LB_STATUS_SUCCESS; - } - - if (buffer->state != CREATED) { - ErrPrint("Invalid state of a FB\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (buffer->type != BUFFER_TYPE_PIXMAP) { - ErrPrint("Invalid buffer\n"); - return LB_STATUS_SUCCESS; - } - - if (!s_info.disp) { - s_info.disp = XOpenDisplay(NULL); - if (s_info.disp) { - Screen *screen; - - s_info.disp_is_opened = 1; - - screen = DefaultScreenOfDisplay(s_info.disp); - - s_info.screen = DefaultScreen(s_info.disp); - s_info.visual = DefaultVisualOfScreen(screen); - } else { - ErrPrint("Failed to open a display\n"); - return LB_STATUS_ERROR_FAULT; - } - } - - if (info->handle == 0) { - ErrPrint("Pixmap ID is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (info->bufsz == 0) { - /*! - * If the client does not acquire the buffer, - * This function will do nothing. - * It will work only if the buffer is acquired. - * To sync its contents. - */ - DbgPrint("Nothing can be sync\n"); - return LB_STATUS_SUCCESS; - } - - si.shmid = shmget(IPC_PRIVATE, info->bufsz, IPC_CREAT | 0666); - if (si.shmid < 0) { - ErrPrint("shmget: %s\n", strerror(errno)); - return LB_STATUS_ERROR_FAULT; - } - - si.readOnly = False; - si.shmaddr = shmat(si.shmid, NULL, 0); - if (si.shmaddr == (void *)-1) { - if (shmctl(si.shmid, IPC_RMID, 0) < 0) { - ErrPrint("shmctl: %s\n", strerror(errno)); - } - - return LB_STATUS_ERROR_FAULT; - } - - /*! - * \NOTE - * Use the 24 bits Pixmap for Video player - */ - xim = XShmCreateImage(s_info.disp, s_info.visual, - (info->pixels << 3), ZPixmap, NULL, - &si, - info->w, info->h); - if (xim == NULL) { - if (shmdt(si.shmaddr) < 0) { - ErrPrint("shmdt: %s\n", strerror(errno)); - } - - if (shmctl(si.shmid, IPC_RMID, 0) < 0) { - ErrPrint("shmctl: %s\n", strerror(errno)); - } - - return LB_STATUS_ERROR_FAULT; - } - - xim->data = si.shmaddr; - XShmAttach(s_info.disp, &si); - - XShmGetImage(s_info.disp, info->handle, xim, 0, 0, 0xFFFFFFFF); - XSync(s_info.disp, False); - - memcpy(buffer->data, xim->data, info->bufsz); - - XShmDetach(s_info.disp, &si); - XDestroyImage(xim); - - if (shmdt(si.shmaddr) < 0) { - ErrPrint("shmdt: %s\n", strerror(errno)); - } - - if (shmctl(si.shmid, IPC_RMID, 0) < 0) { - ErrPrint("shmctl: %s\n", strerror(errno)); - } - - return LB_STATUS_SUCCESS; -} - -int fb_sync(struct fb_info *info) -{ - if (!info) { - ErrPrint("FB Handle is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!info->id || info->id[0] == '\0') { - DbgPrint("Ingore sync\n"); - return LB_STATUS_SUCCESS; - } - - if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { - return sync_for_file(info); - } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - return sync_for_pixmap(info); - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { - /* No need to do sync */ - return LB_STATUS_SUCCESS; - } - - return LB_STATUS_ERROR_INVALID; -} - -struct fb_info *fb_create(const char *id, int w, int h) -{ - struct fb_info *info; - - if (!id || id[0] == '\0') { - ErrPrint("Invalid ID\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->pixels = sizeof(int); /* Use the default pixels(depth) */ - - if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) { - DbgPrint("SHMID: %d is gotten\n", info->handle); - } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) { - DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels); - } else { - info->handle = LB_STATUS_ERROR_INVALID; - } - - info->bufsz = 0; - info->buffer = NULL; - info->w = w; - info->h = h; - - return info; -} - -int fb_destroy(struct fb_info *info) -{ - if (!info) { - ErrPrint("Handle is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (info->buffer) { - struct buffer *buffer; - buffer = info->buffer; - - buffer->info = NULL; - } - - free(info->id); - free(info); - return LB_STATUS_SUCCESS; -} - -int fb_is_created(struct fb_info *info) -{ - if (!info) { - ErrPrint("Handle is not valid\n"); - return 0; - } - - if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) { - return 1; - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) { - return 1; - } else { - const char *path; - path = util_uri_to_path(info->id); - if (path && access(path, F_OK | R_OK) == 0) { - return 1; - } else { - ErrPrint("access: %s (%s)\n", strerror(errno), path); - } - } - - return 0; -} - -void *fb_acquire_buffer(struct fb_info *info) -{ - struct buffer *buffer; - - if (!info) { - ErrPrint("info == NIL\n"); - return NULL; - } - - if (!info->buffer) { - if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - update_fb_size(info); - - buffer = calloc(1, sizeof(*buffer) + info->bufsz); - if (!buffer) { - ErrPrint("Heap: %s\n", strerror(errno)); - info->bufsz = 0; - return NULL; - } - - buffer->type = BUFFER_TYPE_PIXMAP; - buffer->refcnt = 0; - buffer->state = CREATED; - buffer->info = info; - info->buffer = buffer; - - /*! - * \note - * Just update from here. - */ - sync_for_pixmap(info); - } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { - update_fb_size(info); - - buffer = calloc(1, sizeof(*buffer) + info->bufsz); - if (!buffer) { - ErrPrint("Heap: %s\n", strerror(errno)); - info->bufsz = 0; - return NULL; - } - - buffer->type = BUFFER_TYPE_FILE; - buffer->refcnt = 0; - buffer->state = CREATED; - buffer->info = info; - info->buffer = buffer; - - sync_for_file(info); - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { - buffer = shmat(info->handle, NULL, 0); - if (buffer == (void *)-1) { - ErrPrint("shmat: %s (%d)\n", strerror(errno), info->handle); - return NULL; - } - - return buffer->data; - } else { - ErrPrint("Buffer is not created (%s)\n", info->id); - return NULL; - } - } - - buffer = info->buffer; - - switch (buffer->type) { - case BUFFER_TYPE_PIXMAP: - buffer->refcnt++; - break; - case BUFFER_TYPE_FILE: - buffer->refcnt++; - break; - default: - DbgPrint("Unknwon FP: %d\n", buffer->type); - break; - } - - return buffer->data; -} - -int fb_release_buffer(void *data) -{ - struct buffer *buffer; - - if (!data) { - ErrPrint("buffer data == NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - buffer = container_of(data, struct buffer, data); - - if (buffer->state != CREATED) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - switch (buffer->type) { - case BUFFER_TYPE_SHM: - if (shmdt(buffer) < 0) { - ErrPrint("shmdt: %s\n", strerror(errno)); - } - break; - case BUFFER_TYPE_PIXMAP: - buffer->refcnt--; - if (buffer->refcnt == 0) { - struct fb_info *info; - info = buffer->info; - - buffer->state = DESTROYED; - free(buffer); - - if (info && info->buffer == buffer) { - info->buffer = NULL; - } - } - break; - case BUFFER_TYPE_FILE: - buffer->refcnt--; - if (buffer->refcnt == 0) { - struct fb_info *info; - info = buffer->info; - - buffer->state = DESTROYED; - free(buffer); - - if (info && info->buffer == buffer) { - info->buffer = NULL; - } - } - break; - default: - ErrPrint("Unknwon buffer type\n"); - break; - } - - return LB_STATUS_SUCCESS; -} - -int fb_refcnt(void *data) -{ - struct buffer *buffer; - struct shmid_ds buf; - int ret; - - if (!data) { - return LB_STATUS_ERROR_INVALID; - } - - buffer = container_of(data, struct buffer, data); - - if (buffer->state != CREATED) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - switch (buffer->type) { - case BUFFER_TYPE_SHM: - if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) { - ErrPrint("Error: %s\n", strerror(errno)); - return LB_STATUS_ERROR_FAULT; - } - - ret = buf.shm_nattch; - break; - case BUFFER_TYPE_PIXMAP: - ret = buffer->refcnt; - break; - case BUFFER_TYPE_FILE: - ret = buffer->refcnt; - break; - default: - ret = LB_STATUS_ERROR_INVALID; - break; - } - - return ret; -} - -const char *fb_id(struct fb_info *info) -{ - return info ? info->id : NULL; -} - -int fb_get_size(struct fb_info *info, int *w, int *h) -{ - if (!info) { - ErrPrint("Handle is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - *w = info->w; - *h = info->h; - return LB_STATUS_SUCCESS; -} - -int fb_size(struct fb_info *info) -{ - if (!info) { - return 0; - } - - update_fb_size(info); - - return info->bufsz; -} - -int fb_type(struct fb_info *info) -{ - struct buffer *buffer; - - if (!info) { - return BUFFER_TYPE_ERROR; - } - - buffer = info->buffer; - if (!buffer) { - int type = BUFFER_TYPE_ERROR; - /*! - * \note - * Try to get this from SCHEMA - */ - if (info->id) { - if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { - type = BUFFER_TYPE_FILE; - } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - type = BUFFER_TYPE_PIXMAP; - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { - type = BUFFER_TYPE_SHM; - } - } - - return type; - } - - return buffer->type; -} -/* End of a file */ diff --git a/src/fb_wayland.c b/src/fb_wayland.c deleted file mode 100644 index a38eb5f..0000000 --- a/src/fb_wayland.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include /* For error code */ - -#include "debug.h" -#include "util.h" -#include "fb.h" - -int errno; - -struct fb_info { - char *id; - int w; - int h; - int bufsz; - void *buffer; - - int pixels; - int handle; -}; - -struct buffer { /*!< Must has to be sync with slave & provider */ - enum { - CREATED = 0x00beef00, - DESTROYED = 0x00dead00 - } state; - enum buffer_type type; - int refcnt; - void *info; - char data[]; -}; - -static struct { -} s_info = { -}; - -int fb_init(void *disp) -{ - return 0; -} - -int fb_fini(void) -{ - return 0; -} - -static inline void update_fb_size(struct fb_info *info) -{ - info->bufsz = info->w * info->h * info->pixels; -} - -static inline int sync_for_file(struct fb_info *info) -{ - int fd; - struct buffer *buffer; - - buffer = info->buffer; - - if (!buffer) { /* Ignore this sync request */ - return LB_STATUS_SUCCESS; - } - - if (buffer->state != CREATED) { - ErrPrint("Invalid state of a FB\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (buffer->type != BUFFER_TYPE_FILE) { - ErrPrint("Invalid buffer\n"); - return LB_STATUS_SUCCESS; - } - - fd = open(util_uri_to_path(info->id), O_RDONLY); - if (fd < 0) { - ErrPrint("Failed to open a file (%s) because of (%s)\n", - util_uri_to_path(info->id), strerror(errno)); - - /*! - * \note - * But return ZERO, even if we couldn't get a buffer file, - * the viewer can draw empty screen. - * - * and then update it after it gots update events - */ - return LB_STATUS_SUCCESS; - } - - if (read(fd, buffer->data, info->bufsz) != info->bufsz) { - ErrPrint("read: %s\n", strerror(errno)); - if (close(fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - - /*! - * \note - * But return ZERO, even if we couldn't get a buffer file, - * the viewer can draw empty screen. - * - * and then update it after it gots update events - */ - return LB_STATUS_SUCCESS; - } - - if (close(fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - return LB_STATUS_SUCCESS; -} - -int fb_sync(struct fb_info *info) -{ - if (!info) { - ErrPrint("FB Handle is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!info->id || info->id[0] == '\0') { - DbgPrint("Ingore sync\n"); - return LB_STATUS_SUCCESS; - } - - if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { - return sync_for_file(info); - } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { - /* No need to do sync */ - return LB_STATUS_SUCCESS; - } - - return LB_STATUS_ERROR_INVALID; -} - -struct fb_info *fb_create(const char *id, int w, int h) -{ - struct fb_info *info; - - if (!id || id[0] == '\0') { - ErrPrint("Invalid ID\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->pixels = sizeof(int); /* Use the default pixels(depth) */ - - if (sscanf(info->id, SCHEMA_SHM "%d", &info->handle) == 1) { - DbgPrint("SHMID: %d is gotten\n", info->handle); - } else if (sscanf(info->id, SCHEMA_PIXMAP "%d:%d", &info->handle, &info->pixels) == 2) { - DbgPrint("PIXMAP-SHMID: %d is gotten (%d)\n", info->handle, info->pixels); - ErrPrint("Unsupported\n"); - free(info); - return NULL; - } else { - info->handle = LB_STATUS_ERROR_INVALID; - } - - info->bufsz = 0; - info->buffer = NULL; - info->w = w; - info->h = h; - - return info; -} - -int fb_destroy(struct fb_info *info) -{ - if (!info) { - ErrPrint("Handle is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (info->buffer) { - struct buffer *buffer; - buffer = info->buffer; - - buffer->info = NULL; - } - - free(info->id); - free(info); - return LB_STATUS_SUCCESS; -} - -int fb_is_created(struct fb_info *info) -{ - if (!info) { - ErrPrint("Handle is not valid\n"); - return 0; - } - - if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)) && info->handle != 0) { - return 1; - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM)) && info->handle > 0) { - return 1; - } else { - const char *path; - path = util_uri_to_path(info->id); - if (path && access(path, F_OK | R_OK) == 0) { - return 1; - } else { - ErrPrint("access: %s (%s)\n", strerror(errno), path); - } - } - - return 0; -} - -void *fb_acquire_buffer(struct fb_info *info) -{ - struct buffer *buffer; - - if (!info) { - ErrPrint("info == NIL\n"); - return NULL; - } - - if (!info->buffer) { - if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - ErrPrint("Unsupported Type\n"); - return NULL; - } else if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { - update_fb_size(info); - - buffer = calloc(1, sizeof(*buffer) + info->bufsz); - if (!buffer) { - ErrPrint("Heap: %s\n", strerror(errno)); - info->bufsz = 0; - return NULL; - } - - buffer->type = BUFFER_TYPE_FILE; - buffer->refcnt = 0; - buffer->state = CREATED; - buffer->info = info; - info->buffer = buffer; - - sync_for_file(info); - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { - buffer = shmat(info->handle, NULL, 0); - if (buffer == (void *)-1) { - ErrPrint("shmat: %s (%d)\n", strerror(errno), info->handle); - return NULL; - } - - return buffer->data; - } else { - ErrPrint("Buffer is not created (%s)\n", info->id); - return NULL; - } - } - - buffer = info->buffer; - - switch (buffer->type) { - case BUFFER_TYPE_FILE: - buffer->refcnt++; - break; - case BUFFER_TYPE_PIXMAP: - default: - DbgPrint("Unknwon FP: %d\n", buffer->type); - break; - } - - return buffer->data; -} - -int fb_release_buffer(void *data) -{ - struct buffer *buffer; - - if (!data) { - ErrPrint("buffer data == NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - buffer = container_of(data, struct buffer, data); - - if (buffer->state != CREATED) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - switch (buffer->type) { - case BUFFER_TYPE_SHM: - if (shmdt(buffer) < 0) { - ErrPrint("shmdt: %s\n", strerror(errno)); - } - break; - case BUFFER_TYPE_FILE: - buffer->refcnt--; - if (buffer->refcnt == 0) { - struct fb_info *info; - info = buffer->info; - - buffer->state = DESTROYED; - free(buffer); - - if (info && info->buffer == buffer) { - info->buffer = NULL; - } - } - break; - case BUFFER_TYPE_PIXMAP: - default: - ErrPrint("Unknwon buffer type\n"); - break; - } - - return LB_STATUS_SUCCESS; -} - -int fb_refcnt(void *data) -{ - struct buffer *buffer; - struct shmid_ds buf; - int ret; - - if (!data) { - return LB_STATUS_ERROR_INVALID; - } - - buffer = container_of(data, struct buffer, data); - - if (buffer->state != CREATED) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - switch (buffer->type) { - case BUFFER_TYPE_SHM: - if (shmctl(buffer->refcnt, IPC_STAT, &buf) < 0) { - ErrPrint("Error: %s\n", strerror(errno)); - return LB_STATUS_ERROR_FAULT; - } - - ret = buf.shm_nattch; - break; - case BUFFER_TYPE_FILE: - ret = buffer->refcnt; - break; - case BUFFER_TYPE_PIXMAP: - default: - ret = LB_STATUS_ERROR_INVALID; - break; - } - - return ret; -} - -const char *fb_id(struct fb_info *info) -{ - return info ? info->id : NULL; -} - -int fb_get_size(struct fb_info *info, int *w, int *h) -{ - if (!info) { - ErrPrint("Handle is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - *w = info->w; - *h = info->h; - return LB_STATUS_SUCCESS; -} - -int fb_size(struct fb_info *info) -{ - if (!info) { - return 0; - } - - update_fb_size(info); - - return info->bufsz; -} - -int fb_type(struct fb_info *info) -{ - struct buffer *buffer; - - if (!info) { - return BUFFER_TYPE_ERROR; - } - - buffer = info->buffer; - if (!buffer) { - int type = BUFFER_TYPE_ERROR; - /*! - * \note - * Try to get this from SCHEMA - */ - if (info->id) { - if (!strncasecmp(info->id, SCHEMA_FILE, strlen(SCHEMA_FILE))) { - type = BUFFER_TYPE_FILE; - } else if (!strncasecmp(info->id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - /* Unsupported type */ - } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) { - type = BUFFER_TYPE_SHM; - } - } - - return type; - } - - return buffer->type; -} -/* End of a file */ diff --git a/src/file_service.c b/src/file_service.c deleted file mode 100644 index e890d0b..0000000 --- a/src/file_service.c +++ /dev/null @@ -1,715 +0,0 @@ -/* - * 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 _GNU_SOURCE - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "client.h" -#include "debug.h" -#include "dlist.h" - -#define FILE_SERVICE_PORT 8209 - -#define CRITICAL_SECTION_BEGIN(handle) \ -do { \ - int ret; \ - ret = pthread_mutex_lock(handle); \ - if (ret != 0) { \ - ErrPrint("Failed to lock: %s\n", strerror(ret)); \ - } \ -} while (0) - -#define CRITICAL_SECTION_END(handle) \ -do { \ - int ret; \ - ret = pthread_mutex_unlock(handle); \ - if (ret != 0) { \ - ErrPrint("Failed to unlock: %s\n", strerror(ret)); \ - } \ -} while (0) - -#define CANCEL_SECTION_BEGIN() do { \ - int ret; \ - ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); \ - if (ret != 0) { \ - ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \ - } \ -} while (0) - -#define CANCEL_SECTION_END() do { \ - int ret; \ - ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); \ - if (ret != 0) { \ - ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \ - } \ -} while (0) - -#define CLOSE_PIPE(p) do { \ - int status; \ - status = close(p[PIPE_READ]); \ - if (status < 0) { \ - ErrPrint("close: %s\n", strerror(errno)); \ - } \ - status = close(p[PIPE_WRITE]); \ - if (status < 0) { \ - ErrPrint("close: %s\n", strerror(errno)); \ - } \ -} while (0) - -#define PIPE_READ 0 -#define PIPE_WRITE 1 -#define PIPE_MAX 2 - -#define EVT_END_CH 'c' -#define EVT_CH 'e' - -static struct { - pthread_t file_svc_thid; - pthread_mutex_t file_svc_lock; - int ctrl_pipe[PIPE_MAX]; - int evt_pipe[PIPE_MAX]; - struct dlist *request_list; - int file_service_fd; -} s_info = { - .ctrl_pipe = { -1, -1 }, - .evt_pipe = { -1, -1 }, - .request_list = NULL, - .file_service_fd = -1, -}; - -struct request_item { - char *filename; - char *save_to; - void (*result_cb)(const char *filename, const char *save_to, int ret, void *data); - void *data; - int ret; -}; - -/*! - * File transfer header. - * This must should be shared with client. - */ -struct burst_head { - off_t size; - int flen; - char fname[]; -}; - -struct burst_data { - int size; - char data[]; -}; - -static inline int put_event_ch(int fd, char ch) -{ - int ret; - - ret = write(fd, &ch, sizeof(ch)); - if (ret != sizeof(ch)) { - ErrPrint("write: %s\n", strerror(errno)); - return ret; - } - - return 0; -} - -static inline int get_event_ch(int fd) -{ - int ret; - char ch; - - ret = read(fd, &ch, sizeof(ch)); - if (ret != sizeof(ch)) { - ErrPrint("read: %s\n", strerror(errno)); - return ret; - } - - ret = (int)((unsigned int)ch); - return ret; -} - -static inline int file_service_close(int fd) -{ - return secure_socket_destroy_handle(fd); -} - -static inline int file_service_open(void) -{ - char *addr; - int port; - char *file_addr; - int len; - int fd; - - addr = malloc(strlen(client_addr()) + 1); - if (!addr) { - ErrPrint("Heap: %s\n", strerror(errno)); - return -ENOMEM; - } - - if (sscanf(client_addr(), COM_CORE_REMOTE_SCHEME"%[^:]:%d", addr, &port) != 2) { - ErrPrint("Invalid URL\n"); - free(addr); - return -EINVAL; - } - - len = strlen(COM_CORE_REMOTE_SCHEME); - len+= strlen(addr); - len+= 6; /* Port length? */ - - file_addr = malloc(len); - if (!file_addr) { - ErrPrint("Heap: %s\n", strerror(errno)); - free(addr); - return -ENOMEM; - } - - snprintf(file_addr, len, COM_CORE_REMOTE_SCHEME"%s:%d", addr, FILE_SERVICE_PORT); - DbgPrint("File service: %s\n", file_addr); - fd = secure_socket_create_client(file_addr); - free(file_addr); - free(addr); - - return fd; -} - -/*! - * Service Thread - */ -static void write_item_to_pipe(struct request_item *item, int ret) -{ - item->ret = LB_STATUS_ERROR_FAULT; - if (write(s_info.evt_pipe[PIPE_WRITE], &item, sizeof(item)) != sizeof(item)) { - ErrPrint("write: %s\n", strerror(errno)); - free(item->filename); - free(item->save_to); - free(item); - item = NULL; - } -} - -/*! - * Service Thread - */ -static void *file_service_main(void *data) -{ - int ret = 0; - int select_fd; - struct timeval tv; - fd_set set; - int offset; - enum { - RECV_INIT, - RECV_HEADER, - RECV_DATA, - } recv_state; - struct burst_head *head; - struct burst_data *body; - int recvsz; - struct request_item *item; - int file_offset; - int file_fd; - - head = NULL; - item = NULL; - recv_state = RECV_INIT; - select_fd = (s_info.file_service_fd > s_info.ctrl_pipe[PIPE_READ] ? s_info.file_service_fd : s_info.ctrl_pipe[PIPE_READ]) + 1; - while (ret == 0) { - FD_ZERO(&set); - FD_SET(s_info.file_service_fd, &set); - FD_SET(s_info.ctrl_pipe[PIPE_READ], &set); - - tv.tv_sec = 3; - tv.tv_usec = 0; - ret = select(select_fd , &set, NULL, NULL, &tv); - if (ret < 0) { - ret = -errno; - if (errno == EINTR) { - ErrPrint("INTERRUPTED\n"); - ret = 0; - continue; - } - ErrPrint("Error: %s\n", strerror(errno)); - break; - } else if (ret == 0) { - ErrPrint("Timeout\n"); - ret = -ETIMEDOUT; - break; - } - - if (item && FD_ISSET(s_info.file_service_fd, &set)) { - switch (recv_state) { - case RECV_INIT: - if (head == NULL) { - recvsz = sizeof(*head); - - head = malloc(recvsz); - if (!head) { - ErrPrint("Heap: %s\n", strerror(errno)); - ret = LB_STATUS_ERROR_MEMORY; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - - offset = 0; - recv_state = RECV_HEADER; - } - case RECV_HEADER: - if (offset < recvsz) { - ret = secure_socket_recv(s_info.file_service_fd, (char *)head + offset, recvsz - offset, NULL); - if (ret > 0) { - offset += ret; - } else { - free(head); - head = NULL; - recv_state = RECV_INIT; - ret = LB_STATUS_ERROR_FAULT; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - } - - if (offset == sizeof(*head)) { - void *tmp; - - recvsz += head->flen; - - tmp = realloc(head, recvsz); - if (!tmp) { - ErrPrint("Heap: %s\n", strerror(errno)); - - free(head); - head = NULL; - recv_state = RECV_INIT; - - ret = LB_STATUS_ERROR_MEMORY; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - - head = tmp; - } else if (offset == recvsz) { - DbgPrint("Filesize: %d, name[%s]\n", head->size, head->fname); - if (strcmp(item->filename, head->fname)) { - ErrPrint("Invalid data sequence (%s <> %s)\n", item->filename, head->fname); - - free(head); - head = NULL; - recv_state = RECV_INIT; - ret = LB_STATUS_ERROR_FAULT; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - - file_fd = open(item->save_to, O_WRONLY|O_CREAT, 0644); - if (file_fd < 0) { - ErrPrint("open: %s\n", strerror(errno)); - free(head); - head = NULL; - recv_state = RECV_INIT; - - ret = LB_STATUS_ERROR_IO; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - - recv_state = RECV_DATA; - body = NULL; - - } else { - ErrPrint("Invalid state\n"); - free(head); - head = NULL; - recv_state = RECV_INIT; - ret = LB_STATUS_ERROR_INVALID; - write_item_to_pipe(item, ret); - item = NULL; - } - break; - case RECV_DATA: - if (!body) { - body = malloc(sizeof(*body)); - if (!body) { - free(head); - head = NULL; - recv_state = RECV_INIT; - ret = LB_STATUS_ERROR_MEMORY; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - - recvsz = sizeof(*body); - offset = 0; - } - - ret = secure_socket_recv(s_info.file_service_fd, (char *)body + offset, recvsz - offset, NULL); - if (ret > 0) { - offset += ret; - } else { - free(head); - head = NULL; - free(body); - body = NULL; - recv_state = RECV_INIT; - ret = LB_STATUS_ERROR_FAULT; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - - if (offset == sizeof(*body)) { - void *tmp; - - if (body->size < 0) { - ErrPrint("body->size: %d\n", body->size); - free(head); - head = NULL; - free(body); - body = NULL; - recv_state = RECV_INIT; - ret = LB_STATUS_ERROR_FAULT; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - - recvsz += body->size; - - tmp = realloc(body, recvsz); - if (!tmp) { - ErrPrint("Heap: %s\n", strerror(errno)); - free(head); - head = NULL; - - free(body); - body = NULL; - recv_state = RECV_INIT; - - ret = LB_STATUS_ERROR_MEMORY; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - } else if (offset == recvsz) { - /* Flush this to the file */ - ret = write(file_fd, body->data, body->size); - if (ret < 0) { - ErrPrint("write: %s\n", strerror(errno)); - free(head); - head = NULL; - - free(body); - body = NULL; - recv_state = RECV_INIT; - - ret = LB_STATUS_ERROR_IO; - write_item_to_pipe(item, ret); - item = NULL; - break; - } else { - if (body->size != ret) { - DbgPrint("Body is not flushed correctly: %d, %d\n", ret, body->size); - ret = body->size; - } - - file_offset += ret; - if (file_offset == head->size) { - if (close(file_fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - ret = LB_STATUS_SUCCESS; - write_item_to_pipe(item, ret); - item = NULL; - } - } - - free(body); - body = NULL; - - free(head); - head = NULL; - - recv_state = RECV_INIT; - } else { - ErrPrint("Invalid state\n"); - - ret = -EFAULT; - free(body); - body = NULL; - free(head); - head = NULL; - recv_state = RECV_INIT; - - ret = LB_STATUS_ERROR_FAULT; - write_item_to_pipe(item, ret); - item = NULL; - } - break; - default: - ErrPrint("Unknown event: %d\n", recv_state); - ret = LB_STATUS_ERROR_FAULT; - write_item_to_pipe(item, ret); - item = NULL; - break; - } - } else if (item == NULL && recv_state == RECV_INIT && FD_ISSET(s_info.ctrl_pipe[PIPE_READ], &set)) { - int ch; - struct dlist *l; - - /* Only if the recv state is not changed, we can get next request item */ - ch = get_event_ch(s_info.ctrl_pipe[PIPE_READ]); - if (ch == EVT_END_CH) { - DbgPrint("Service thread is canceled\n"); - break; - } - - CRITICAL_SECTION_BEGIN(&s_info.file_svc_lock); - l = dlist_nth(s_info.request_list, 0); - item = dlist_data(l); - s_info.request_list = dlist_remove(s_info.request_list, l); - CRITICAL_SECTION_END(&s_info.file_svc_lock); - } - } - - return (void *)ret; -} - -/* Master */ -static gboolean evt_cb(GIOChannel *src, GIOCondition cond, gpointer data) -{ - int fd; - struct request_item *item; - - fd = g_io_channel_unix_get_fd(src); - - if (!(cond & G_IO_IN)) { - DbgPrint("Client is disconencted\n"); - return FALSE; - } - - if ((cond & G_IO_ERR) || (cond & G_IO_HUP) || (cond & G_IO_NVAL)) { - DbgPrint("Client connection is lost\n"); - return FALSE; - } - - if (read(fd, &item, sizeof(item)) != sizeof(item)) { - ErrPrint("read: %s\n", strerror(errno)); - } else { - if (item->result_cb) { - item->result_cb(item->filename, item->save_to, item->ret, item->data); - } - - free(item->filename); - free(item->save_to); - free(item); - } - - return TRUE; -} - -int file_service_send_request(const char *filename, const char *save_to, void (*result_cb)(const char *filename, const char *save_to, int ret, void *data), void *data) -{ - struct request_item *item; - - item = malloc(sizeof(*item)); - if (!item) { - ErrPrint("Heap: %s\n", strerror(errno)); - return -ENOMEM; - } - - item->filename = strdup(filename); - if (!item->filename) { - ErrPrint("Heap: %s\n", strerror(errno)); - free(item); - return -ENOMEM; - } - - item->save_to = strdup(save_to); - if (!item->save_to) { - ErrPrint("Heap: %s\n", strerror(errno)); - free(item->filename); - free(item); - return -ENOMEM; - } - - item->result_cb = result_cb; - item->data = data; - - CRITICAL_SECTION_BEGIN(&s_info.file_svc_lock); - s_info.request_list = dlist_append(s_info.request_list, item); - CRITICAL_SECTION_END(&s_info.file_svc_lock); - return 0; -} - -int file_service_init(void) -{ - int status; - GIOChannel *gio; - guint id; - - if (strncmp(client_addr(), COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { - return 0; - } - - s_info.file_service_fd = file_service_open(); - if (s_info.file_service_fd < 0) { - return -EFAULT; - } - - if (pipe2(s_info.ctrl_pipe, O_NONBLOCK | O_CLOEXEC) < 0) { - ErrPrint("file service: %s\n", strerror(errno)); - file_service_close(s_info.file_service_fd); - s_info.file_service_fd = -1; - return -EFAULT; - } - - if (pipe2(s_info.evt_pipe, O_NONBLOCK | O_CLOEXEC) < 0) { - ErrPrint("file service: %s\n", strerror(errno)); - CLOSE_PIPE(s_info.ctrl_pipe); - file_service_close(s_info.file_service_fd); - s_info.file_service_fd = -1; - return -EFAULT; - } - - status = pthread_mutex_init(&s_info.file_svc_lock, NULL); - if (status != 0) { - ErrPrint("Mutex: %s\n", strerror(status)); - CLOSE_PIPE(s_info.ctrl_pipe); - CLOSE_PIPE(s_info.evt_pipe); - file_service_close(s_info.file_service_fd); - s_info.file_service_fd = -1; - return -EFAULT; - } - - gio = g_io_channel_unix_new(s_info.evt_pipe[PIPE_READ]); - if (!gio) { - ErrPrint("io channel new\n"); - status = pthread_mutex_destroy(&s_info.file_svc_lock); - if (status != 0) { - ErrPrint("destroy: %s\n", strerror(status)); - } - CLOSE_PIPE(s_info.ctrl_pipe); - CLOSE_PIPE(s_info.evt_pipe); - file_service_close(s_info.file_service_fd); - s_info.file_service_fd = -1; - return -EFAULT; - } - - g_io_channel_set_close_on_unref(gio, FALSE); - - id = g_io_add_watch(gio, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc)evt_cb, NULL); - if (id <= 0) { - GError *err = NULL; - ErrPrint("Failed to add IO watch\n"); - g_io_channel_shutdown(gio, TRUE, &err); - if (err) { - ErrPrint("Shutdown: %s\n", err->message); - g_error_free(err); - } - g_io_channel_unref(gio); - - status = pthread_mutex_destroy(&s_info.file_svc_lock); - if (status != 0) { - ErrPrint("destroy: %s\n", strerror(status)); - } - CLOSE_PIPE(s_info.ctrl_pipe); - CLOSE_PIPE(s_info.evt_pipe); - file_service_close(s_info.file_service_fd); - s_info.file_service_fd = -1; - return -EIO; - } - - status = pthread_create(&s_info.file_svc_thid, NULL, file_service_main, NULL); - if (status != 0) { - GError *err = NULL; - ErrPrint("Failed to add IO watch\n"); - g_io_channel_shutdown(gio, TRUE, &err); - if (err) { - ErrPrint("Shutdown: %s\n", err->message); - g_error_free(err); - } - g_io_channel_unref(gio); - - ErrPrint("file service: %s\n", strerror(status)); - CLOSE_PIPE(s_info.ctrl_pipe); - CLOSE_PIPE(s_info.evt_pipe); - file_service_close(s_info.file_service_fd); - s_info.file_service_fd = -1; - - status = pthread_mutex_destroy(&s_info.file_svc_lock); - if (status != 0) { - ErrPrint("destroy: %s\n", strerror(status)); - } - - return -EFAULT; - } - - g_io_channel_unref(gio); - return 0; -} - -int file_service_fini(void) -{ - void *svc_ret; - int ret; - - if (strncmp(client_addr(), COM_CORE_REMOTE_SCHEME, strlen(COM_CORE_REMOTE_SCHEME))) { - return 0; - } - - (void)put_event_ch(s_info.ctrl_pipe[PIPE_WRITE], EVT_END_CH); - - ret = pthread_join(s_info.file_svc_thid, &svc_ret); - if (ret != 0) { - ErrPrint("join: %s\n", strerror(ret)); - } else { - DbgPrint("file svc returns: %d\n", (int)svc_ret); - } - - ret = pthread_mutex_destroy(&s_info.file_svc_lock); - if (ret != 0) { - ErrPrint("destroy: %s\n", strerror(ret)); - } - - CLOSE_PIPE(s_info.evt_pipe); - CLOSE_PIPE(s_info.ctrl_pipe); - - return 0; -} - -/* End of a file */ diff --git a/src/livebox.c b/src/livebox.c deleted file mode 100644 index 1eed536..0000000 --- a/src/livebox.c +++ /dev/null @@ -1,4885 +0,0 @@ -/* - * 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 -#include -#include /* malloc */ -#include /* strdup */ -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "debug.h" -#include "fb.h" -#include "livebox.h" -#include "livebox_internal.h" -#include "dlist.h" -#include "util.h" -#include "master_rpc.h" -#include "client.h" -#include "conf.h" - -#define EAPI __attribute__((visibility("default"))) - -#if defined(FLOG) -FILE *__file_log_fp; -#endif - -static int default_launch_handler(struct livebox *handler, const char *appid, void *data); - -enum event_state { - INFO_STATE_CALLBACK_IN_IDLE = 0x00, - INFO_STATE_CALLBACK_IN_PROCESSING = 0x01, -}; - -static struct info { - struct dlist *livebox_list; - struct dlist *livebox_common_list; - - struct dlist *event_list; - struct dlist *fault_list; - - int init_count; - int prevent_overwrite; - enum event_state event_state; - enum event_state fault_state; - guint job_timer; - struct dlist *job_list; - - struct launch { - int (*handler)(struct livebox *handler, const char *appid, void *data); - void *data; - } launch; -} s_info = { - .livebox_list = NULL, - .event_list = NULL, - .fault_list = NULL, - .init_count = 0, - .prevent_overwrite = 0, - .event_state = INFO_STATE_CALLBACK_IN_IDLE, - .fault_state = INFO_STATE_CALLBACK_IN_IDLE, - .job_timer = 0, - .job_list = NULL, - .launch = { - .handler = default_launch_handler, - .data = NULL, - }, -}; - -struct cb_info { - ret_cb_t cb; - void *data; -}; - -struct event_info { - int is_deleted; - int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data); - void *user_data; -}; - -struct fault_info { - int is_deleted; - int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data); - void *user_data; -}; - -static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data); -static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data); - -static int default_launch_handler(struct livebox *handler, const char *appid, void *data) -{ - int ret; - - ret = aul_launch_app(appid, NULL); - if (ret <= 0) { - ErrPrint("Failed to launch an app %s (%d)\n", appid, ret); - } - -/* - service_h service; - - DbgPrint("AUTO_LAUNCH [%s]\n", handler->common->lb.auto_launch); - - ret = service_create(&service); - if (ret == SERVICE_ERROR_NONE) { - service_set_package(service, handler->common->lb.auto_launch); - service_send_launch_request(service, NULL, NULL); - service_destroy(service); - } else { - ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret); - } -*/ - - return ret > 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT; -} - -static inline void default_create_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default created event handler: %d\n", ret); -} - -static inline void default_delete_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default deleted event handler: %d\n", ret); -} - -static inline void default_pinup_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default pinup event handler: %d\n", ret); -} - -static inline void default_group_changed_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default group changed event handler: %d\n", ret); -} - -static inline void default_period_changed_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default period changed event handler: %d\n", ret); -} - -static inline void default_pd_created_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default PD created event handler: %d\n", ret); -} - -static inline void default_pd_destroyed_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default PD destroyed event handler: %d\n", ret); -} - -static inline void default_lb_size_changed_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default LB size changed event handler: %d\n", ret); -} - -static inline void default_update_mode_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default update mode set event handler: %d\n", ret); -} - -static inline void default_access_event_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default access event handler: %d\n", ret); -} - -static inline void default_key_event_cb(struct livebox *handler, int ret, void *data) -{ - DbgPrint("Default key event handler: %d\n", ret); -} - -static inline __attribute__((always_inline)) struct cb_info *create_cb_info(ret_cb_t cb, void *data) -{ - struct cb_info *info; - - info = malloc(sizeof(*info)); - if (!info) { - ErrPrint("Heap: %s\n", strerror(errno)); - return NULL; - } - - info->cb = cb; - info->data = data; - return info; -} - -static inline void destroy_cb_info(struct cb_info *info) -{ - free(info); -} - -static int do_fb_lock(int fd) -{ - struct flock flock; - int ret; - - flock.l_type = F_RDLCK; - flock.l_whence = SEEK_SET; - flock.l_start = 0; - flock.l_len = 0; - flock.l_pid = getpid(); - - do { - ret = fcntl(fd, F_SETLKW, &flock); - if (ret < 0) { - ret = errno; - ErrPrint("fcntl: %s\n", strerror(errno)); - } - } while (ret == EINTR); - - return ret; -} - -static int do_fb_unlock(int fd) -{ - struct flock flock; - int ret; - - flock.l_type = F_UNLCK; - flock.l_whence = SEEK_SET; - flock.l_start = 0; - flock.l_len = 0; - flock.l_pid = getpid(); - - do { - ret = fcntl(fd, F_SETLKW, &flock); - if (ret < 0) { - ret = errno; - ErrPrint("fcntl: %s\n", strerror(errno)); - } - } while (ret == EINTR); - - return ret; -} - -int lb_destroy_lock_file(struct livebox_common *common, int is_pd) -{ - if (is_pd) { - if (!common->pd.lock) { - return LB_STATUS_ERROR_INVALID; - } - - if (close(common->pd.lock_fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - common->pd.lock_fd = -1; - - if (unlink(common->pd.lock) < 0) { - ErrPrint("unlink: %s\n", strerror(errno)); - } - - free(common->pd.lock); - common->pd.lock = NULL; - } else { - if (!common->lb.lock) { - return LB_STATUS_ERROR_INVALID; - } - - if (close(common->lb.lock_fd) < 0) { - ErrPrint("close: %s\n", strerror(errno)); - } - common->lb.lock_fd = -1; - - if (unlink(common->lb.lock) < 0) { - ErrPrint("unlink: %s\n", strerror(errno)); - } - - free(common->lb.lock); - common->lb.lock = NULL; - } - - return LB_STATUS_SUCCESS; -} - -int lb_create_lock_file(struct livebox_common *common, int is_pd) -{ - int len; - char *file; - - len = strlen(common->id); - file = malloc(len + 20); - if (!file) { - ErrPrint("Heap: %s\n", strerror(errno)); - return LB_STATUS_ERROR_MEMORY; - } - - snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(common->id), is_pd ? "pd" : "lb"); - - if (is_pd) { - common->pd.lock_fd = open(file, O_RDONLY); - if (common->pd.lock_fd < 0) { - ErrPrint("open: %s\n", strerror(errno)); - free(file); - return LB_STATUS_ERROR_IO; - } - - common->pd.lock = file; - } else { - common->lb.lock_fd = open(file, O_RDONLY); - if (common->lb.lock_fd < 0) { - ErrPrint("open: %s\n", strerror(errno)); - free(file); - return LB_STATUS_ERROR_IO; - } - - common->lb.lock = file; - } - - return LB_STATUS_SUCCESS; -} - -static void update_mode_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - goto errout; - } else if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid argument\n"); - ret = LB_STATUS_ERROR_INVALID; - goto errout; - } - - if (ret < 0) { - ErrPrint("Resize request is failed: %d\n", ret); - goto errout; - } - - return; - -errout: - handler->cbs.update_mode.cb(handler, ret, handler->cbs.update_mode.data); - handler->cbs.update_mode.cb = NULL; - handler->cbs.update_mode.data = NULL; - handler->common->request.update_mode = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static void resize_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - goto errout; - } else if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid argument\n"); - ret = LB_STATUS_ERROR_INVALID; - goto errout; - } - - /*! - * \note - * In case of resize request, - * The livebox handler will not have resized value right after this callback, - * It can only get the new size when it makes updates. - * - * So the user can only get the resized value(result) from the first update event - * after this request. - */ - if (ret < 0) { - ErrPrint("Resize request is failed: %d\n", ret); - goto errout; - } - - return; - -errout: - handler->cbs.size_changed.cb(handler, ret, handler->cbs.size_changed.data); - handler->cbs.size_changed.cb = NULL; - handler->cbs.size_changed.data = NULL; - handler->common->request.size_changed = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - void *cbdata; - struct cb_info *info = data; - ret_cb_t cb; - - cbdata = info->data; - cb = info->cb; - destroy_cb_info(info); - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid argument\n"); - ret = LB_STATUS_ERROR_INVALID; - } - - if (cb) { - cb(handler, ret, cbdata); - } - return; -} - -static void set_group_ret_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - goto errout; - } else if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid argument\n"); - ret = LB_STATUS_ERROR_INVALID; - goto errout; - } - - if (ret < 0) { - goto errout; - } - - return; - -errout: - handler->cbs.group_changed.cb(handler, ret, handler->cbs.group_changed.data); - handler->cbs.group_changed.cb = NULL; - handler->cbs.group_changed.data = NULL; - handler->common->request.group_changed = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - goto errout; - } else if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid argument\n"); - ret = LB_STATUS_ERROR_INVALID; - goto errout; - } - - if (ret < 0) { - goto errout; - } - - return; - -errout: - handler->cbs.period_changed.cb(handler, ret, handler->cbs.period_changed.data); - handler->cbs.period_changed.cb = NULL; - handler->cbs.period_changed.data = NULL; - handler->common->request.period_changed = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data) -{ - struct cb_info *info = data; - int ret; - ret_cb_t cb; - void *cbdata; - - cb = info->cb; - cbdata = info->data; - destroy_cb_info(info); - - if (!result) { - ErrPrint("Connection lost?\n"); - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid argument\n"); - ret = LB_STATUS_ERROR_INVALID; - } - - if (ret == 0) { - handler->cbs.deleted.cb = cb; - handler->cbs.deleted.data = cbdata; - } else if (cb) { - cb(handler, ret, cbdata); - } - - /*! - * \note - * Do not call the deleted callback from here. - * master will send the "deleted" event. - * Then invoke this callback. - * - * if (handler->cbs.deleted.cb) - * handler->cbs.deleted.cb(handler, ret, handler->cbs.deleted.data); - */ -} - -static void new_ret_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - struct cb_info *info = data; - ret_cb_t cb; - void *cbdata; - - cb = info->cb; - cbdata = info->data; - destroy_cb_info(info); - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "i", &ret) != 1) { - ret = LB_STATUS_ERROR_INVALID; - } - - if (ret >= 0) { - handler->cbs.created.cb = cb; - handler->cbs.created.data = cbdata; - - /*! - * \note - * Don't go anymore ;) - */ - return; - } else if (cb) { - /*! - * \note - * It means the current instance is not created, - * so user has to know about this. - * notice it to user using "deleted" event. - */ - cb(handler, ret, cbdata); - } - - lb_unref(handler, 1); -} - -static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - goto errout; - } else if (packet_get(result, "i", &ret) != 1) { - ret = LB_STATUS_ERROR_INVALID; - goto errout; - } - - if (ret < 0) { - ErrPrint("Failed to create a PD[%d]\n", ret); - goto errout; - } - - return; - -errout: - handler->cbs.pd_created.cb(handler, ret, handler->cbs.pd_created.data); - handler->cbs.pd_created.cb = NULL; - handler->cbs.pd_created.data = NULL; - handler->common->request.pd_created = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static void activated_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - struct cb_info *info = data; - void *cbdata; - ret_cb_t cb; - const char *pkgname = ""; - - cbdata = info->data; - cb = info->cb; - destroy_cb_info(info); - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "is", &ret, &pkgname) != 2) { - ret = LB_STATUS_ERROR_INVALID; - } - - if (cb) { - cb(handler, ret, cbdata); - } -} - -static void pd_destroy_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - ret_cb_t cb; - void *cbdata; - struct cb_info *info = data; - - cbdata = info->data; - cb = info->cb; - destroy_cb_info(info); - - if (!result) { - ErrPrint("Result is NIL (may connection lost)\n"); - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid parameter\n"); - ret = LB_STATUS_ERROR_INVALID; - } - - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.pd_destroyed.cb = cb; - handler->cbs.pd_destroyed.data = cbdata; - } else { - handler->common->is_pd_created = 0; - handler->common->request.pd_destroyed = 0; - - if (cb) { - cb(handler, ret, cbdata); - } - } -} - -static void delete_cluster_cb(struct livebox *handler, const struct packet *result, void *data) -{ - struct cb_info *info = data; - int ret; - ret_cb_t cb; - void *cbdata; - - cb = info->cb; - cbdata = info->data; - destroy_cb_info(info); - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "i", &ret) != 1) { - ret = LB_STATUS_ERROR_INVALID; - } - - if (cb) { - cb(handler, ret, cbdata); - } -} - -static void delete_category_cb(struct livebox *handler, const struct packet *result, void *data) -{ - struct cb_info *info = data; - int ret; - ret_cb_t cb; - void *cbdata; - - cb = info->cb; - cbdata = info->data; - destroy_cb_info(info); - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "i", &ret) != 1) { - ret = LB_STATUS_ERROR_INVALID; - } - - if (cb) { - cb(handler, ret, cbdata); - } -} - -static int lb_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - const char *id; - int ret; - - id = fb_id(handler->common->lb.fb); - if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - return LB_STATUS_ERROR_INVALID; - } - - packet = packet_create("lb_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - packet_destroy(packet); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo); - if (ret < 0) { - destroy_cb_info(cbinfo); - } - - return ret; -} - -static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int pixmap; - int ret = LB_STATUS_ERROR_INVALID; - ret_cb_t cb; - void *cbdata; - struct cb_info *info = data; - - cb = info->cb; - cbdata = info->data; - destroy_cb_info(info); - - if (!result) { - pixmap = 0; /* PIXMAP 0 means error */ - } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { - pixmap = 0; - } - - if (ret == (int)LB_STATUS_ERROR_BUSY) { - ret = lb_acquire_lb_pixmap(handler, cb, cbdata); - DbgPrint("Busy, Try again: %d\n", ret); - /* Try again */ - } else if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - if (cb) { - cb(handler, pixmap, cbdata); - } - - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } else { - if (cb) { - cb(handler, pixmap, cbdata); - } - } -} - -static int lb_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - const char *id; - int ret; - - id = fb_id(handler->common->pd.fb); - if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - return LB_STATUS_ERROR_INVALID; - } - - packet = packet_create("pd_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - packet_destroy(packet); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo); - if (ret < 0) { - /*! - * \note - * Packet will be destroyed by master_rpc_async_request - */ - destroy_cb_info(cbinfo); - } - - return ret; -} - -static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int pixmap; - int ret; - ret_cb_t cb; - void *cbdata; - struct cb_info *info = data; - - cb = info->cb; - cbdata = info->data; - destroy_cb_info(info); - - if (!result) { - pixmap = 0; /* PIXMAP 0 means error */ - ret = LB_STATUS_ERROR_FAULT; - } else if (packet_get(result, "ii", &pixmap, &ret) != 2) { - pixmap = 0; - ret = LB_STATUS_ERROR_INVALID; - } - - if (ret == (int)LB_STATUS_ERROR_BUSY) { - ret = lb_acquire_pd_pixmap(handler, cb, cbdata); - DbgPrint("Busy, Try again: %d\n", ret); - /* Try again */ - } else if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - if (cb) { - cb(handler, pixmap, cbdata); - } - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } else { - if (cb) { - DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap); - cb(handler, pixmap, cbdata); - } - } -} - -static void pinup_done_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - goto errout; - } else if (packet_get(result, "i", &ret) != 1) { - goto errout; - } - - if (ret < 0) { - goto errout; - } - - return; - -errout: - handler->cbs.pinup.cb(handler, ret, handler->cbs.pinup.data); - handler->cbs.pinup.cb = NULL; - handler->cbs.pinup.data = NULL; - handler->common->request.pinup = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static void key_ret_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - return; - } - - if (packet_get(result, "i", &ret) != 1) { - ret = LB_STATUS_ERROR_INVALID; - return; - } - - if (ret != LB_STATUS_SUCCESS) { - goto errout; - } - - return; -errout: - handler->cbs.key_event.cb(handler, ret, handler->cbs.key_event.data); - handler->cbs.key_event.cb = NULL; - handler->cbs.key_event.data = NULL; - handler->common->request.key_event = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static void access_ret_cb(struct livebox *handler, const struct packet *result, void *data) -{ - int ret; - - if (!result) { - ret = LB_STATUS_ERROR_FAULT; - return; - } - - if (packet_get(result, "i", &ret) != 1) { - ret = LB_STATUS_ERROR_INVALID; - return; - } - - if (ret != LB_STATUS_SUCCESS) { - goto errout; - } - - return; - -errout: - handler->cbs.access_event.cb(handler, ret, handler->cbs.access_event.data); - handler->cbs.access_event.cb = NULL; - handler->cbs.access_event.data = NULL; - handler->common->request.access_event = 0; - - if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } -} - -static int send_access_event(struct livebox *handler, const char *event, int x, int y) -{ - struct packet *packet; - double timestamp; - - timestamp = util_timestamp(); - - packet = packet_create(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y); - if (!packet) { - ErrPrint("Failed to build packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_async_request(handler, packet, 0, access_ret_cb, NULL); -} - -static int send_key_event(struct livebox *handler, const char *event, unsigned int keycode) -{ - struct packet *packet; - double timestamp; - - timestamp = util_timestamp(); - packet = packet_create(event, "ssdi", handler->common->pkgname, handler->common->id, timestamp, keycode); - if (!packet) { - ErrPrint("Failed to build packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_async_request(handler, packet, 0, key_ret_cb, NULL); -} - -static int send_mouse_event(struct livebox *handler, const char *event, int x, int y) -{ - struct packet *packet; - double timestamp; - - timestamp = util_timestamp(); - packet = packet_create_noack(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y); - if (!packet) { - ErrPrint("Failed to build param\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(handler, packet); -} - -static void initialize_livebox(void *disp, int use_thread) -{ -#if defined(FLOG) - char filename[BUFSIZ]; - snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid()); - __file_log_fp = fopen(filename, "w+t"); - if (!__file_log_fp) { - __file_log_fp = fdopen(1, "w+t"); - } -#endif - livebox_service_init(); - fb_init(disp); - - client_init(use_thread); - - s_info.init_count++; -} - -EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread) -{ - if (s_info.init_count > 0) { - s_info.init_count++; - return LB_STATUS_SUCCESS; - } - - /*! - * \note - * Some application doesn't want to use the environment value. - * So set them using arguments. - */ - s_info.prevent_overwrite = prevent_overwrite; - conf_set_event_filter(event_filter); - - initialize_livebox(disp, use_thread); - return LB_STATUS_SUCCESS; -} - -EAPI int livebox_init(void *disp) -{ - const char *env; - - if (s_info.init_count > 0) { - s_info.init_count++; - return LB_STATUS_SUCCESS; - } - - env = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE"); - if (env && !strcasecmp(env, "true")) { - s_info.prevent_overwrite = 1; - } - - env = getenv("PROVIDER_EVENT_FILTER"); - if (env) { - double event_filter; - if (sscanf(env, "%lf", &event_filter) == 1) { - conf_set_event_filter(event_filter); - } - } - - initialize_livebox(disp, 0); - return LB_STATUS_SUCCESS; -} - -EAPI int livebox_fini(void) -{ - if (s_info.init_count <= 0) { - ErrPrint("Doesn't initialized\n"); - return LB_STATUS_ERROR_INVALID; - } - - s_info.init_count--; - if (s_info.init_count > 0) { - ErrPrint("init count : %d\n", s_info.init_count); - return LB_STATUS_SUCCESS; - } - - client_fini(); - fb_fini(); - livebox_service_fini(); - return LB_STATUS_SUCCESS; -} - -static inline char *lb_pkgname(const char *pkgname) -{ - char *lb; - - lb = livebox_service_pkgname(pkgname); - if (!lb) { - if (util_validate_livebox_package(pkgname) == 0) { - return strdup(pkgname); - } - } - - return lb; -} - -static struct livebox_common *find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category) -{ - struct dlist *l; - struct livebox_common *common; - - if (!conf_shared_content()) { - /*! - * Shared content option is turnned off. - */ - return NULL; - } - - dlist_foreach(s_info.livebox_common_list, l, common) { - if (common->state != CREATE) { - continue; - } - - if (strcmp(common->pkgname, pkgname)) { - continue; - } - - if (strcmp(common->cluster, cluster)) { - DbgPrint("Cluster mismatched\n"); - continue; - } - - if (strcmp(common->category, category)) { - DbgPrint("Category mismatched\n"); - continue; - } - - if (common->content && content) { - if (strcmp(common->content, content)) { - DbgPrint("%s Content ([%s] <> [%s])\n", common->pkgname, common->content, content); - continue; - } - } else { - int c1_len; - int c2_len; - - /*! - * \note - * We assumes "" (ZERO length string) to NULL - */ - c1_len = common->content ? strlen(common->content) : 0; - c2_len = content ? strlen(content) : 0; - if (c1_len != c2_len) { - DbgPrint("%s Content %p <> %p\n", common->pkgname, common->content, content); - continue; - } - } - - if (common->request.size_changed) { - DbgPrint("Changing size\n"); - /*! - * \note - * Do not re-use resizing instance. - * We will not use predicted size. - */ - continue; - } - - if (common->request.created) { - DbgPrint("Creating now but re-use it (%s)\n", common->pkgname); - } - - if (common->lb.width != w || common->lb.height != h) { - DbgPrint("Size mismatched\n"); - continue; - } - - DbgPrint("common handle is found: %p\n", common); - return common; - } - - return NULL; -} - -/*! - * Just wrapping the livebox_add_with_size function. - */ -EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, ret_cb_t cb, void *data) -{ - return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data); -} - -static gboolean job_execute_cb(void *data) -{ - struct job_item *item; - struct dlist *l; - - l = dlist_nth(s_info.job_list, 0); - if (!l) { - s_info.job_timer = 0; - return FALSE; - } - - item = dlist_data(l); - s_info.job_list = dlist_remove(s_info.job_list, l); - - if (item) { - item->cb(item->handle, item->ret, item->data); - lb_unref(item->handle, 1); - free(item); - } - - return TRUE; -} - -static int job_add(struct livebox *handle, ret_cb_t job_cb, int ret, void *data) -{ - struct job_item *item; - - if (!job_cb) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - item = malloc(sizeof(*item)); - if (!item) { - ErrPrint("Heap: %s\n", strerror(errno)); - return LB_STATUS_ERROR_MEMORY; - } - - item->handle = lb_ref(handle); - item->cb = job_cb; - item->data = data; - item->ret = ret; - - s_info.job_list = dlist_append(s_info.job_list, item); - - if (!s_info.job_timer) { - s_info.job_timer = g_timeout_add(1, job_execute_cb, NULL); - if (!s_info.job_timer) { - ErrPrint("Failed to create a job timer\n"); - } - } - - return LB_STATUS_SUCCESS; -} - -static int create_real_instance(struct livebox *handler, ret_cb_t cb, void *data) -{ - struct cb_info *cbinfo; - struct packet *packet; - struct livebox_common *common; - int ret; - - common = handler->common; - - packet = packet_create("new", "dssssdii", - common->timestamp, common->pkgname, common->content, - common->cluster, common->category, - common->lb.period, common->lb.width, common->lb.height); - if (!packet) { - ErrPrint("Failed to create a new packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - ErrPrint("Failed to create a cbinfo\n"); - packet_destroy(packet); - return LB_STATUS_ERROR_MEMORY; - } - - /*! - * \note - * master_rpc_async_request will destroy the packet (decrease the refcnt) - * So be aware the packet object after return from master_rpc_async_request. - */ - ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo); - if (ret < 0) { - ErrPrint("Failed to send a new packet\n"); - destroy_cb_info(cbinfo); - return LB_STATUS_ERROR_FAULT; - } - handler->common->request.created = 1; - return LB_STATUS_SUCCESS; -} - -static void create_cb(struct livebox *handle, int ret, void *data) -{ - struct cb_info *cbinfo = data; - - if (cbinfo->cb) { - cbinfo->cb(handle, ret, cbinfo->data); - } - - destroy_cb_info(cbinfo); - - /*! - * \note - * Forcely generate "updated" event - */ - lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED); -} - -static int create_fake_instance(struct livebox *handler, ret_cb_t cb, void *data) -{ - struct cb_info *cbinfo; - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - ErrPrint("Failed to create a cbinfo\n"); - return LB_STATUS_ERROR_MEMORY; - } - - if (job_add(handler, create_cb, LB_STATUS_SUCCESS, cbinfo) != LB_STATUS_SUCCESS) { - destroy_cb_info(cbinfo); - } - - return LB_STATUS_SUCCESS; -} - -struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category) -{ - struct livebox_common *common; - - common = calloc(1, sizeof(*common)); - if (!common) { - ErrPrint("Heap: %s\n", strerror(errno)); - return NULL; - } - - common->pkgname = strdup(pkgname); - if (!common->pkgname) { - free(common); - return NULL; - } - - common->cluster = strdup(cluster); - if (!common->cluster) { - ErrPrint("Error: %s\n", strerror(errno)); - free(common->pkgname); - free(common); - return NULL; - } - - common->category = strdup(category); - if (!common->category) { - ErrPrint("Error: %s\n", strerror(errno)); - free(common->cluster); - free(common->pkgname); - free(common); - return NULL; - } - - /* Data provider will set this */ - common->lb.type = _LB_TYPE_FILE; - common->pd.type = _PD_TYPE_SCRIPT; - - /* Used for handling the mouse event on a box */ - common->lb.mouse_event = 0; - - /* Cluster infomration is not determined yet */ - common->nr_of_sizes = 0x01; - - common->timestamp = util_timestamp(); - common->is_user = 1; - common->delete_type = LB_DELETE_PERMANENTLY; - common->pd.lock = NULL; - common->pd.lock_fd = -1; - common->lb.lock = NULL; - common->lb.lock_fd = -1; - - common->state = CREATE; - common->visible = LB_SHOW; - - s_info.livebox_common_list = dlist_append(s_info.livebox_common_list, common); - return common; -} - -int lb_destroy_common_handle(struct livebox_common *common) -{ - dlist_remove_data(s_info.livebox_common_list, common); - - common->state = DESTROYED; - - if (common->filename) { - (void)util_unlink(common->filename); - } - - free(common->cluster); - free(common->category); - free(common->id); - free(common->pkgname); - free(common->filename); - free(common->lb.auto_launch); - free(common->alt.icon); - free(common->alt.name); - - if (common->lb.fb) { - fb_destroy(common->lb.fb); - common->lb.fb = NULL; - } - - if (common->pd.fb) { - fb_destroy(common->pd.fb); - common->pd.fb = NULL; - } - - return 0; -} - -int lb_common_ref(struct livebox_common *common, struct livebox *handle) -{ - common->livebox_list = dlist_append(common->livebox_list, handle); - common->refcnt++; - - return common->refcnt; -} - -int lb_common_unref(struct livebox_common *common, struct livebox *handle) -{ - int refcnt; - dlist_remove_data(common->livebox_list, handle); - refcnt = --common->refcnt; - - return refcnt; -} - -static void refresh_for_paused_updating_cb(struct livebox *handle, int ret, void *data) -{ - if (handle->paused_updating == 0) { - DbgPrint("Paused updates are cleared\n"); - return; - } - - DbgPrint("Pending updates are found\n"); - lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED); -} - -static int lb_set_visibility(struct livebox *handler, enum livebox_visible_state state) -{ - struct packet *packet; - int need_to_add_job = 0; - int ret; - - if (handler->common->visible != LB_SHOW && state == LB_SHOW) { - need_to_add_job = !!handler->paused_updating; - } else if (handler->common->visible == LB_SHOW && state != LB_SHOW) { - struct dlist *l; - struct livebox *item; - - dlist_foreach(handler->common->livebox_list, l, item) { - if (item->visible == LB_SHOW) { - DbgPrint("%s visibility is not changed\n", handler->common->pkgname); - return LB_STATUS_SUCCESS; - } - } - } else if (handler->common->visible == LB_SHOW && state == LB_SHOW && handler->paused_updating) { - if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) { - ErrPrint("Unable to add a new job for refreshing box\n"); - } - - return LB_STATUS_SUCCESS; - } else { - /*! - * \brief - * No need to send this to the master - */ - return LB_STATUS_SUCCESS; - } - - packet = packet_create_noack("change,visibility", "ssi", handler->common->pkgname, handler->common->id, (int)state); - if (!packet) { - ErrPrint("Failed to create a packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_request_only(handler, packet); - if (ret == (int)LB_STATUS_SUCCESS) { - DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state); - handler->common->visible = state; - - if (need_to_add_job) { - if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) { - ErrPrint("Unable to add a new job for refreshing box\n"); - } - } - } - - return ret; -} - -EAPI struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data) -{ - char *lbid; - struct livebox *handler; - int w = 0; - int h = 0; - - if (!pkgname || !cluster || !category) { - ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n", - pkgname, cluster, category); - return NULL; - } - - lbid = lb_pkgname(pkgname); - if (!lbid) { - ErrPrint("Invalid package: %s\n", pkgname); - return NULL; - } - - if (livebox_service_is_enabled(lbid) == 0) { - DbgPrint("Livebox [%s](%s) is disabled package\n", lbid, pkgname); - free(lbid); - return NULL; - } - - if (type != LB_SIZE_TYPE_UNKNOWN) { - (void)livebox_service_get_size(type, &w, &h); - } - - handler = calloc(1, sizeof(*handler)); - if (!handler) { - ErrPrint("Error: %s\n", strerror(errno)); - free(lbid); - return NULL; - } - - if (!cb) { - cb = default_create_cb; - } - - handler->common = find_sharable_common_handle(lbid, content, w, h, cluster, category); - if (!handler->common) { - handler->common = lb_create_common_handle(handler, lbid, cluster, category); - free(lbid); - if (!handler->common) { - ErrPrint("Failed to find common handle\n"); - free(handler); - return NULL; - } - - if (!content || !strlen(content)) { - char *pc; - /*! - * \note - * I know the content should not be modified. use it temporarly without "const" - */ - pc = livebox_service_content(handler->common->pkgname); - lb_set_content(handler->common, pc); - free(pc); - } else { - lb_set_content(handler->common, content); - } - - lb_set_period(handler->common, period); - lb_set_size(handler->common, w, h); - lb_common_ref(handler->common, handler); - - if (create_real_instance(handler, cb, data) < 0) { - if (lb_common_unref(handler->common, handler) == 0) { - /*! - * Delete common - */ - lb_destroy_common_handle(handler->common); - handler->common = NULL; - } - free(handler); - return NULL; - } - } else { - free(lbid); - - lb_common_ref(handler->common, handler); - - if (handler->common->request.created) { - /*! - * If a box is in creating, wait its result too - */ - handler->cbs.created.cb = cb; - handler->cbs.created.data = data; - } else { - /*! - * or fire the fake created_event - */ - if (create_fake_instance(handler, cb, data) < 0) { - if (lb_common_unref(handler->common, handler) == 0) { - /*! - * Delete common - */ - lb_destroy_common_handle(handler->common); - } - free(handler); - return NULL; - } - } - } - - handler->visible = LB_SHOW; - handler->state = CREATE; - handler = lb_ref(handler); - - if (handler->common->visible != LB_SHOW) { - lb_set_visibility(handler, LB_SHOW); - } - - return handler; -} - -EAPI double livebox_period(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return 0.0f; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return 0.0f; - } - - if (!handler->common->id) { - ErrPrint("Hnalder is not valid\n"); - return 0.0f; - } - - return handler->common->lb.period; -} - -EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data) -{ - struct packet *packet; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->request.period_changed) { - ErrPrint("Previous request for changing period is not finished\n"); - return LB_STATUS_ERROR_BUSY; - } - - if (!handler->common->is_user) { - ErrPrint("CA Livebox is not able to change the period\n"); - return LB_STATUS_ERROR_PERMISSION; - } - - if (handler->common->lb.period == period) { - DbgPrint("No changes\n"); - return LB_STATUS_ERROR_ALREADY; - } - - packet = packet_create("set_period", "ssd", handler->common->pkgname, handler->common->id, period); - if (!packet) { - ErrPrint("Failed to build a packet %s\n", handler->common->pkgname); - return LB_STATUS_ERROR_FAULT; - } - - if (!cb) { - cb = default_period_changed_cb; - } - - ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.period_changed.cb = cb; - handler->cbs.period_changed.data = data; - handler->common->request.period_changed = 1; - } - - return ret; -} - -static void lb_update_visibility(struct livebox_common *old_common) -{ - struct dlist *l; - struct livebox *item; - - item = NULL; - dlist_foreach(old_common->livebox_list, l, item) { - if (item->visible == LB_SHOW) { - break; - } - - item = NULL; - } - - if (!item) { - l = dlist_nth(old_common->livebox_list, 0); - item = dlist_data(l); - - if (item) { - lb_set_visibility(item, LB_HIDE_WITH_PAUSE); - } else { - ErrPrint("Unable to get the valid handle from common handler\n"); - } - } else { - lb_set_visibility(item, LB_SHOW); - } -} - -/*! - * \note - * The second parameter should be the "return value", - * But in this case, we will use it for "type of deleting instance". - */ -static void job_del_cb(struct livebox *handle, int type, void *data) -{ - struct cb_info *cbinfo = data; - ret_cb_t cb; - - if (handle->visible == LB_SHOW) { - lb_update_visibility(handle->common); - } - - cb = cbinfo->cb; - data = cbinfo->data; - destroy_cb_info(cbinfo); - - if (handle->common->state != CREATE) { - DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt); - if (cb) { - cb(handle, LB_STATUS_SUCCESS, data); - } - - return; - } - - if (handle->common->refcnt == 1) { - handle->common->delete_type = type; - handle->common->state = DELETE; - - if (!handle->common->id) { - /*! - * \note - * The id is not determined yet. - * It means a user didn't receive created event yet. - * Then just stop to delete procedure from here. - * Because the "created" event handle will release this. - * By the way, if the user adds any callback for getting return status of this, - * call it at here. - */ - if (cb) { - cb(handle, LB_STATUS_SUCCESS, data); - } - } - - DbgPrint("Send delete request\n"); - lb_send_delete(handle, type, cb, data); - } else { - if (cb) { - cb(handle, LB_STATUS_SUCCESS, data); - } - - DbgPrint("Before unref: %d\n", handle->common->refcnt); - lb_unref(handle, 1); - } -} - -EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data) -{ - struct cb_info *cbinfo; - - if (!handler) { - ErrPrint("Handler is NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->state != CREATE) { - ErrPrint("Handler is already deleted\n"); - return LB_STATUS_ERROR_INVALID; - } - - handler->state = DELETE; - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - ErrPrint("Failed to create a cbinfo\n"); - return LB_STATUS_ERROR_MEMORY; - } - - if (job_add(handler, job_del_cb, type, cbinfo) != LB_STATUS_SUCCESS) { - ErrPrint("Failed to add a new job\n"); - destroy_cb_info(cbinfo); - return LB_STATUS_ERROR_FAULT; - } - - return LB_STATUS_SUCCESS; -} - -EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data) -{ - return livebox_del_NEW(handler, LB_DELETE_PERMANENTLY, cb, data); -} - -EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data) -{ - struct fault_info *info; - - if (!cb) { - return LB_STATUS_ERROR_INVALID; - } - - info = malloc(sizeof(*info)); - if (!info) { - ErrPrint("Heap: %s\n", strerror(errno)); - return LB_STATUS_ERROR_MEMORY; - } - - info->handler = cb; - info->user_data = data; - info->is_deleted = 0; - - s_info.fault_list = dlist_append(s_info.fault_list, info); - return LB_STATUS_SUCCESS; -} - -EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *)) -{ - struct fault_info *info; - struct dlist *l; - - dlist_foreach(s_info.fault_list, l, info) { - if (info->handler == cb) { - void *data; - - data = info->user_data; - - if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) { - info->is_deleted = 1; - } else { - s_info.fault_list = dlist_remove(s_info.fault_list, l); - free(info); - } - - return data; - } - } - - return NULL; -} - -EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data) -{ - struct event_info *info; - - if (!cb) { - ErrPrint("Invalid argument cb is nil\n"); - return LB_STATUS_ERROR_INVALID; - } - - info = malloc(sizeof(*info)); - if (!info) { - ErrPrint("Heap: %s\n", strerror(errno)); - return LB_STATUS_ERROR_MEMORY; - } - - info->handler = cb; - info->user_data = data; - info->is_deleted = 0; - - s_info.event_list = dlist_append(s_info.event_list, info); - return LB_STATUS_SUCCESS; -} - -EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *)) -{ - struct event_info *info; - struct dlist *l; - - dlist_foreach(s_info.event_list, l, info) { - if (info->handler == cb) { - void *data; - - data = info->user_data; - - if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) { - info->is_deleted = 1; - } else { - s_info.event_list = dlist_remove(s_info.event_list, l); - free(info); - } - - return data; - } - } - - return NULL; -} - -EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data) -{ - struct packet *packet; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is Invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is Invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is Invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->request.update_mode) { - ErrPrint("Previous update_mode cb is not finished yet\n"); - return LB_STATUS_ERROR_BUSY; - } - - if (handler->common->is_active_update == active_update) { - return LB_STATUS_ERROR_ALREADY; - } - - if (!handler->common->is_user) { - return LB_STATUS_ERROR_PERMISSION; - } - - packet = packet_create("update_mode", "ssi", handler->common->pkgname, handler->common->id, active_update); - if (!packet) { - return LB_STATUS_ERROR_FAULT; - } - - if (!cb) { - cb = default_update_mode_cb; - } - - ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.update_mode.cb = cb; - handler->cbs.update_mode.data = data; - handler->common->request.update_mode = 1; - } - - return ret; -} - -EAPI int livebox_is_active_update(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is Invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is Invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - return LB_STATUS_ERROR_INVALID; - } - - return handler->common->is_active_update; -} - -static void resize_job_cb(struct livebox *handler, int ret, void *data) -{ - struct cb_info *info = data; - - if (info->cb) { - info->cb(handler, ret, info->data); - } - - free(info); - - /*! - * \note - * Forcely update the box - */ - lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED); -} - -EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data) -{ - struct livebox_common *common; - int w; - int h; - int ret; - - /*! - * \TODO - * If this handle is host instance or link instance, - * Create a new instance or find another linkable instance. - */ - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - /*! - * \note - * resize operation should be separated by each handler. - * If a handler is resizing, the other handler can request resize too. - * So we should not use the common->request.size_changed flag. - */ - if (handler->cbs.size_changed.cb) { - ErrPrint("Previous resize request is not finished yet\n"); - return LB_STATUS_ERROR_BUSY; - } - - if (livebox_service_get_size(type, &w, &h) != 0) { - ErrPrint("Invalid size type\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->lb.width == w && handler->common->lb.height == h) { - DbgPrint("No changes\n"); - return LB_STATUS_ERROR_ALREADY; - } - - if (!handler->common->is_user) { - ErrPrint("CA Livebox is not able to be resized\n"); - return LB_STATUS_ERROR_PERMISSION; - } - - if (handler->common->refcnt <= 1) { - struct packet *packet; - - /* Only 1 instance */ - packet = packet_create("resize", "ssii", handler->common->pkgname, handler->common->id, w, h); - if (!packet) { - ErrPrint("Failed to build param\n"); - return LB_STATUS_ERROR_FAULT; - } - - if (!cb) { - cb = default_lb_size_changed_cb; - } - - ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.size_changed.cb = cb; - handler->cbs.size_changed.data = data; - handler->common->request.size_changed = 1; - } - } else { - common = find_sharable_common_handle(handler->common->pkgname, handler->common->content, w, h, handler->common->cluster, handler->common->category); - if (!common) { - struct livebox_common *old_common; - /*! - * \note - * If the common handler is in resizing, - * if user tries to resize a hander, then simply create new one even if the requested size is same with this. - - if (handler->common->request.size_changed) { - } - - */ - - old_common = handler->common; - - common = lb_create_common_handle(handler, old_common->pkgname, old_common->cluster, old_common->category); - if (!common) { - ErrPrint("Failed to create common handle\n"); - return LB_STATUS_ERROR_FAULT; - } - - lb_set_size(common, w, h); - lb_set_content(common, old_common->content); - lb_set_period(common, old_common->lb.period); - - /*! - * \note - * Disconnecting from old one. - */ - if (lb_common_unref(old_common, handler) == 0) { - /*! - * \note - * Impossible - */ - ErrPrint("Common has no associated handler\n"); - } - - lb_common_ref(common, handler); - - /*! - * Connect to a new one - */ - handler->common = common; - - /*! - * \TODO - * Need to care, if it fails to create a common handle, - * the resize operation will be failed. - * in that case, we should reuse the old common handle - */ - ret = create_real_instance(handler, cb, data); - if (ret < 0) { - lb_common_unref(common, handler); - lb_destroy_common_handle(common); - - lb_common_ref(old_common, handler); - handler->common = old_common; - } else { - /*! - * In this case, we should update visibility of old_common's liveboxes - */ - if (handler->visible == LB_SHOW) { - lb_update_visibility(old_common); - } - } - } else { - struct cb_info *cbinfo; - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - ErrPrint("Failed to create a cbinfo\n"); - ret = LB_STATUS_ERROR_MEMORY; - } else { - ret = job_add(handler, resize_job_cb, LB_STATUS_SUCCESS, cbinfo); - if (ret == (int)LB_STATUS_SUCCESS) { - struct livebox_common *old_common; - - old_common = handler->common; - - if (lb_common_unref(handler->common, handler) == 0) { - ErrPrint("Old common has no associated handler\n"); - } - - lb_common_ref(common, handler); - handler->common = common; - - if (handler->visible == LB_SHOW) { - lb_update_visibility(old_common); /* To update visibility: Show --> Paused */ - lb_update_visibility(common); /* To update visibility: Paused --> Show */ - } - } else { - destroy_cb_info(cbinfo); - } - } - } - } - - return ret; -} - -EAPI int livebox_click(struct livebox *handler, double x, double y) -{ - struct packet *packet; - double timestamp; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->lb.auto_launch) { - if (s_info.launch.handler) { - ret = s_info.launch.handler(handler, handler->common->lb.auto_launch, s_info.launch.data); - if (ret < 0) { - ErrPrint("launch handler app %s (%d)\n", handler->common->lb.auto_launch, ret); - } - } - } - - timestamp = util_timestamp(); - DbgPrint("CLICKED: %lf\n", timestamp); - - packet = packet_create_noack("clicked", "sssddd", handler->common->pkgname, handler->common->id, "clicked", timestamp, x, y); - if (!packet) { - ErrPrint("Failed to build param\n"); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_request_only(handler, packet); - - if (!handler->common->lb.mouse_event && (handler->common->lb.type == _LB_TYPE_BUFFER || handler->common->lb.type == _LB_TYPE_SCRIPT)) { - int ret; /* Shadow variable */ - ret = send_mouse_event(handler, "lb_mouse_down", x * handler->common->lb.width, y * handler->common->lb.height); - if (ret < 0) { - ErrPrint("Failed to send Down: %d\n", ret); - } - - ret = send_mouse_event(handler, "lb_mouse_move", x * handler->common->lb.width, y * handler->common->lb.height); - if (ret < 0) { - ErrPrint("Failed to send Move: %d\n", ret); - } - - ret = send_mouse_event(handler, "lb_mouse_up", x * handler->common->lb.width, y * handler->common->lb.height); - if (ret < 0) { - ErrPrint("Failed to send Up: %d\n", ret); - } - } - - return ret; -} - -EAPI int livebox_has_pd(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - return !!handler->common->pd.fb; -} - -EAPI int livebox_pd_is_created(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->pd.fb || !handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - return handler->common->is_pd_created; -} - -EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data) -{ - return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data); -} - -static void turn_off_pd_destroyed_flag_cb(struct livebox *handler, int ret, void *data) -{ - if (handler->common->request.pd_destroyed) { - ret_cb_t cb; - void *data; - - DbgPrint("pd_destroyed request is canceled\n"); - handler->common->request.pd_destroyed = 0; - cb = handler->cbs.pd_destroyed.cb; - data = handler->cbs.pd_destroyed.data; - handler->cbs.pd_destroyed.cb = NULL; - handler->cbs.pd_destroyed.data = NULL; - - if (cb) { - cb(handler, ret, data); - } - } -} - -EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data) -{ - struct packet *packet; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->pd.fb || !handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - /*! - * \note - * Only one handler can have a PD - */ - if (handler->common->is_pd_created) { - DbgPrint("PD is already created\n"); - return LB_STATUS_SUCCESS; - } - - if (handler->common->request.pd_created) { - ErrPrint("Previous request is not completed yet\n"); - return LB_STATUS_ERROR_BUSY; - } - - /*! - * \note - * Turn off the pd_destroyed request flag - */ - if (handler->common->request.pd_destroyed) { - if (job_add(handler, turn_off_pd_destroyed_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) { - ErrPrint("Failed to add pd_destroyed job\n"); - } - } - - packet = packet_create("create_pd", "ssdd", handler->common->pkgname, handler->common->id, x, y); - if (!packet) { - ErrPrint("Failed to build param\n"); - return LB_STATUS_ERROR_FAULT; - } - - if (!cb) { - cb = default_pd_created_cb; - } - - DbgPrint("PERF_DBOX\n"); - ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.pd_created.cb = cb; - handler->cbs.pd_created.data = data; - handler->common->request.pd_created = 1; - } - - return ret; -} - -EAPI int livebox_move_pd(struct livebox *handler, double x, double y) -{ - struct packet *packet; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->pd.fb || !handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->is_pd_created) { - ErrPrint("PD is not created\n"); - return LB_STATUS_ERROR_INVALID; - } - - packet = packet_create_noack("pd_move", "ssdd", handler->common->pkgname, handler->common->id, x, y); - if (!packet) { - ErrPrint("Failed to build param\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(handler, packet); -} - -EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - int ret; - - if (!pkgname) { - return LB_STATUS_ERROR_INVALID; - } - - packet = packet_create("activate_package", "s", pkgname); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - ErrPrint("Unable to create cbinfo\n"); - packet_destroy(packet); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo); - if (ret < 0) { - destroy_cb_info(cbinfo); - } - - return ret; -} - -static void turn_off_pd_created_flag_cb(struct livebox *handler, int ret, void *data) -{ - if (handler->common->request.pd_created) { - ret_cb_t cb; - void *data; - - DbgPrint("pd_created request is canceled\n"); - handler->common->request.pd_created = 0; - cb = handler->cbs.pd_created.cb; - data = handler->cbs.pd_created.data; - handler->cbs.pd_created.cb = NULL; - handler->cbs.pd_created.data = NULL; - - if (cb) { - cb(handler, ret, data); - } - } -} - -EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->pd.fb || !handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - /*! - * \FIXME - * Replace the callback check code. - * Use the flag instead of callback. - * the flag should be in the ADT "common" - */ - if (!handler->common->is_pd_created && !handler->common->request.pd_created) { - ErrPrint("PD is not created\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->request.pd_destroyed) { - ErrPrint("PD destroy request is already sent\n"); - return LB_STATUS_ERROR_ALREADY; - } - - /*! - * \note - * Disable the pd_created request flag - */ - if (handler->common->request.pd_created) { - if (job_add(handler, turn_off_pd_created_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) { - ErrPrint("Failed to add a new job\n"); - } - } - - DbgPrint("[%s]\n", handler->common->pkgname); - - packet = packet_create("destroy_pd", "ss", handler->common->pkgname, handler->common->id); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - if (!cb) { - cb = default_pd_destroyed_cb; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - packet_destroy(packet); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo); - if (ret < 0) { - destroy_cb_info(cbinfo); - } else { - handler->common->request.pd_destroyed = 1; - } - - return ret; -} - -EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data) -{ - int w = 1; - int h = 1; - char cmd[32] = { '\0', }; - char *ptr = cmd; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->request.access_event) { - ErrPrint("Previous access event is not yet done\n"); - return LB_STATUS_ERROR_BUSY; - } - - if (type & ACCESS_EVENT_PD_MASK) { - if (!handler->common->is_pd_created) { - ErrPrint("PD is not created\n"); - return LB_STATUS_ERROR_INVALID; - } - *ptr++ = 'p'; - *ptr++ = 'd'; - w = handler->common->pd.width; - h = handler->common->pd.height; - } else if (type & ACCESS_EVENT_LB_MASK) { - *ptr++ = 'l'; - *ptr++ = 'b'; - w = handler->common->lb.width; - h = handler->common->lb.height; - } else { - ErrPrint("Invalid event type\n"); - return LB_STATUS_ERROR_INVALID; - } - - switch (type & ~ACCESS_EVENT_PD_MASK) { - case ACCESS_EVENT_HIGHLIGHT: - strcpy(ptr, "_access_hl"); - break; - case ACCESS_EVENT_HIGHLIGHT_NEXT: - strcpy(ptr, "_access_hl_next"); - break; - case ACCESS_EVENT_HIGHLIGHT_PREV: - strcpy(ptr, "_access_hl_prev"); - break; - case ACCESS_EVENT_ACTIVATE: - strcpy(ptr, "_access_activate"); - break; - case ACCESS_EVENT_ACTION_DOWN: - strcpy(ptr, "_access_action_down"); - break; - case ACCESS_EVENT_ACTION_UP: - strcpy(ptr, "_access_action_up"); - break; - case ACCESS_EVENT_UNHIGHLIGHT: - strcpy(ptr, "_access_unhighlight"); - break; - case ACCESS_EVENT_SCROLL_DOWN: - strcpy(ptr, "_access_scroll_down"); - break; - case ACCESS_EVENT_SCROLL_MOVE: - strcpy(ptr, "_access_scroll_move"); - break; - case ACCESS_EVENT_SCROLL_UP: - strcpy(ptr, "_access_scroll_up"); - break; - default: - return LB_STATUS_ERROR_INVALID; - } - - if (!cb) { - cb = default_access_event_cb; - } - - ret = send_access_event(handler, cmd, x * w, y * h); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.access_event.cb = cb; - handler->cbs.access_event.data = data; - handler->common->request.access_event = 1; - } - - return ret; -} - -EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y) -{ - return livebox_mouse_event(handler, type, x, y); -} - -EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y) -{ - int w = 1; - int h = 1; - char cmd[32] = { '\0', }; - char *ptr = cmd; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!(type & CONTENT_EVENT_MOUSE_MASK)) { - ErrPrint("Invalid content event is used\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (type & CONTENT_EVENT_PD_MASK) { - int flag = 1; - - if (!handler->common->is_pd_created) { - ErrPrint("PD is not created\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->pd.fb) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (type & CONTENT_EVENT_MOUSE_MOVE) { - if (fabs(x - handler->common->pd.x) < conf_event_filter() && fabs(y - handler->common->pd.y) < conf_event_filter()) { - return LB_STATUS_ERROR_BUSY; - } - } else if (type & CONTENT_EVENT_MOUSE_SET) { - flag = 0; - } - - if (flag) { - w = handler->common->pd.width; - h = handler->common->pd.height; - handler->common->pd.x = x; - handler->common->pd.y = y; - } - *ptr++ = 'p'; - *ptr++ = 'd'; - } else if (type & CONTENT_EVENT_LB_MASK) { - int flag = 1; - - if (!handler->common->lb.mouse_event) { - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->lb.fb) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (type & CONTENT_EVENT_MOUSE_MOVE) { - if (fabs(x - handler->common->lb.x) < conf_event_filter() && fabs(y - handler->common->lb.y) < conf_event_filter()) { - return LB_STATUS_ERROR_BUSY; - } - } else if (type & CONTENT_EVENT_MOUSE_SET) { - flag = 0; - } - - if (flag) { - w = handler->common->lb.width; - h = handler->common->lb.height; - handler->common->lb.x = x; - handler->common->lb.y = y; - } - *ptr++ = 'l'; - *ptr++ = 'b'; - } else { - ErrPrint("Invalid event type\n"); - return LB_STATUS_ERROR_INVALID; - } - - /*! - * Must be shorter than 29 bytes. - */ - switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) { - case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_enter"); - break; - case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_leave"); - break; - case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_up"); - break; - case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_down"); - break; - case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_move"); - break; - case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_set"); - break; - case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_unset"); - break; - case CONTENT_EVENT_ON_SCROLL | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_on_scroll"); - break; - case CONTENT_EVENT_ON_HOLD | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_on_hold"); - break; - case CONTENT_EVENT_OFF_SCROLL | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_off_scroll"); - break; - case CONTENT_EVENT_OFF_HOLD | CONTENT_EVENT_MOUSE_MASK: - strcpy(ptr, "_mouse_off_hold"); - break; - default: - ErrPrint("Invalid event type\n"); - return LB_STATUS_ERROR_INVALID; - } - - return send_mouse_event(handler, cmd, x * w, y * h); -} - -EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data) -{ - char cmd[32] = { '\0', }; - char *ptr = cmd; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!(type & CONTENT_EVENT_KEY_MASK)) { - ErrPrint("Invalid key event is used\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->request.key_event) { - ErrPrint("Previous key event is not completed yet\n"); - return LB_STATUS_ERROR_BUSY; - } - - if (type & CONTENT_EVENT_PD_MASK) { - if (!handler->common->is_pd_created) { - ErrPrint("PD is not created\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->pd.fb) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (type & CONTENT_EVENT_KEY_DOWN) { - /*! - * \TODO - * filtering the reproduced events if it is too fast - */ - } else if (type & CONTENT_EVENT_KEY_SET) { - /*! - * \TODO - * What can I do for this case? - */ - } - - *ptr++ = 'p'; - *ptr++ = 'd'; - } else if (type & CONTENT_EVENT_LB_MASK) { - if (!handler->common->lb.mouse_event) { - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->lb.fb) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (type & CONTENT_EVENT_KEY_DOWN) { - /*! - * \TODO - * filtering the reproduced events if it is too fast - */ - } else if (type & CONTENT_EVENT_KEY_SET) { - /*! - * What can I do for this case? - */ - } - - *ptr++ = 'l'; - *ptr++ = 'b'; - } else { - ErrPrint("Invalid event type\n"); - return LB_STATUS_ERROR_INVALID; - } - - /*! - * Must be short than 29 bytes. - */ - switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) { - case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK: - strcpy(ptr, "_key_focus_in"); - break; - case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK: - strcpy(ptr, "_key_focus_out"); - break; - case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK: - strcpy(ptr, "_key_up"); - break; - case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK: - strcpy(ptr, "_key_down"); - break; - case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK: - strcpy(ptr, "_key_set"); - break; - case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK: - strcpy(ptr, "_key_unset"); - break; - default: - ErrPrint("Invalid event type\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!cb) { - cb = default_key_event_cb; - } - - ret = send_key_event(handler, cmd, keycode); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.key_event.cb = cb; - handler->cbs.key_event.data = data; - handler->common->request.key_event = 1; - } - - return ret; -} - -EAPI const char *livebox_filename(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return NULL; - } - - if (handler->common->filename) { - return handler->common->filename; - } - - /* Oooops */ - return util_uri_to_path(handler->common->id); -} - -EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h) -{ - int _w; - int _h; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!w) { - w = &_w; - } - if (!h) { - h = &_h; - } - - if (!handler->common->is_pd_created) { - *w = handler->common->pd.default_width; - *h = handler->common->pd.default_height; - } else { - *w = handler->common->pd.width; - *h = handler->common->pd.height; - } - - return LB_STATUS_SUCCESS; -} - -EAPI int livebox_size(struct livebox *handler) -{ - int w; - int h; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - w = handler->common->lb.width; - h = handler->common->lb.height; - - switch (handler->common->lb.type) { - case _LB_TYPE_BUFFER: - case _LB_TYPE_SCRIPT: - if (!fb_is_created(handler->common->lb.fb)) { - w = 0; - h = 0; - } - break; - default: - break; - } - - return livebox_service_size_type(w, h); -} - -EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data) -{ - struct packet *packet; - int ret; - - if (!handler) { - ErrPrint("Handler is NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!cluster || !category || handler->state != CREATE) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->request.group_changed) { - ErrPrint("Previous group changing request is not finished yet\n"); - return LB_STATUS_ERROR_BUSY; - } - - if (!handler->common->is_user) { - ErrPrint("CA Livebox is not able to change the group\n"); - return LB_STATUS_ERROR_PERMISSION; - } - - if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) { - DbgPrint("No changes\n"); - return LB_STATUS_ERROR_ALREADY; - } - - packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - if (!cb) { - cb = default_group_changed_cb; - } - - ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.group_changed.cb = cb; - handler->cbs.group_changed.data = data; - handler->common->request.group_changed = 1; - } - - return ret; -} - -EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category) -{ - if (!handler) { - ErrPrint("Handler is NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!cluster || !category || handler->state != CREATE) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - *cluster = handler->common->cluster; - *category = handler->common->category; - return LB_STATUS_SUCCESS; -} - -EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list) -{ - register int i; - register int j; - - if (!handler || !size_list) { - ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list); - return LB_STATUS_ERROR_INVALID; - } - - if (!cnt || handler->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - for (j = i = 0; i < NR_OF_SIZE_LIST; i++) { - if (handler->common->lb.size_list & (0x01 << i)) { - if (j == *cnt) { - break; - } - - size_list[j++] = (0x01 << i); - } - } - - *cnt = j; - return LB_STATUS_SUCCESS; -} - -EAPI const char *livebox_pkgname(struct livebox *handler) -{ - if (!handler) { - ErrPrint("Handler is NIL\n"); - return NULL; - } - - if (handler->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return NULL; - } - - return handler->common->pkgname; -} - -EAPI double livebox_priority(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return -1.0f; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return -1.0f; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid (%p)\n", handler); - return -1.0f; - } - - return handler->common->lb.priority; -} - -EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - int ret; - - packet = packet_create("delete_cluster", "s", cluster); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - packet_destroy(packet); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo); - if (ret < 0) { - destroy_cb_info(cbinfo); - } - - return ret; -} - -EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - int ret; - - packet = packet_create("delete_category", "ss", cluster, category); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - packet_destroy(packet); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo); - if (ret < 0) { - destroy_cb_info(cbinfo); - } - - return ret; -} - -EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_TYPE_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_TYPE_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_TYPE_INVALID; - } - - switch (handler->common->lb.type) { - case _LB_TYPE_FILE: - return LB_TYPE_IMAGE; - case _LB_TYPE_BUFFER: - case _LB_TYPE_SCRIPT: - { - const char *id; - id = fb_id(handler->common->lb.fb); - if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - return LB_TYPE_PIXMAP; - } - } - return LB_TYPE_BUFFER; - case _LB_TYPE_TEXT: - return LB_TYPE_TEXT; - default: - break; - } - - return LB_TYPE_INVALID; -} - -EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return PD_TYPE_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return PD_TYPE_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return PD_TYPE_INVALID; - } - - switch (handler->common->pd.type) { - case _PD_TYPE_TEXT: - return PD_TYPE_TEXT; - case _PD_TYPE_BUFFER: - case _PD_TYPE_SCRIPT: - { - const char *id; - id = fb_id(handler->common->pd.fb); - if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) { - return PD_TYPE_PIXMAP; - } - } - return PD_TYPE_BUFFER; - default: - break; - } - - return PD_TYPE_INVALID; -} - -EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops) -{ - if (!handler) { - ErrPrint("Handler is NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops)); - return LB_STATUS_SUCCESS; -} - -EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops) -{ - if (!handler) { - ErrPrint("Handler is NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops)); - return LB_STATUS_SUCCESS; -} - -EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) { - ErrPrint("Handler is not valid type\n"); - return LB_STATUS_ERROR_INVALID; - } - - return lb_acquire_lb_pixmap(handler, cb, data); -} - -/*! - * \note - * Do not check the state of handler and common-handler. - * If this function is used in the deleted callback, - * the handler and common-handler's state would be DELETE - * if this function check the state of handles, - * user cannot release the pixmap. - */ -EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap) -{ - struct packet *packet; - const char *pkgname; - const char *id; - - if (pixmap == 0 /* || handler->state != CREATE */ ) { - ErrPrint("Handler is invalid [%d]\n", pixmap); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler) { - /*! - * \note - * Even though the handler is NULL, we should send the release request to the master. - * Because the pixmap resource can be released after the handler is destroyed. - * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap. - * In some cases, the pixmap can be released after the handler is deleted. - * - * Its implementation is up to the viewer app. - * But we cannot force it to use only with valid handler. - */ - DbgPrint("Using NULL handler\n"); - pkgname = NULL; - id = NULL; - /*! - * \note - * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid. - */ - } else { - if (!handler->common /* || handler->common->state != CREATE */) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) { - ErrPrint("Handler is not valid type\n"); - return LB_STATUS_ERROR_INVALID; - } - - pkgname = handler->common->pkgname; - id = handler->common->id; - } - - packet = packet_create_noack("lb_release_pixmap", "ssi", pkgname, id, pixmap); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_INVALID; - } - - return master_rpc_request_only(handler, packet); -} - -EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) { - ErrPrint("Handler is not valid type\n"); - return LB_STATUS_ERROR_INVALID; - } - - return lb_acquire_pd_pixmap(handler, cb, data); -} - -EAPI int livebox_pd_pixmap(const struct livebox *handler) -{ - const char *id; - int pixmap = 0; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return 0; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return 0; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return 0; - } - - if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) { - ErrPrint("Invalid handler\n"); - return 0; - } - - id = fb_id(handler->common->pd.fb); - if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) { - ErrPrint("PIXMAP Id is not valid\n"); - return 0; - } - - return pixmap; -} - -EAPI int livebox_lb_pixmap(const struct livebox *handler) -{ - const char *id; - int pixmap = 0; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return 0; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return 0; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return 0; - } - - if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) { - ErrPrint("Invalid handler\n"); - return 0; - } - - id = fb_id(handler->common->lb.fb); - if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) { - ErrPrint("PIXMAP Id is not valid\n"); - return 0; - } - - return pixmap; -} - -/*! - * \note - * Do not check the state of handler and common-handler. - * If this function is used in the deleted callback, - * the handler and common-handler's state would be DELETE - * if this function check the state of handles, - * user cannot release the pixmap. - */ -EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap) -{ - struct packet *packet; - const char *pkgname; - const char *id; - - if (pixmap == 0 /* || handler->state != CREATE */) { - ErrPrint("Pixmap is invalid [%d]\n", pixmap); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler) { - /*! - * \note - * Even though the handler is NULL, we should send the release request to the master. - * Because the pixmap resource can be released after the handler is destroyed. - * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap. - * In some cases, the pixmap can be released after the handler is deleted. - * - * Its implementation is up to the viewer app. - * But we cannot force it to use only with valid handler. - */ - DbgPrint("Using NULL handler\n"); - pkgname = NULL; - id = NULL; - /*! - * \note - * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid. - */ - } else { - if (!handler->common /* || handler-common->state != CREATE */) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) { - ErrPrint("Handler is not valid type\n"); - return LB_STATUS_ERROR_INVALID; - } - - pkgname = handler->common->pkgname; - id = handler->common->id; - } - - packet = packet_create_noack("pd_release_pixmap", "ssi", pkgname, id, pixmap); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(handler, packet); -} - -EAPI void *livebox_acquire_fb(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common->id) { - ErrPrint("Invalid handle\n"); - return NULL; - } - - if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) { - ErrPrint("Handler is not valid type\n"); - return NULL; - } - - return fb_acquire_buffer(handler->common->lb.fb); -} - -EAPI int livebox_release_fb(void *buffer) -{ - return fb_release_buffer(buffer); -} - -EAPI int livebox_fb_refcnt(void *buffer) -{ - return fb_refcnt(buffer); -} - -EAPI void *livebox_acquire_pdfb(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return NULL; - } - - if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) { - ErrPrint("Handler is not valid type\n"); - return NULL; - } - - return fb_acquire_buffer(handler->common->pd.fb); -} - -EAPI int livebox_release_pdfb(void *buffer) -{ - return fb_release_buffer(buffer); -} - -EAPI int livebox_pdfb_refcnt(void *buffer) -{ - return fb_refcnt(buffer); -} - -EAPI int livebox_pdfb_bufsz(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return LB_STATUS_ERROR_INVALID; - } - - return fb_size(handler->common->pd.fb); -} - -EAPI int livebox_lbfb_bufsz(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return LB_STATUS_ERROR_INVALID; - } - - return fb_size(handler->common->lb.fb); -} - -EAPI int livebox_is_user(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return LB_STATUS_ERROR_INVALID; - } - - return handler->common->is_user; -} - -EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data) -{ - struct packet *packet; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->common->request.pinup) { - ErrPrint("Previous pinup request is not finished\n"); - return LB_STATUS_ERROR_BUSY; - } - - if (handler->common->is_pinned_up == flag) { - DbgPrint("No changes\n"); - return LB_STATUS_ERROR_ALREADY; - } - - packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - if (!cb) { - cb = default_pinup_cb; - } - - ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL); - if (ret == (int)LB_STATUS_SUCCESS) { - handler->cbs.pinup.cb = cb; - handler->cbs.pinup.data = data; - handler->common->request.pinup = 1; - } - - return ret; -} - -EAPI int livebox_is_pinned_up(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return LB_STATUS_ERROR_INVALID; - } - - return handler->common->is_pinned_up; -} - -EAPI int livebox_has_pinup(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handler\n"); - return LB_STATUS_ERROR_INVALID; - } - - return handler->common->lb.pinup_supported; -} - -EAPI int livebox_set_data(struct livebox *handler, void *data) -{ - if (!handler) { - ErrPrint("Handler is NIL\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - handler->data = data; - return LB_STATUS_SUCCESS; -} - -EAPI void *livebox_get_data(struct livebox *handler) -{ - if (!handler) { - ErrPrint("Handler is NIL\n"); - return NULL; - } - - if (handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - return handler->data; -} - -EAPI int livebox_is_exists(const char *pkgname) -{ - char *lb; - - lb = lb_pkgname(pkgname); - if (lb) { - free(lb); - return 1; - } - - return 0; -} - -EAPI const char *livebox_content(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return NULL; - } - - return handler->common->content; -} - -EAPI const char *livebox_category_title(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return NULL; - } - - return handler->common->title; -} - -EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!emission) { - emission = ""; - } - - if (!source) { - source = ""; - } - - packet = packet_create("text_signal", "ssssdddd", - handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey); - if (!packet) { - ErrPrint("Failed to build a param\n"); - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - packet_destroy(packet); - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo); - if (ret < 0) { - destroy_cb_info(cbinfo); - } - - return ret; -} - -EAPI int livebox_subscribe_group(const char *cluster, const char *category) -{ - struct packet *packet; - - /*! - * \todo - * Validate the group info using DB - * If the group info is not valid, do not send this request - */ - - packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : ""); - if (!packet) { - ErrPrint("Failed to create a packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(NULL, packet); -} - -EAPI int livebox_unsubscribe_group(const char *cluster, const char *category) -{ - struct packet *packet; - - /*! - * \todo - * Validate the group info using DB - * If the group info is not valid, do not send this request - * AND Check the subscribed or not too - */ - - packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : ""); - if (!packet) { - ErrPrint("Failed to create a packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(NULL, packet); -} - -EAPI int livebox_refresh(struct livebox *handler, int force) -{ - struct packet *packet; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force); - if (!packet) { - ErrPrint("Failed to create a packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(handler, packet); -} - -EAPI int livebox_refresh_group(const char *cluster, const char *category, int force) -{ - struct packet *packet; - - if (!cluster || !category) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - packet = packet_create_noack("refresh_group", "ssi", cluster, category, force); - if (!packet) { - ErrPrint("Failed to create a packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(NULL, packet); -} - -EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state) -{ - int old_state; - int ret; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->is_user) { - /* System cluster livebox cannot be changed its visible states */ - if (state == LB_HIDE_WITH_PAUSE) { - ErrPrint("CA Livebox is not able to change the visibility\n"); - return LB_STATUS_ERROR_PERMISSION; - } - } - - if (handler->visible == state) { - DbgPrint("%s has no changes\n", handler->common->pkgname); - return LB_STATUS_ERROR_ALREADY; - } - - old_state = handler->visible; - handler->visible = state; - - ret = lb_set_visibility(handler, state); - if (ret < 0) { - handler->visible = old_state; - } - - return ret; -} - -EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is invalid\n"); - return LB_VISIBLE_ERROR; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_VISIBLE_ERROR; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid\n"); - return LB_VISIBLE_ERROR; - } - - return handler->visible; -} - -int lb_set_group(struct livebox_common *common, const char *cluster, const char *category) -{ - void *pc = NULL; - void *ps = NULL; - - if (cluster) { - pc = strdup(cluster); - if (!pc) { - ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster); - return LB_STATUS_ERROR_MEMORY; - } - } - - if (category) { - ps = strdup(category); - if (!ps) { - ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category); - free(pc); - return LB_STATUS_ERROR_MEMORY; - } - } - - if (common->cluster) { - free(common->cluster); - } - - if (common->category) { - free(common->category); - } - - common->cluster = pc; - common->category = ps; - - return LB_STATUS_SUCCESS; -} - -void lb_set_size(struct livebox_common *common, int w, int h) -{ - int size_type; - - common->lb.width = w; - common->lb.height = h; - - size_type = livebox_service_size_type(w, h); - if (size_type != LB_SIZE_TYPE_UNKNOWN) { - common->lb.mouse_event = livebox_service_mouse_event(common->pkgname, size_type); - } -} - -void lb_set_update_mode(struct livebox_common *common, int active_mode) -{ - common->is_active_update = active_mode; -} - -void lb_set_pdsize(struct livebox_common *common, int w, int h) -{ - common->pd.width = w; - common->pd.height = h; -} - -void lb_set_default_pdsize(struct livebox_common *common, int w, int h) -{ - common->pd.default_width = w; - common->pd.default_height = h; -} - -void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func) -{ - struct dlist *l; - struct dlist *n; - struct fault_info *info; - - s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING; - - dlist_foreach_safe(s_info.fault_list, l, n, info) { - if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) { - info->is_deleted = 1; - } - - if (info->is_deleted) { - s_info.fault_list = dlist_remove(s_info.fault_list, l); - free(info); - } - } - - s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING; -} - -void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event) -{ - struct dlist *l; - struct dlist *n; - struct event_info *info; - - if (event == LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) { - if (handler->visible != LB_SHOW) { - DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname); - handler->paused_updating++; - return; - } else { - handler->paused_updating = 0; - } - } - - s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING; - - dlist_foreach_safe(s_info.event_list, l, n, info) { - if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) { - DbgPrint("Event handler returns EXIT_FAILURE\n"); - info->is_deleted = 1; - } - - if (info->is_deleted) { - s_info.event_list = dlist_remove(s_info.event_list, l); - free(info); - } - } - - s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING; -} - -struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id) -{ - struct dlist *l; - struct livebox_common *common; - - dlist_foreach(s_info.livebox_common_list, l, common) { - if (!common->id) { - continue; - } - - if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) { - return common; - } - } - - return NULL; -} - -struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp) -{ - struct dlist *l; - struct livebox_common *common; - - dlist_foreach(s_info.livebox_common_list, l, common) { - if (common->timestamp == timestamp) { - return common; - } - } - - return NULL; -} - -struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category) -{ - struct livebox *handler; - - handler = calloc(1, sizeof(*handler)); - if (!handler) { - ErrPrint("Failed to create a new livebox\n"); - return NULL; - } - - handler->common = lb_create_common_handle(handler, pkgname, cluster, category); - if (!handler->common) { - ErrPrint("Heap: %s\n", strerror(errno)); - free(handler); - return NULL; - } - - lb_common_ref(handler->common, handler); - lb_set_id(handler->common, id); - handler->common->timestamp = timestamp; - handler->common->state = CREATE; - handler->visible = LB_SHOW; - s_info.livebox_list = dlist_append(s_info.livebox_list, handler); - - return lb_ref(handler); -} - -int lb_delete_all(void) -{ - struct dlist *l; - struct dlist *n; - struct livebox *handler; - - dlist_foreach_safe(s_info.livebox_list, l, n, handler) { - lb_invoke_event_handler(handler, LB_EVENT_DELETED); - lb_unref(handler, 1); - } - - return LB_STATUS_SUCCESS; -} - -int lb_set_content(struct livebox_common *common, const char *content) -{ - char *pc = NULL; - - if (content) { - pc = strdup(content); - if (!pc) { - ErrPrint("heap: %s [%s]\n", strerror(errno), content); - return LB_STATUS_ERROR_MEMORY; - } - } - - free(common->content); - common->content = pc; - return LB_STATUS_SUCCESS; -} - -int lb_set_title(struct livebox_common *common, const char *title) -{ - char *pt = NULL; - - if (title) { - pt = strdup(title); - if (!pt) { - ErrPrint("heap: %s [%s]\n", strerror(errno), title); - return LB_STATUS_ERROR_MEMORY; - } - } - - free(common->title); - common->title = pt; - return LB_STATUS_SUCCESS; -} - -void lb_set_size_list(struct livebox_common *common, int size_list) -{ - common->lb.size_list = size_list; -} - -void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch) -{ - char *pa = NULL; - - if (!auto_launch || !strlen(auto_launch)) { - return; - } - - pa = strdup(auto_launch); - if (!pa) { - ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch); - return; - } - - free(common->lb.auto_launch); - common->lb.auto_launch = pa; -} - -void lb_set_priority(struct livebox_common *common, double priority) -{ - common->lb.priority = priority; -} - -void lb_set_id(struct livebox_common *common, const char *id) -{ - char *pi = NULL; - - if (id) { - pi = strdup(id); - if (!pi) { - ErrPrint("heap: %s [%s]\n", strerror(errno), pi); - return; - } - } - - free(common->id); - common->id = pi; -} - -void lb_set_filename(struct livebox_common *common, const char *filename) -{ - if (common->filename) { - if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) { - if (common->filename[0] && unlink(common->filename) < 0) { - ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename); - } - } - - free(common->filename); - } - - common->filename = strdup(filename); - if (!common->filename) { - ErrPrint("Heap: %s\n", strerror(errno)); - } -} - -void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name) -{ - char *_icon = NULL; - char *_name = NULL; - - if (icon && strlen(icon)) { - _icon = strdup(icon); - if (!_icon) { - ErrPrint("Heap: %s\n", strerror(errno)); - } - } - - if (name && strlen(name)) { - _name = strdup(name); - if (!_name) { - ErrPrint("Heap: %s\n", strerror(errno)); - } - } - - free(common->alt.icon); - common->alt.icon = _icon; - - free(common->alt.name); - common->alt.name = _name; -} - -int lb_set_lb_fb(struct livebox_common *common, const char *filename) -{ - struct fb_info *fb; - - if (!common) { - return LB_STATUS_ERROR_INVALID; - } - - fb = common->lb.fb; - if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */ - return LB_STATUS_SUCCESS; - } - - common->lb.fb = NULL; - - if (!filename || filename[0] == '\0') { - if (fb) { - fb_destroy(fb); - } - return LB_STATUS_SUCCESS; - } - - common->lb.fb = fb_create(filename, common->lb.width, common->lb.height); - if (!common->lb.fb) { - ErrPrint("Faield to create a FB\n"); - if (fb) { - fb_destroy(fb); - } - return LB_STATUS_ERROR_FAULT; - } - - if (fb) { - fb_destroy(fb); - } - - return LB_STATUS_SUCCESS; -} - -int lb_set_pd_fb(struct livebox_common *common, const char *filename) -{ - struct fb_info *fb; - - if (!common || common->state != CREATE) { - return LB_STATUS_ERROR_INVALID; - } - - fb = common->pd.fb; - if (fb && !strcmp(fb_id(fb), filename)) { - /* BUFFER is not changed, just update the content */ - return LB_STATUS_ERROR_EXIST; - } - common->pd.fb = NULL; - - if (!filename || filename[0] == '\0') { - if (fb) { - fb_destroy(fb); - } - return LB_STATUS_SUCCESS; - } - - common->pd.fb = fb_create(filename, common->pd.width, common->pd.height); - if (!common->pd.fb) { - ErrPrint("Failed to create a FB\n"); - if (fb) { - fb_destroy(fb); - } - return LB_STATUS_ERROR_FAULT; - } - - if (fb) { - fb_destroy(fb); - } - return LB_STATUS_SUCCESS; -} - -struct fb_info *lb_get_lb_fb(struct livebox_common *common) -{ - return common->lb.fb; -} - -struct fb_info *lb_get_pd_fb(struct livebox_common *common) -{ - return common->pd.fb; -} - -void lb_set_user(struct livebox_common *common, int user) -{ - common->is_user = user; -} - -void lb_set_pinup(struct livebox_common *common, int pinup_supported) -{ - common->lb.pinup_supported = pinup_supported; -} - -void lb_set_text_lb(struct livebox_common *common) -{ - common->lb.type = _LB_TYPE_TEXT; -} - -void lb_set_text_pd(struct livebox_common *common) -{ - common->pd.type = _PD_TYPE_TEXT; -} - -int lb_text_lb(struct livebox_common *common) -{ - return common->lb.type == _LB_TYPE_TEXT; -} - -int lb_text_pd(struct livebox_common *common) -{ - return common->pd.type == _PD_TYPE_TEXT; -} - -void lb_set_period(struct livebox_common *common, double period) -{ - common->lb.period = period; -} - -struct livebox *lb_ref(struct livebox *handler) -{ - if (!handler) { - return NULL; - } - - handler->refcnt++; - return handler; -} - -struct livebox *lb_unref(struct livebox *handler, int destroy_common) -{ - if (!handler) { - return NULL; - } - - handler->refcnt--; - if (handler->refcnt > 0) { - return handler; - } - - if (handler->cbs.created.cb) { - handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data); - handler->cbs.created.cb = NULL; - handler->cbs.created.data = NULL; - } - - if (handler->cbs.deleted.cb) { - handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data); - handler->cbs.deleted.cb = NULL; - handler->cbs.deleted.data = NULL; - } - - if (handler->cbs.pinup.cb) { - handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data); - handler->cbs.pinup.cb = NULL; - handler->cbs.pinup.data = NULL; - } - - if (handler->cbs.group_changed.cb) { - handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data); - handler->cbs.group_changed.cb = NULL; - handler->cbs.group_changed.data = NULL; - } - - if (handler->cbs.period_changed.cb) { - handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data); - handler->cbs.period_changed.cb = NULL; - handler->cbs.period_changed.data = NULL; - } - - if (handler->cbs.size_changed.cb) { - handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data); - handler->cbs.size_changed.cb = NULL; - handler->cbs.size_changed.data = NULL; - } - - if (handler->cbs.pd_created.cb) { - handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data); - handler->cbs.pd_created.cb = NULL; - handler->cbs.pd_created.data = NULL; - } - - if (handler->cbs.pd_destroyed.cb) { - handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data); - handler->cbs.pd_destroyed.cb = NULL; - handler->cbs.pd_destroyed.data = NULL; - } - - if (handler->cbs.update_mode.cb) { - handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data); - handler->cbs.update_mode.cb = NULL; - handler->cbs.update_mode.data = NULL; - } - - if (handler->cbs.access_event.cb) { - handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data); - handler->cbs.access_event.cb = NULL; - handler->cbs.access_event.data = NULL; - } - - if (handler->cbs.key_event.cb) { - handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data); - handler->cbs.key_event.cb = NULL; - handler->cbs.key_event.data = NULL; - } - - dlist_remove_data(s_info.livebox_list, handler); - - handler->state = DESTROYED; - if (lb_common_unref(handler->common, handler) == 0) { - if (destroy_common) { - /*! - * \note - * Lock file should be deleted after all callbacks are processed. - */ - lb_destroy_lock_file(handler->common, 0); - lb_destroy_common_handle(handler->common); - } - } - free(handler); - DbgPrint("Handler is released\n"); - return NULL; -} - -int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data) -{ - struct packet *packet; - struct cb_info *cbinfo; - int ret; - - if (handler->common->request.deleted) { - ErrPrint("Already in-progress\n"); - if (cb) { - cb(handler, LB_STATUS_SUCCESS, data); - } - return LB_STATUS_ERROR_BUSY; - } - - if (!cb) { - cb = default_delete_cb; - } - - packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp); - if (!packet) { - ErrPrint("Failed to build a param\n"); - if (cb) { - cb(handler, LB_STATUS_ERROR_FAULT, data); - } - - return LB_STATUS_ERROR_FAULT; - } - - cbinfo = create_cb_info(cb, data); - if (!cbinfo) { - packet_destroy(packet); - ErrPrint("Failed to create cbinfo\n"); - if (cb) { - cb(handler, LB_STATUS_ERROR_FAULT, data); - } - - return LB_STATUS_ERROR_FAULT; - } - - ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo); - if (ret < 0) { - /*! - * Packet is destroyed by master_rpc_async_request. - */ - destroy_cb_info(cbinfo); - - if (cb) { - cb(handler, LB_STATUS_ERROR_FAULT, data); - } - } else { - handler->common->request.deleted = 1; - } - - return ret; -} - -EAPI int livebox_client_paused(void) -{ - struct packet *packet; - - packet = packet_create_noack("client_paused", "d", util_timestamp()); - if (!packet) { - ErrPrint("Failed to create a pause packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(NULL, packet); -} - -EAPI int livebox_client_resumed(void) -{ - struct packet *packet; - - packet = packet_create_noack("client_resumed", "d", util_timestamp()); - if (!packet) { - ErrPrint("Failed to create a resume packet\n"); - return LB_STATUS_ERROR_FAULT; - } - - return master_rpc_request_only(NULL, packet); -} - -EAPI int livebox_sync_lb_fb(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - return LB_STATUS_ERROR_INVALID; - } - - return lb_sync_lb_fb(handler->common); -} - -int lb_sync_lb_fb(struct livebox_common *common) -{ - int ret; - - if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) { - (void)do_fb_lock(common->lb.lock_fd); - ret = fb_sync(lb_get_lb_fb(common)); - (void)do_fb_unlock(common->lb.lock_fd); - } else { - ret = fb_sync(lb_get_lb_fb(common)); - } - - return ret; -} - -int lb_sync_pd_fb(struct livebox_common *common) -{ - int ret; - - if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) { - (void)do_fb_lock(common->pd.lock_fd); - ret = fb_sync(lb_get_pd_fb(common)); - (void)do_fb_unlock(common->pd.lock_fd); - } else { - ret = fb_sync(lb_get_pd_fb(common)); - } - - return ret; -} - -EAPI int livebox_sync_pd_fb(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - return lb_sync_pd_fb(handler->common); -} - -EAPI const char *livebox_alt_icon(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is not valid[%p]\n", handler); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return NULL; - } - - return handler->common->alt.icon; -} - -EAPI const char *livebox_alt_name(struct livebox *handler) -{ - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is not valid[%p]\n", handler); - return NULL; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return NULL; - } - - return handler->common->alt.name; -} - -EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd) -{ - int ret = LB_STATUS_SUCCESS; - int fd; - - if (!handler || handler->state != CREATE) { - ErrPrint("Handler is not valid[%p]\n", handler); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Handler is not valid\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid[%p]\n", handler); - return LB_STATUS_ERROR_INVALID; - } - - if (is_pd) { - if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) { - DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd); - return LB_STATUS_ERROR_INVALID; - } - - if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) { - return LB_STATUS_SUCCESS; - } - - fd = handler->common->pd.lock_fd; - } else { - if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) { - DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd); - return LB_STATUS_ERROR_INVALID; - } - - if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) { - return LB_STATUS_SUCCESS; - } - - fd = handler->common->lb.lock_fd; - } - - ret = do_fb_lock(fd); - - return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT; -} - -EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd) -{ - int ret = LB_STATUS_SUCCESS; - int fd; - - if (!handler || handler->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common || handler->common->state != CREATE) { - ErrPrint("Invalid handle\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!handler->common->id) { - ErrPrint("Handler is not valid[%p]\n", handler); - return LB_STATUS_ERROR_INVALID; - } - - if (is_pd) { - if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) { - DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd); - return LB_STATUS_ERROR_INVALID; - } - - if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) { - return LB_STATUS_SUCCESS; - } - - fd = handler->common->pd.lock_fd; - } else { - if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) { - DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd); - return LB_STATUS_ERROR_INVALID; - } - - if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) { - return LB_STATUS_SUCCESS; - } - - fd = handler->common->lb.lock_fd; - } - - ret = do_fb_unlock(fd); - - return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT; -} - -EAPI int livebox_set_option(enum livebox_option_type option, int state) -{ - int ret = LB_STATUS_SUCCESS; - - switch (option) { - case LB_OPTION_MANUAL_SYNC: - conf_set_manual_sync(state); - break; - case LB_OPTION_FRAME_DROP_FOR_RESIZE: - conf_set_frame_drop_for_resizing(state); - break; - case LB_OPTION_SHARED_CONTENT: - conf_set_shared_content(state); - break; - default: - ret = LB_STATUS_ERROR_INVALID; - break; - } - - return ret; -} - -EAPI int livebox_option(enum livebox_option_type option) -{ - int ret; - - switch (option) { - case LB_OPTION_MANUAL_SYNC: - ret = conf_manual_sync(); - break; - case LB_OPTION_FRAME_DROP_FOR_RESIZE: - ret = conf_frame_drop_for_resizing(); - break; - case LB_OPTION_SHARED_CONTENT: - ret = conf_shared_content(); - break; - default: - ret = LB_STATUS_ERROR_INVALID; - break; - } - - return ret; -} - -EAPI int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data) -{ - s_info.launch.handler = launch_handler; - s_info.launch.data = data; - - return LB_STATUS_SUCCESS; -} - -/* End of a file */ diff --git a/src/master_rpc.c b/src/master_rpc.c deleted file mode 100644 index ec3b4cb..0000000 --- a/src/master_rpc.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * 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 -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include "debug.h" -#include "dlist.h" -#include "livebox.h" -#include "livebox_internal.h" -#include "master_rpc.h" -#include "client.h" -#include "util.h" - -#define DEFAULT_TTL 10 -#define REQUEST_DELAY 10 - -struct command { - int ttl; - struct packet *packet; - struct livebox *handler; - void (*ret_cb)(struct livebox *handler, const struct packet *result, void *data); - void *data; - enum { - TYPE_ACK, - TYPE_NOACK - } type; -}; - -int errno; - -static struct { - guint cmd_timer; - struct dlist *cmd_list; -} s_info = { - .cmd_timer = 0, - .cmd_list = NULL, -}; - -static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data); - -static inline struct command *pop_command(void) -{ - struct dlist *l; - struct command *command; - - l = dlist_nth(s_info.cmd_list, 0); - if (!l) { - return NULL; - } - - command = dlist_data(l); - s_info.cmd_list = dlist_remove(s_info.cmd_list, l); - return command; -} - -static inline struct command *create_command(struct livebox *handler, struct packet *packet) -{ - struct command *command; - - command = malloc(sizeof(*command)); - if (!command) { - ErrPrint("Failed to allocate mem for command\n"); - return NULL; - } - - command->handler = lb_ref(handler); - command->packet = packet_ref(packet); - return command; -} - -static inline void destroy_command(struct command *command) -{ - packet_unref(command->packet); - lb_unref(command->handler, 1); - free(command); -} - -static gboolean cmd_consumer(gpointer user_data) -{ - struct command *command; - - command = pop_command(); - if (!command) { - s_info.cmd_timer = 0; - return FALSE; - } - - /*! - * \NOTE: - * Item will be deleted in the "done_cb" - * - * item->param be release by the g_dbus_proxy_call - * so to use it again from the done_cb function, - * increate the reference counter of the item->param - */ - if (command->type == TYPE_NOACK) { - if (com_core_packet_send_only(client_fd(), command->packet) < 0) { - ErrPrint("Failed to send a packet to master\n"); - } - - destroy_command(command); - } else { - if (com_core_packet_async_send(client_fd(), command->packet, 0u, done_cb, command) < 0) { - ErrPrint("Failed to send a packet to master\n"); - if (command->ret_cb) { - command->ret_cb(command->handler, NULL, command->data); - } - destroy_command(command); - } - } - return TRUE; -} - -static inline void prepend_command(struct command *command) -{ - s_info.cmd_list = dlist_prepend(s_info.cmd_list, command); - master_rpc_check_and_fire_consumer(); -} - -void master_rpc_check_and_fire_consumer(void) -{ - if (!s_info.cmd_list || s_info.cmd_timer || client_fd() < 0) { - return; - } - - s_info.cmd_timer = g_timeout_add(REQUEST_DELAY, cmd_consumer, NULL); - if (!s_info.cmd_timer) { - ErrPrint("Failed to add timer\n"); - } -} - -static int done_cb(pid_t pid, int handle, const struct packet *packet, void *data) -{ - struct command *command; - int ret; - - command = data; - - if (!packet) { - /*! \NOTE: - * Release resource even if - * we failed to finish the method call - */ - command->ttl--; - if (command->ttl > 0) { - prepend_command(command); - return 0; - } - - goto out; - } - - if (packet_get(packet, "i", &ret) != 1) { - ErrPrint("Invalid result packet\n"); - ret = LB_STATUS_ERROR_INVALID; - } - -out: - if (command->ret_cb) { - command->ret_cb(command->handler, packet, command->data); - } - - destroy_command(command); - return 0; -} - -static inline void push_command(struct command *command) -{ - s_info.cmd_list = dlist_append(s_info.cmd_list, command); - master_rpc_check_and_fire_consumer(); -} - -/*! - * \note - * "handler" could be NULL - */ -int master_rpc_async_request(struct livebox *handler, struct packet *packet, int urgent, void (*ret_cb)(struct livebox *handler, const struct packet *result, void *data), void *data) -{ - struct command *command; - - command = create_command(handler, packet); - if (!command) { - ErrPrint("Failed to create a command\n"); - packet_unref(packet); - return LB_STATUS_ERROR_FAULT; - } - - command->ret_cb = ret_cb; - command->data = data; - command->ttl = DEFAULT_TTL; - command->type = TYPE_ACK; - - if (urgent) { - prepend_command(command); - } else { - push_command(command); - } - - packet_unref(packet); - return LB_STATUS_SUCCESS; -} - -int master_rpc_request_only(struct livebox *handler, struct packet *packet) -{ - struct command *command; - - command = create_command(handler, packet); - if (!command) { - ErrPrint("Failed to create a command\n"); - packet_unref(packet); - return LB_STATUS_ERROR_FAULT; - } - - command->ret_cb = NULL; - command->data = NULL; - command->ttl = 0; - command->type = TYPE_NOACK; - - push_command(command); - packet_unref(packet); - return LB_STATUS_SUCCESS; -} - -int master_rpc_clear_fault_package(const char *pkgname) -{ - struct dlist *l; - struct dlist *n; - struct command *command; - - if (!pkgname) { - return LB_STATUS_ERROR_INVALID; - } - - dlist_foreach_safe(s_info.cmd_list, l, n, command) { - if (!command->handler) { - continue; - } - - if (!strcmp(command->handler->common->pkgname, pkgname)) { - s_info.cmd_list = dlist_remove(s_info.cmd_list, l); - if (command->ret_cb) { - command->ret_cb(command->handler, NULL, command->data); - } - - destroy_command(command); - } - } - - return 0; -} - -int master_rpc_clear_all_request(void) -{ - struct command *command; - struct dlist *l; - struct dlist *n; - - dlist_foreach_safe(s_info.cmd_list, l, n, command) { - s_info.cmd_list = dlist_remove(s_info.cmd_list, l); - - if (command->ret_cb) { - command->ret_cb(command->handler, NULL, command->data); - } - - destroy_command(command); - } - - return 0; -} - -int master_rpc_sync_request(struct packet *packet) -{ - struct packet *result; - int ret; - - result = com_core_packet_oneshot_send(client_addr(), packet, 0.0f); - if (result) { - if (packet_get(result, "i", &ret) != 1) { - ErrPrint("Invalid result packet\n"); - ret = LB_STATUS_ERROR_INVALID; - } - - packet_unref(result); - } else { - ErrPrint("Failed to send a sync request\n"); - ret = LB_STATUS_ERROR_FAULT; - } - - packet_unref(packet); - return ret; -} - -/* End of a file */ diff --git a/src/util.c b/src/util.c deleted file mode 100644 index 66431c6..0000000 --- a/src/util.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include - -#include -#include /* For error code */ - -#include "debug.h" -#include "util.h" - -int errno; -#if defined(_USE_ECORE_TIME_GET) -static struct { - clockid_t type; -} s_info = { - .type = CLOCK_MONOTONIC, -}; -#endif - -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 LB_STATUS_ERROR_INVALID; - } - - check_ptr ++; - } - - return 0; -} - -double util_timestamp(void) -{ -#if defined(_USE_ECORE_TIME_GET) - struct timespec ts; - - do { - if (clock_gettime(s_info.type, &ts) == 0) { - return ts.tv_sec + ts.tv_nsec / 1000000000.0f; - } - - ErrPrint("%d: %s\n", s_info.type, strerror(errno)); - if (s_info.type == CLOCK_MONOTONIC) { - s_info.type = CLOCK_REALTIME; - } else if (s_info.type == CLOCK_REALTIME) { - struct timeval tv; - if (gettimeofday(&tv, NULL) < 0) { - ErrPrint("gettimeofday: %s\n", strerror(errno)); - break; - } - - return tv.tv_sec + tv.tv_usec / 1000000.0f; - } - } while (1); - - return 0.0f; -#else - struct timeval tv; - - if (gettimeofday(&tv, NULL) < 0) { - ErrPrint("gettimeofday: %s\n", strerror(errno)); - tv.tv_sec = 0; - tv.tv_usec = 0; - } - - return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f; -#endif -} - -const char *util_basename(const char *name) -{ - int length; - length = name ? strlen(name) : 0; - if (!length) { - return "."; - } - - while (--length > 0 && name[length] != '/'); - - return length <= 0 ? name : name + length + (name[length] == '/'); -} - -static inline int check_native_livebox(const char *pkgname) -{ - int len; - char *path; - - len = strlen(pkgname) * 2; - len += strlen("/opt/usr/live/%s/libexec/liblive-%s.so"); - - path = malloc(len + 1); - if (!path) { - ErrPrint("Heap: %s\n", strerror(errno)); - return LB_STATUS_ERROR_MEMORY; - } - - snprintf(path, len, "/opt/usr/live/%s/libexec/liblive-%s.so", pkgname, pkgname); - if (access(path, F_OK | R_OK) != 0) { - ErrPrint("%s is not a valid package\n", pkgname); - free(path); - return LB_STATUS_ERROR_INVALID; - } - - free(path); - return 0; -} - -static inline int check_web_livebox(const char *pkgname) -{ - int len; - char *path; - - len = strlen(pkgname) * 2; - len += strlen("/opt/usr/apps/%s/res/wgt/livebox/index.html"); - - path = malloc(len + 1); - if (!path) { - ErrPrint("Heap: %s\n", strerror(errno)); - return LB_STATUS_ERROR_MEMORY; - } - - snprintf(path, len, "/opt/usr/apps/%s/res/wgt/livebox/index.html", pkgname); - if (access(path, F_OK | R_OK) != 0) { - ErrPrint("%s is not a valid package\n", pkgname); - free(path); - return LB_STATUS_ERROR_INVALID; - } - - free(path); - return 0; -} - -int util_validate_livebox_package(const char *pkgname) -{ - if (!pkgname) { - ErrPrint("Invalid argument\n"); - return LB_STATUS_ERROR_INVALID; - } - - if (!check_native_livebox(pkgname) || !check_web_livebox(pkgname)) { - return 0; - } - - return LB_STATUS_ERROR_INVALID; -} - -const char *util_uri_to_path(const char *uri) -{ - int len; - - len = strlen(SCHEMA_FILE); - if (strncasecmp(uri, SCHEMA_FILE, len)) { - return NULL; - } - - return uri + len; -} - -int util_unlink(const char *filename) -{ - char *descfile; - int desclen; - int ret; - - if (!filename) { - return LB_STATUS_ERROR_INVALID; - } - - desclen = strlen(filename) + 6; /* .desc */ - descfile = malloc(desclen); - if (!descfile) { - ErrPrint("Heap: %s\n", strerror(errno)); - return LB_STATUS_ERROR_MEMORY; - } - - ret = snprintf(descfile, desclen, "%s.desc", filename); - if (ret < 0) { - ErrPrint("Error: %s\n", strerror(errno)); - free(descfile); - return LB_STATUS_ERROR_FAULT; - } - - (void)unlink(descfile); - free(descfile); - (void)unlink(filename); - - return LB_STATUS_SUCCESS; -} - -/* End of a file */ -- 2.7.4