--- /dev/null
+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")
+
+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
+)
+
+FOREACH(flag ${pkgs_CFLAGS})
+ SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+#ADD_DEFINITIONS("-Werror")
+#ADD_DEFINITIONS("-Wall")
+#ADD_DEFINITIONS("-Wextra")
+#ADD_DEFINITIONS("-ansi")
+#ADD_DEFINITIONS("-pedantic")
+
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+ADD_DEFINITIONS("-DLOG_TAG=\"${PROJECT_NAME}\"")
+ADD_DEFINITIONS("-DLIVE_IMAGE_FOLDER=\"/opt/share/live_magazine/\"")
+ADD_DEFINITIONS("-DNDEBUG")
+#ADD_DEFINITIONS("-DFLOG")
+ADD_DEFINITIONS("-DMASTER_PKGNAME=\"com.samsung.data-provider-master\"")
+
+ADD_DEFINITIONS("-DBUS_TYPE=G_BUS_TYPE_SYSTEM") # G_BUS_TYPE_SESSION
+ADD_DEFINITIONS("-DSERVICE_INTERFACE=\"com.samsung.dataprovider.server\"")
+ADD_DEFINITIONS("-DSERVICE_NAME=\"com.samsung.dataprovider.serviceinterface\"")
+ADD_DEFINITIONS("-DOBJECT_PATH=\"/com/samsung/dataprovider/serviceobject\"")
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED
+ src/dlist.c
+ src/livebox.c
+ src/util.c
+ src/dbus.c
+ src/fb_file.c
+ src/desc_parser.c
+)
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES VERSION ${VERSION})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${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_SOURCE_DIR}/include/livebox.h DESTINATION include/${PROJECT_NAME})
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/include/livebox-viewer_PG.h DESTINATION /usr/share/doc/${PROJECT_NAME})
+
+ADD_SUBDIRECTORY(data)
--- /dev/null
+livebox-viewer (0.0.1) unstable; urgency=low
+
+ * Initial Release.
+
+ * Git: slp/pkgs/l/livebox-viewer
+ * Tag: livebox-viewer_0.0.1
+
+ -- Sung-jae Park <nicesj.park@samsung.com> Mon, 27 Feb 2012 14:14:00 +0900
+
--- /dev/null
+Source: livebox-viewer
+Section: libs
+Priority: optional
+Maintainer: Sung-jae Park <nicesj.park@samsung.com>, Young-joo Park <yjoo93.park@samsung.com>
+Build-Depends: debhelper (>= 5), dlog-dev, libaul-1-dev, libglib2.0-dev
+Standards-Version: 0.1.0
+
+Package: liblivebox-viewer
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Livebox supporting library (shared object)
+
+Package: liblivebox-viewer-dev
+Section: libs
+Architecture: any
+Depends: liblivebox-viewer (= ${Source-Version})
+Description: Livebox supporting library (development)
+
+Package: liblivebox-viewer-dbg
+Section: debug
+Architecture: any
+Depends: ${misc:Depends}, liblivebox-viewer (= ${Source-Version})
+Description: Livebox supporting library (unstripped)
+
--- /dev/null
+@PREFIX@/include/@PROJECT_NAME@/livebox.h
+@PREFIX@/share/doc/@PROJECT_NAME@/livebox-viewer_PG.h
+@PREFIX@/lib/pkgconfig/*.pc
--- /dev/null
+@PREFIX@/lib/*.so*
--- /dev/null
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+CFLAGS += -Wall -Werror -Winline
+LDFLAGS +=
+PREFIX ?= /usr
+DATADIR ?= /opt
+PROJECT_NAME ?= livebox-viewer
+
+BUILDDIR ?= $(CURDIR)/cmake-tmp
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+ CFLAGS += -O0
+else
+ CFLAGS += -O2
+endif
+
+LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--as-needed -lm
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+ # Add here commands to configure the package.
+ mkdir -p $(BUILDDIR) && cd $(BUILDDIR) && CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" cmake .. -DCMAKE_INSTALL_PREFIX=$(PREFIX)
+
+ touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+
+ # Add here commands to compile the package.
+ cd $(BUILDDIR) && $(MAKE)
+ #docbook-to-man debian/wavplayer.sgml > wavplayer.1
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ cat $$f > $${f%.in}; \
+ sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \
+ sed -i -e "s#@PROJECT_NAME@#$(PROJECT_NAME)#g" $${f%.in}; \
+ sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \
+ done
+
+
+ touch $@
+
+clean:
+ dh_testdir
+ dh_testroot
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ rm -rf $(BUILDDIR)
+ #rm -rf CMakeCache.txt CMakeFiles cmake_install.cmake Makefile install_manifest.txt
+
+ for f in `find $(CURDIR)/debian/ -name "*.in"`; do \
+ rm -f $${f%.in}; \
+ done
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/wavplayer.
+ cd $(BUILDDIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ #dh_installchangelogs
+ #dh_installdocs
+ #dh_installexamples
+ dh_install --sourcedir=debian/tmp
+# dh_installmenu
+# dh_installdebconf
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+# dh_python
+# dh_installinit
+# dh_installcron
+# dh_installinfo
+ dh_installman
+ dh_link
+ dh_strip --dbg-package=liblivebox-viewer-dbg
+ dh_compress
+ dh_fixperms
+# dh_perl
+ dh_makeshlibs
+ dh_installdeb
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
--- /dev/null
+
+extern GDBusProxy *dbus_get_proxy(void);
+extern int dbus_push_command(struct livebox *handler, const char *funcname, GVariant *param, void (*ret_cb)(struct livebox *handler, int ret, void *data), void *data);
+extern int dbus_sync_command(const char *funcname, GVariant *param);
+extern int dbus_init(void);
+extern int dbus_fini(void);
+
+/* End of a file */
--- /dev/null
+#if !defined(FLOG)
+#define DbgPrint(format, arg...) LOGD("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#define ErrPrint(format, arg...) LOGE("[\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg)
+#else
+extern FILE *__file_log_fp;
+#define DbgPrint(format, arg...) do { fprintf(__file_log_fp, "[LOG] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
+
+#define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [\e[32m%s/%s\e[0m:%d] " format, basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
+#endif
+
+/* End of a file */
--- /dev/null
+extern int parse_desc(struct livebox *handle, const char *descfile, int is_pd);
+
+/* End of a file */
--- /dev/null
+#define dlist_remove_data(list, data) do { \
+ struct dlist *l; \
+ l = dlist_find_data(list, data); \
+ list = dlist_remove(list, l); \
+} while (0)
+
+#define dlist_foreach(list, l, data) \
+ for ((l) = (list); ((data) = dlist_data(l)); (l) = dlist_next(l))
+
+#define dlist_foreach_safe(list, l, n, data) \
+ for ((l) = (list), (n) = dlist_next(l); \
+ ((data) = dlist_data(l)); \
+ (l) = (n), (n) = dlist_next(l))
+
+struct dlist;
+
+extern struct dlist *dlist_append(struct dlist *list, void *data);
+extern struct dlist *dlist_prepend(struct dlist *list, void *data);
+extern struct dlist *dlist_remove(struct dlist *list, struct dlist *l);
+extern struct dlist *dlist_find_data(struct dlist *list, void *data);
+extern void *dlist_data(struct dlist *l);
+extern struct dlist *dlist_next(struct dlist *l);
+extern struct dlist *dlist_prev(struct dlist *l);
+extern int dlist_count(struct dlist *l);
+extern struct dlist *dlist_nth(struct dlist *l, int nth);
+
+/* End of a file */
--- /dev/null
+struct fb_info;
+
+extern int fb_init(void);
+extern int fb_fini(void);
+extern void *fb_buffer(struct fb_info *info);
+extern const char *fb_filename(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_size(struct fb_info *info);
+extern int fb_is_created(struct fb_info *info);
+
+extern struct fb_info *fb_create(const char *filename, int w, int h);
+extern int fb_create_buffer(struct fb_info *info);
+extern int fb_destroy_buffer(struct fb_info *info);
+extern int fb_destroy(struct fb_info *info);
+
+/* End of a file */
--- /dev/null
+#ifndef __LIVEBOX_H
+#define __LIVEBOX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct livebox;
+
+/*!
+ * \note size list
+ * 172x172
+ * 372x172
+ * 372x372
+ * 720x372
+ */
+#define NR_OF_SIZE_LIST 4
+
+static const struct supported_size_list {
+ int w;
+ int h;
+} SIZE_LIST[NR_OF_SIZE_LIST] = {
+ { 172, 172 },
+ { 348, 172 },
+ { 348, 348 },
+ { 700, 348 },
+};
+
+struct livebox_script_operators {
+ int (*update_begin)(struct livebox *handle);
+ int (*update_end)(struct livebox *handle);
+
+ int (*update_text)(struct livebox *handle, const char *id, const char *part, const char *data);
+ int (*update_image)(struct livebox *handle, const char *id, const char *part, const char *data);
+ int (*update_edje)(struct livebox *handle, const char *id, const char *part, const char *file, const char *group);
+ int (*update_signal)(struct livebox *handle, const char *id, const char *emission, const char *signal);
+ int (*update_drag)(struct livebox *handle, const char *id, const char *part, double dx, double dy);
+ int (*update_info_size)(struct livebox *handle, const char *id, int w, int h);
+ int (*update_info_category)(struct livebox *handle, const char *id, const char *category);
+};
+
+extern int livebox_init(void);
+extern int livebox_fini(void);
+
+extern struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category);
+extern int livebox_del(struct livebox *handler, int server);
+
+/*!
+ * \note event list
+ * "lb,updated" - Contents of the given livebox is updated.
+ * "pd,updated" - Contents of the given pd is updated.
+ * "lb,created" - A new livebox is created
+ * "lb,deleted" - Given livebox is deleted
+ * "pd,created" - frame buffer of PD is created
+ * "pd,create,failed" - frame buffer of PD is not created
+ * "pd,deleted" - frame buffer of PD is deleted
+ * "pinup,changed" - Pinup status is changed
+ * "pinup,failed" - Pinup status is not changed
+ * "event,ignored" - Event is not delivered to the livebox
+ */
+extern int livebox_event_handler_set(int (*cb)(struct livebox *handler, const char *event, void *data), void *data);
+/*!
+ * return pointer of 'data'
+ */
+extern void *livebox_event_handler_unset(int (*cb)(struct livebox *handler, const char *event, void *data));
+
+/*!
+ * \note argument list
+ * event, pkgname, filename, funcname
+ *
+ * event list
+ * "activated" - Package is successfully activated
+ * "invalid,request" - Package is not valid
+ * "deactivated" - Package is deactivated
+ * "activation,failed" - Failed to activate a package
+ */
+extern int livebox_fault_handler_set(int (*cb)(const char *, const char *, const char *, const char *, void *), void *data);
+/*!
+ * return pointer of 'data'
+ */
+extern void *livebox_fault_handler_unset(int (*cb)(const char *, const char *, const char *, const char *, void *));
+
+extern int livebox_activate(const char *pkgname);
+
+extern int livebox_resize(struct livebox *handler, int w, int h);
+extern int livebox_click(struct livebox *handler, double x, double y);
+
+extern int livebox_set_group(struct livebox *handler, const char *cluster, const char *category);
+extern int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category);
+
+extern int livebox_delete_cluster(const char *cluster);
+extern int livebox_delete_category(const char *cluster, const char *category);
+
+extern int livebox_is_text(struct livebox *handler);
+extern int livebox_is_file(struct livebox *handler);
+extern int livebox_is_user(struct livebox *handler);
+
+extern const char *livebox_filename(struct livebox *handler);
+extern void *livebox_fb(struct livebox *handler);
+extern void *livebox_pdfb(struct livebox *handler);
+
+extern int livebox_get_size(struct livebox *handler, int *w, int *h);
+extern int livebox_get_pdsize(struct livebox *handler, int *w, int *h);
+
+extern int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *w, int *h);
+extern const char *livebox_pkgname(struct livebox *handler);
+extern double livebox_priority(struct livebox *handler);
+
+extern int livebox_lbfb_bufsz(struct livebox *handler);
+extern int livebox_pdfb_bufsz(struct livebox *handler);
+
+extern int livebox_pd_mouse_down(struct livebox *handler, double x, double y);
+extern int livebox_pd_mouse_up(struct livebox *handler, double x, double y);
+extern int livebox_pd_mouse_move(struct livebox *handler, double x, double y);
+
+extern int livebox_livebox_mouse_down(struct livebox *handler, double x, double y);
+extern int livebox_livebox_mouse_up(struct livebox *handler, double x, double y);
+extern int livebox_livebox_mouse_move(struct livebox *handler, double x, double y);
+
+extern int livebox_set_pinup(struct livebox *handler, int flag);
+extern int livebox_pinup(struct livebox *handler);
+extern int livebox_has_pinup(struct livebox *handler);
+
+extern int livebox_has_pd(struct livebox *handler);
+extern int livebox_create_pd(struct livebox *handler);
+extern int livebox_destroy_pd(struct livebox *handler);
+extern int livebox_pd_is_created(struct livebox *handler);
+extern int livebox_pd_is_text(struct livebox *handler);
+
+extern int livebox_set_data(struct livebox *handler, void *data);
+extern void *livebox_get_data(struct livebox *handler);
+
+extern int livebox_is_exists(const char *pkgname);
+
+extern int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops);
+extern int livebox_pd_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* End of a file */
--- /dev/null
+extern int lb_set_group(struct livebox *handler, const char *cluster, const char *category);
+extern int lb_set_size(struct livebox *handler, int w, int h);
+extern int lb_set_pdsize(struct livebox *handler, int w, int h);
+extern int lb_invoke_event_handler(struct livebox *handler, const char *event);
+extern int lb_invoke_fault_handler(const char *event, const char *pkgname, const char *filename, const char *function);
+extern int lb_set_content(struct livebox *handler, const char *content);
+extern int lb_set_auto_launch(struct livebox *handler, int auto_launch);
+extern struct livebox *lb_find_livebox(const char *pkgname, const char *filename);
+extern struct livebox *lb_new_livebox(const char *pkgname, const char *filename);
+extern struct livebox *lb_find_livebox_by_timestamp(double timestamp);
+extern void lb_set_filename(struct livebox *handler, const char *filename);
+extern void lb_set_size_list(struct livebox *handler, int size_list);
+extern void lb_set_priority(struct livebox *handler, double priority);
+extern void lb_set_lb_fb(struct livebox *handler, const char *filename, int w, int h);
+extern void lb_set_pd_fb(struct livebox *handler, const char *filename, int w, int h);
+extern struct fb_info *lb_get_pd_fb(struct livebox *handler);
+extern struct fb_info *lb_get_lb_fb(struct livebox *handler);
+extern void lb_update_pd_fb(struct livebox *handler, int w, int h);
+extern void lb_update_lb_fb(struct livebox *handler, int w, int h);
+extern void lb_set_user(struct livebox *handler, int user);
+extern void lb_set_pinup(struct livebox *handler, int pinup);
+extern void lb_set_text_lb(struct livebox *handler, int flag);
+extern void lb_set_text_pd(struct livebox *handler, int flag);
+extern int lb_text_lb(struct livebox *handler);
+extern int lb_text_pd(struct livebox *handler);
+
+struct livebox {
+ char *cluster;
+ char *category;
+
+ char *pkgname;
+ char *filename;
+
+ int size_list;
+
+ double timestamp;
+
+ enum {
+ FILEDATA,
+ FBDATA,
+ } data_type;
+
+ char *content;
+ int lb_w;
+ int lb_h;
+ int pd_w;
+ int pd_h;
+ int auto_launch;
+ double priority;
+
+ int nr_of_sizes;
+
+ struct fb_info *lb_fb;
+ struct fb_info *pd_fb;
+
+ int is_user;
+ int is_pinned_up;
+ int pinup_supported;
+ int text_lb;
+ int text_pd;
+
+ void *data;
+
+ struct livebox_script_operators ops;
+ struct livebox_script_operators pd_ops;
+};
+
+/* End of a file */
--- /dev/null
+/*
+ * com.samsung.live-magazine
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sung-jae Park <nicesj.park@samsung.com>, Youngjoo Park <yjoo93.park@samsung.com>
+ *
+ * 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.
+ *
+ */
+
+extern int util_check_extension(const char *filename, const char *check_ptr);
+extern double util_get_timestamp(void);
+
+/* End of a file */
--- /dev/null
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: livebox
+Description: livebox supporting library
+Version: @VERSION@
+Libs: -L${libdir} -llivebox-viewer
+Cflags: -I${includedir}
--- /dev/null
+all:
+ @gcc sample.c -o sample -Wall -p -g `pkg-config ail elementary dlog ecore-x appcore-efl glib-2.0 gio-2.0 livebox-viewer shortcut --libs --cflags`
--- /dev/null
+#include <appcore-efl.h>
+#include <Elementary.h>
+#include <Ecore_X.h>
+#include <unistd.h>
+
+#include <dlog.h>
+#include <ail.h>
+
+#include <livebox.h>
+#include <shortcut.h>
+
+static struct info {
+ Eina_List *boxes;
+ Evas_Object *win;
+ Evas_Object *bg;
+ Evas_Coord w, h;
+ Evas_Object *pkg_list;
+ Evas_Object *c_list;
+ Evas_Object *s_list;
+ Evas_Object *pd_btn;
+ Evas_Object *create_btn;
+ char *pkgname;
+ char *content;
+ char *cluster;
+ char *category;
+} s_info = {
+ .boxes = NULL,
+ .win = NULL,
+ .bg = NULL,
+ .w = 0,
+ .h = 0,
+ .pkgname = NULL,
+ .content = NULL,
+ .cluster = NULL,
+ .category = NULL,
+ .pkg_list = NULL,
+ .c_list = NULL,
+ .s_list = NULL,
+};
+
+struct box_info {
+ struct livebox *handler;
+ Evas_Object *box;
+ Evas_Object *pd;
+};
+
+char *util_get_iconfile(const char *pkgname)
+{
+ ail_appinfo_h handle;
+ ail_error_e ret;
+ char *iconfile;
+ char *ret_iconfile;
+
+ ret = ail_package_get_appinfo(pkgname, &handle);
+ if (ret != AIL_ERROR_OK) {
+ fprintf(stderr, "ail get pkgname = %s\n", pkgname);
+ return NULL;
+ }
+
+ ret = ail_appinfo_get_str(handle, AIL_PROP_ICON_STR, &iconfile);
+ if (ret != AIL_ERROR_OK) {
+ ret = ail_package_destroy_appinfo(handle);
+ fprintf(stderr, "Get iconfile from pkgname = %s\n", pkgname);
+ return NULL;
+ }
+
+ ret_iconfile = strdup(iconfile);
+ if (!ret_iconfile)
+ fprintf(stderr, "Error: %s\n", strerror(errno));
+
+ ret = ail_package_destroy_appinfo(handle);
+ if (ret != AIL_ERROR_OK) {
+ if (ret_iconfile)
+ free(ret_iconfile);
+ fprintf(stderr, "Failed to destory appinfo\n");
+ return NULL;
+ }
+
+ return ret_iconfile;
+}
+
+static void pd_mouse_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Down *down = event_info;
+ Evas_Coord x, y, w, h;
+ double rx, ry;
+ struct box_info *info = data;
+
+ 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_pd_mouse_down(info->handler, rx, ry);
+}
+
+static void pd_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Up *up = event_info;
+ Evas_Coord x, y, w, h;
+ double rx, ry;
+ struct box_info *info = data;
+
+ 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;
+
+ livebox_pd_mouse_up(info->handler, rx, ry);
+}
+
+static void pd_mouse_move_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Move *move = event_info;
+ Evas_Coord x, y, w, h;
+ double rx, ry;
+ struct box_info *info = data;
+
+ 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_pd_mouse_move(info->handler, rx, ry);
+}
+
+static void box_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Up *up = event_info;
+ Evas_Coord x, y, w, h;
+ double rx, ry;
+ struct box_info *info = data;
+
+ 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;
+
+ livebox_click(info->handler, rx, ry);
+}
+
+static inline struct box_info *find_box_info(struct livebox *handler)
+{
+ Eina_List *l;
+ Eina_List *n;
+ struct box_info *info;
+
+ EINA_LIST_FOREACH_SAFE(s_info.boxes, l, n, info) {
+ if (info->handler == handler)
+ return info;
+ }
+
+ return NULL;
+}
+
+static inline int create_new_pd(struct livebox *handler)
+{
+ struct box_info *info;
+
+ info = find_box_info(handler);
+ if (!info)
+ return -ENOENT;
+
+ if (info->pd)
+ return -EEXIST;
+
+ info->pd = evas_object_image_add(evas_object_evas_get(s_info.win));
+ if (!info->pd) {
+ fprintf(stderr, "Failed to add an image object for pd\n");
+ } else {
+ Evas_Coord w, h;
+ Evas_Coord x, y;
+
+ livebox_get_pdsize(handler, &w, &h);
+
+ evas_object_image_size_set(info->pd, w, h);
+ evas_object_image_colorspace_set(info->pd, EVAS_COLORSPACE_ARGB8888);
+ evas_object_image_alpha_set(info->pd, EINA_TRUE);
+
+ evas_object_image_fill_set(info->pd, 0, 0, w, h);
+ evas_object_image_data_set(info->pd, livebox_pdfb(handler));
+ evas_object_image_data_update_add(info->pd, 0, 0, w, h);
+ evas_object_resize(info->pd, w, h);
+ if (s_info.w != w)
+ x = (rand() % (s_info.w - w));
+ else
+ x = 0;
+
+ y = (rand() % ((s_info.h / 2) - h));
+ evas_object_move(info->pd, x, y);
+ evas_object_show(info->pd);
+
+ evas_object_event_callback_add(info->pd, EVAS_CALLBACK_MOUSE_DOWN, pd_mouse_down_cb, info);
+ evas_object_event_callback_add(info->pd, EVAS_CALLBACK_MOUSE_MOVE, pd_mouse_move_cb, info);
+ evas_object_event_callback_add(info->pd, EVAS_CALLBACK_MOUSE_UP, pd_mouse_up_cb, info);
+ }
+
+ return 0;
+}
+
+static inline int create_new_box(struct livebox *handler)
+{
+ struct box_info *info;
+
+ info = malloc(sizeof(*info));
+ if (!info) {
+ LOGE("Heap: %s\n", strerror(errno));
+ return -ENOMEM;
+ }
+
+ info->handler = handler;
+
+ info->box = evas_object_image_add(evas_object_evas_get(s_info.win));
+ if (!info->box) {
+ fprintf(stderr, "Failed to add an image object\n");
+ } else {
+ Evas_Coord w, h;
+ livebox_get_size(handler, &w, &h);
+ fprintf(stderr, "created size: %dx%d\n", w, h);
+ evas_object_image_file_set(info->box, livebox_filename(info->handler), NULL);
+ evas_object_image_fill_set(info->box, 0, 0, w, h);
+ evas_object_resize(info->box, w, h);
+ evas_object_move(info->box, (rand() % (s_info.w - w)), (rand() % ((s_info.h / 2) - h)));
+ evas_object_event_callback_add(info->box, EVAS_CALLBACK_MOUSE_UP, box_mouse_up_cb, info);
+ evas_object_layer_set(info->box, livebox_priority(info->handler) * 10);
+ evas_object_show(info->box);
+ }
+
+ info->pd = NULL;
+
+ s_info.boxes = eina_list_append(s_info.boxes, info);
+ return 0;
+}
+
+static inline int delete_pd(struct livebox *handler)
+{
+ struct box_info *info;
+
+ info = find_box_info(handler);
+ if (info && info->pd) {
+ elm_object_part_text_set(info->pd, "default", "CreatePD");
+ evas_object_del(info->pd);
+ info->pd = NULL;
+ }
+
+ return 0;
+}
+
+static inline int delete_box(struct livebox *handler)
+{
+ Eina_List *l;
+ Eina_List *n;
+ struct box_info *info;
+
+ EINA_LIST_FOREACH_SAFE(s_info.boxes, l, n, info) {
+ if (info->handler == handler) {
+ s_info.boxes = eina_list_remove(s_info.boxes, info);
+
+ if (info->box)
+ evas_object_del(info->box);
+
+ if (info->pd) {
+ elm_object_part_text_set(info->pd, "default", "CreatePD");
+ evas_object_del(info->pd);
+ }
+
+ fprintf(stderr, "%s is deleted\n", livebox_filename(info->handler));
+ /* Handler will be freed by the system */
+ free(info);
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+static inline void reload_buffer(Evas_Object *box, void *buffer, double priority, Evas_Coord w, Evas_Coord h)
+{
+ Evas_Coord ow, oh, x, y;
+
+ evas_object_geometry_get(box, &x, &y, &ow, &oh);
+
+ x += ((ow - w) / 2);
+ y += ((oh - h) / 2);
+
+ evas_object_move(box, x, y);
+ if (ow != w || oh != h) {
+ evas_object_image_fill_set(box, 0, 0, w, h);
+ evas_object_image_data_set(box, buffer);
+ evas_object_resize(box, w, h);
+ }
+
+ evas_object_image_data_update_add(box, 0, 0, w, h);
+ evas_object_show(box);
+}
+
+static inline void reload_file(Evas_Object *box, const char *filename, double priority, Evas_Coord w, Evas_Coord h)
+{
+ const char *fname;
+ Evas_Coord ow, oh, x, y;
+
+ evas_object_image_file_get(box, &fname, NULL);
+ evas_object_geometry_get(box, &x, &y, &ow, &oh);
+
+ x += ((ow - w) / 2);
+ y += ((oh - h) / 2);
+
+ evas_object_image_fill_set(box, 0, 0, w, h);
+ evas_object_move(box, x, y);
+ evas_object_resize(box, w, h);
+
+ if (!strcmp(fname, filename)) {
+ evas_object_image_reload(box);
+ fprintf(stderr, "Reload file: %s, %s\n", fname, filename);
+ } else {
+ evas_object_image_file_set(box, fname, NULL);
+ fprintf(stderr, "First load: %s\n", fname);
+ }
+
+ evas_object_layer_set(box, priority * 10);
+ evas_object_show(box);
+}
+
+static inline int update_box(struct livebox *handler)
+{
+ Eina_List *l;
+ struct box_info *info;
+ Evas_Coord w, h;
+
+ livebox_get_size(handler, &w, &h);
+ fprintf(stderr, "reload size: %dx%d\n", w, h);
+
+ EINA_LIST_FOREACH(s_info.boxes, l, info) {
+ if (info->handler == handler) {
+ if (!info->box)
+ return -EINVAL;
+
+ if (livebox_is_file(handler))
+ reload_file(info->box, livebox_filename(handler), livebox_priority(handler), w, h);
+ else
+ reload_buffer(info->box, livebox_fb(handler), 1.0, w, h);
+
+ return 0;
+ }
+ }
+
+ return create_new_box(handler);
+}
+
+static inline int update_pd(struct livebox *handler)
+{
+ Eina_List *l;
+ struct box_info *info;
+ Evas_Coord w, h;
+
+ livebox_get_pdsize(handler, &w, &h);
+ fprintf(stderr, "reload size: %dx%d\n", w, h);
+
+ EINA_LIST_FOREACH(s_info.boxes, l, info) {
+ if (info->handler == handler) {
+ if (!info->pd)
+ create_new_pd(handler);
+ else
+ reload_buffer(info->pd, livebox_pdfb(handler), 1.0, w, h);
+
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+static int fault_cb(const char *event, const char *pkgname, const char *filename, const char *funcname, void *data)
+{
+ fprintf(stderr, "event: %s ==========================\n", event);
+ fprintf(stderr, "pkgname: %s\n", pkgname);
+ fprintf(stderr, "filename: %s\n", filename);
+ fprintf(stderr, "funcname: %s\n", funcname);
+
+ if (!strcmp(event, "invalid,request"))
+ return EXIT_SUCCESS;
+
+ if (!strcmp(event, "activated"))
+ return EXIT_SUCCESS;
+
+ if (!strcmp(event, "activation,failed"))
+ return EXIT_SUCCESS;
+
+ livebox_activate(pkgname);
+ return EXIT_SUCCESS;
+}
+
+static int event_cb(struct livebox *handler, const char *event, void *data)
+{
+ fprintf(stderr, "event: %s ==========================\n", event);
+ fprintf(stderr, "pkgname: %s\n", livebox_pkgname(handler));
+ fprintf(stderr, "priority: %lf\n", livebox_priority(handler));
+ fprintf(stderr, "created by %s\n", livebox_is_user(handler) ? "user" : "system");
+ fprintf(stderr, "handler: %p\n", handler);
+
+ if (!livebox_is_file(handler)) {
+ fprintf(stderr, "[%s] buffer: %p\n", livebox_pkgname(handler), livebox_fb(handler));
+ return EXIT_SUCCESS;
+ }
+
+ if (!strcmp(event, "lb,created"))
+ create_new_box(handler);
+ else if (!strcmp(event, "lb,deleted"))
+ delete_box(handler);
+ else if (!strcmp(event, "lb,updated"))
+ update_box(handler);
+ else if (!strcmp(event, "pd,created"))
+ create_new_pd(handler);
+ else if (!strcmp(event, "pd,deleted"))
+ delete_pd(handler);
+ else if (!strcmp(event, "pd,updated"))
+ update_pd(handler);
+
+ return EXIT_SUCCESS;
+}
+
+static void win_del(void *data, Evas_Object *obj, void *event)
+{
+ elm_exit();
+}
+
+static void item_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ fprintf(stderr, "Pressed: %p\n", obj);
+}
+
+static void category_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ fprintf(stderr, "category: %s\n", (char *)data);
+}
+
+static void cluster_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ fprintf(stderr, "cluster: %s\n", (char *)data);
+}
+
+static inline void pkg_list(void)
+{
+ struct dirent *ent;
+ DIR *dir;
+ const char *name;
+
+ s_info.pkg_list = elm_list_add(s_info.bg);
+ if (!s_info.pkg_list)
+ return;
+
+ evas_object_resize(s_info.pkg_list, s_info.w / 3, s_info.h / 3 - 130);
+ evas_object_move(s_info.pkg_list, 0, s_info.h - (s_info.h / 3 + 30));
+ evas_object_show(s_info.pkg_list);
+
+ dir = opendir("/opt/live");
+ if (dir) {
+ Elm_Object_Item *item;
+ Evas_Object *icon;
+ //Evas_Object *button;
+ char *iconpath;
+ char *tmppath;
+ int len;
+
+ while ((ent = readdir(dir))) {
+ if (ent->d_name[0] == '.')
+ continue;
+
+ len = strlen(ent->d_name) * 2;
+ len += strlen("/opt/live/%s/libexec/liblive-%s.so");
+
+ tmppath = malloc(len + 1);
+ if (!tmppath) {
+ perror("malloc");
+ continue;
+ }
+
+ snprintf(tmppath, len, "/opt/live/%s/libexec/liblive-%s.so",
+ ent->d_name, ent->d_name);
+ if (access(tmppath, F_OK|R_OK) != 0) {
+ fprintf(stderr, "It seems that the %s is not a package\n",
+ ent->d_name);
+ free(tmppath);
+ continue;
+ }
+
+ iconpath = util_get_iconfile(tmppath);
+ if (!iconpath)
+ iconpath = strdup("nofile");
+
+ icon = NULL;
+ if (access(iconpath, R_OK|F_OK) == 0) {
+ icon = elm_icon_add(s_info.bg);
+ if (!icon || elm_icon_file_set(icon, iconpath, NULL) == EINA_FALSE) {
+ fprintf(stderr, "Failed to set icon file: %s\n", iconpath);
+ evas_object_del(icon);
+ icon = NULL;
+ }
+ }
+ free(iconpath);
+
+ len = strlen(ent->d_name);
+ while (len > 0 && ent->d_name[len] != '.')
+ len--;
+
+ if (len > 0)
+ name = ent->d_name + len + 1;
+ else
+ name = ent->d_name;
+
+ item = elm_list_item_append(s_info.pkg_list, name, icon, NULL, item_cb, NULL);
+ if (!item) {
+ if (icon)
+ evas_object_del(icon);
+ fprintf(stderr, "Failed to append a new list item\n");
+ }
+ }
+
+ closedir(dir);
+ }
+
+ elm_list_go(s_info.pkg_list);
+}
+
+static inline void group_list(void)
+{
+ register int i;
+ Elm_Object_Item *item;
+ static const char *cluster[] = {
+ "people",
+ "agenda",
+ "information",
+ "location",
+ "news_feeds",
+ "music",
+ "photos_viedos",
+ "apps",
+ "condition",
+ "user,created",
+ NULL,
+ };
+
+ static const char *category[] = {
+ "people_frequently",
+ "people_rarely",
+ "people_during",
+ "people_at",
+ "location_now",
+ "location_apps",
+ "location_appointment",
+ "music_top_track",
+ "music_recently",
+ "music_top_album",
+ "music_new_album",
+ "media_location",
+ "facebook_media",
+ "media_latest",
+ "apps_frequently",
+ "apps_location",
+ "default",
+ NULL,
+ };
+
+ s_info.c_list = elm_list_add(s_info.bg);
+ if (!s_info.c_list)
+ return;
+
+ evas_object_resize(s_info.c_list, s_info.w / 3, s_info.h / 3 - 130);
+ evas_object_move(s_info.c_list, s_info.w / 3, s_info.h - (s_info.h / 3 + 30));
+ evas_object_show(s_info.c_list);
+
+ for (i = 0; cluster[i]; i++) {
+ item = elm_list_item_append(s_info.c_list, cluster[i], NULL, NULL, cluster_cb, cluster[i]);
+ if (!item)
+ fprintf(stderr, "Failed to append a new list item\n");
+ }
+
+ elm_list_go(s_info.c_list);
+
+ s_info.s_list = elm_list_add(s_info.bg);
+ if (!s_info.s_list)
+ return;
+
+ evas_object_resize(s_info.s_list, s_info.w / 3, s_info.h / 3 - 130);
+ evas_object_move(s_info.s_list, s_info.w * 2 / 3, s_info.h - (s_info.h / 3 + 30));
+ evas_object_show(s_info.s_list);
+
+ for (i = 0; category[i]; i++) {
+ item = elm_list_item_append(s_info.s_list, category[i], NULL, NULL, category_cb, category[i]);
+ if (!item)
+ fprintf(stderr, "Failed to append a new list item\n");
+ }
+
+ elm_list_go(s_info.s_list);
+}
+
+static void btn_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ Elm_Object_Item *pkg;
+ Elm_Object_Item *c_item;
+ Elm_Object_Item *s_item;
+ const char *p_name;
+ const char *c_name;
+ const char *s_name;
+ char pkgname[PATH_MAX];
+
+ pkg = elm_list_selected_item_get(s_info.pkg_list);
+ c_item = elm_list_selected_item_get(s_info.c_list);
+ s_item = elm_list_selected_item_get(s_info.s_list);
+
+ if (pkg)
+ p_name = elm_object_item_part_text_get(pkg, "default");
+ else
+ p_name = "nicesj";
+
+ snprintf(pkgname, sizeof(pkgname), "com.samsung.%s", p_name);
+
+ if (c_item)
+ c_name = elm_object_item_part_text_get(c_item, "default");
+ else
+ c_name = "user,created";
+
+ if (s_item)
+ s_name = elm_object_item_part_text_get(s_item, "default");
+ else
+ s_name = "default";
+
+ fprintf(stderr, "pkgname: %s, c_name: %s, s_name: %s\n", pkgname, c_name, s_name);
+ fprintf(stderr, "content_info: \"default\" [FIXED]]\n");
+
+ struct livebox *handler;
+ handler = livebox_add(pkgname, "default", c_name, s_name);
+ if (!handler)
+ fprintf(stderr, "Failed to create a livebox\n");
+ fprintf(stderr, "Handler added: %p\n", handler);
+}
+
+static void pd_clicked_cb(void *data, Evas_Object *obj, void *event_info)
+{
+ const char *text;
+ Eina_List *l;
+ struct box_info *box;
+
+ l = eina_list_last(s_info.boxes);
+ if (!l)
+ return;
+
+ box = eina_list_data_get(l);
+ if (!box)
+ return;
+
+ text = elm_object_part_text_get(obj, "default");
+ if (!strcmp(text, "DestroyPD")) {
+ elm_object_part_text_set(obj, "default", "CreatePD");
+ evas_object_del(box->pd);
+ box->pd = NULL;
+ livebox_destroy_pd(box->handler);
+ } else if (!strcmp(text, "CreatePD")) {
+ if (livebox_has_pd(box->handler)) {
+ livebox_create_pd(box->handler);
+ elm_object_part_text_set(obj, "default", "DestroyPD");
+ }
+ }
+}
+
+static inline void btn(void)
+{
+ s_info.create_btn = elm_button_add(s_info.bg);
+ elm_object_part_text_set(s_info.create_btn, "default", "Create");
+ evas_object_resize(s_info.create_btn, s_info.w / 3, 100);
+ evas_object_move(s_info.create_btn, s_info.w / 3, s_info.h - 100);
+ evas_object_smart_callback_add(s_info.create_btn, "clicked", btn_clicked_cb, NULL);
+ evas_object_show(s_info.create_btn);
+
+ s_info.pd_btn = elm_button_add(s_info.bg);
+ elm_object_part_text_set(s_info.pd_btn, "default", "CreatePD");
+ evas_object_move(s_info.pd_btn, 0, s_info.h - 100);
+ evas_object_resize(s_info.pd_btn, s_info.w / 3, 100);
+ evas_object_smart_callback_add(s_info.pd_btn, "clicked", pd_clicked_cb, NULL);
+ evas_object_show(s_info.pd_btn);
+}
+
+static inline void package_list(void)
+{
+ Evas_Object *text;
+
+ text = evas_object_text_add(evas_object_evas_get(s_info.bg));
+ evas_object_text_font_set(text, "SLP:Medium", 30);
+ evas_object_text_text_set(text, "Select a package to load it");
+ evas_object_resize(text, s_info.w / 2, 30);
+ evas_object_move(text, 0, s_info.h - (s_info.h / 3));
+ evas_object_color_set(text, 255, 255, 255, 255);
+ evas_object_show(text);
+
+ pkg_list();
+ group_list();
+ btn();
+}
+
+static int shortcut_request_cb(const char *pkgname,
+ const char *name, int type,
+ const char *content, const char *icon,
+ int pid, void *data)
+{
+ struct livebox *handler;
+
+ if (livebox_is_exists(pkgname) != 1) {
+ fprintf(stderr, "%s has no livebox package\n", pkgname);
+ return -EINVAL;
+ }
+
+ handler = livebox_add(pkgname, content, "user,created", "default");
+ if (!handler) {
+ fprintf(stderr, "Failed to add a new livebox\n");
+ return -EFAULT;
+ }
+
+ fprintf(stderr, "%s - [%s] is successfully created [%p]\n", pkgname, content, handler);
+ return 0;
+}
+
+static int app_create(void *data)
+{
+ int w = 0;
+ int h = 0;
+
+ livebox_init();
+
+ s_info.win = elm_win_add(NULL, "test", ELM_WIN_BASIC);
+ if (!s_info.win)
+ return -1;
+
+ elm_win_title_set(s_info.win, "test");
+ elm_win_borderless_set(s_info.win, EINA_TRUE);
+ evas_object_smart_callback_add(s_info.win, "delete,request", win_del, NULL);
+ ecore_x_window_size_get(ecore_x_window_root_first_get(), &w, &h);
+ evas_object_resize(s_info.win, w, h);
+ s_info.w = w;
+ s_info.h = h;
+ evas_object_show(s_info.win);
+ elm_win_indicator_mode_set(s_info.win, EINA_FALSE);
+
+ s_info.bg = evas_object_rectangle_add(evas_object_evas_get(s_info.win));
+ if (s_info.bg) {
+ evas_object_color_set(s_info.bg, 0, 0, 0, 255);
+ evas_object_resize(s_info.bg, w, h);
+ evas_object_move(s_info.bg, 0, 0);
+ evas_object_show(s_info.bg);
+ }
+
+ livebox_event_handler_set(event_cb, NULL);
+ livebox_fault_handler_set(fault_cb, NULL);
+ shortcut_set_request_cb(shortcut_request_cb, NULL);
+
+ package_list();
+ return 0;
+}
+
+static int app_terminate(void *data)
+{
+ if (s_info.pd_btn)
+ evas_object_del(s_info.pd_btn);
+
+ if (s_info.create_btn)
+ evas_object_del(s_info.create_btn);
+
+ if (s_info.bg)
+ evas_object_del(s_info.bg);
+
+ if (s_info.win)
+ evas_object_del(s_info.win);
+
+ livebox_fini();
+ return 0;
+}
+
+static int app_pause(void *data)
+{
+ return 0;
+}
+
+static int app_resume(void *data)
+{
+ return 0;
+}
+
+static int app_reset(bundle *b,void *data)
+{
+ struct livebox *handler;
+ const char *pkgname;
+ const char *content;
+ const char *cluster;
+ const char *category;
+
+ if (s_info.pkgname)
+ pkgname = s_info.pkgname;
+ else
+ pkgname = "com.samsung.nicesj";
+
+ if (s_info.content)
+ content = s_info.content;
+ else
+ content = "nicesj";
+
+ if (s_info.cluster)
+ cluster = s_info.cluster;
+ else
+ cluster = "user,created";
+
+ if (s_info.category)
+ category = s_info.category;
+ else
+ category = "default";
+
+ fprintf(stderr, "pkgname: %s\n", pkgname);
+ fprintf(stderr, "content: %s\n", content);
+ fprintf(stderr, "cluster: %s\n", cluster);
+ fprintf(stderr, "category: %s\n", category);
+
+ handler = livebox_add(pkgname, content, cluster, category);
+ if (!handler)
+ fprintf(stderr, "Failed to create a livebox\n");
+
+ fprintf(stderr, "Add a new livebox!!! %p\n", handler);
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct appcore_ops ops = {
+ .create = app_create,
+ .terminate = app_terminate,
+ .pause = app_pause,
+ .resume = app_resume,
+ .reset = app_reset,
+ };
+
+ switch (argc) {
+ case 5:
+ s_info.category = strdup(argv[4]);
+ case 4:
+ s_info.cluster = strdup(argv[3]);
+ case 3:
+ s_info.content = strdup(argv[2]);
+ case 2:
+ s_info.pkgname = strdup(argv[1]);
+ case 1:
+ default:
+ break;
+ }
+
+ ops.data = NULL;
+ return appcore_efl_main("test", &argc, &argv, &ops);
+}
+
+/* End of a file */
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h> /* free */
+#include <errno.h>
+#include <string.h> /* strdup */
+#include <libgen.h>
+
+#include <gio/gio.h>
+
+#include <dlog.h>
+
+#include "debug.h"
+#include "dlist.h"
+#include "fb_file.h"
+#include "livebox.h"
+#include "livebox0.h"
+#include "dbus.h"
+#include "desc_parser.h"
+
+static struct info {
+ GDBusNodeInfo *node_info;
+ GDBusProxy *proxy;
+ struct dlist *cmd_list;
+ guint cmd_timer;
+ guint recon_timer;
+ guint reg_id;
+ const gchar *xml_data;
+} s_info = {
+ .proxy = NULL,
+ .cmd_list = NULL,
+ .cmd_timer = 0,
+ .recon_timer = 0,
+ .reg_id = 0,
+ .node_info = NULL,
+ .xml_data = "<node>"
+ "<interface name='" SERVICE_INTERFACE "'>"
+ " <method name='fault_package'>"
+ " <arg type='s' name='pkgname' direction='in' />"
+ " <arg type='s' name='filename' direction='in' />"
+ " <arg type='s' name='function' direction='in' />"
+ " <arg type='i' name='result' direction='out' />"
+ " </method>"
+ " <method name='deleted'>"
+ " <arg type='s' name='pkgname' direction='in' />"
+ " <arg type='s' name='filename' direction='in' />"
+ " <arg type='i' name='result' direction='out' />"
+ " </method>"
+ " <method name='lb_updated'>"
+ " <arg type='s' name='pkgname' direction='in' />"
+ " <arg type='s' name='filename' direction='in' />"
+ " <arg type='i' name='lb_w' direction='in' />"
+ " <arg type='i' name='lb_h' direction='in' />"
+ " <arg type='d' name='priority' direction='in' />"
+ " <arg type='i' name='result' direction='out' />"
+ " </method>"
+ " <method name='pd_updated'>"
+ " <arg type='s' name='pkgname' direction='in' />"
+ " <arg type='s' name='filename' direction='in' />"
+ " <arg type='s' name='descfile' direction='in' />"
+ " <arg type='i' name='pd_w' direction='in' />"
+ " <arg type='i' name='pd_h' direction='in' />"
+ " <arg type='i' name='result' direction='out' />"
+ " </method>"
+ " <method name='created'>"
+ " <arg type='d' name='timestamp' direction='in' />"
+ " <arg type='s' name='pkgname' direction='in' />"
+ " <arg type='s' name='filename' direction='in' />"
+ " <arg type='s' name='content' direction='in' />"
+ " <arg type='i' name='lb_w' direction='in' />"
+ " <arg type='i' name='lb_h' direction='in' />"
+ " <arg type='i' name='pd_w' direction='in' />"
+ " <arg type='i' name='pd_h' direction='in' />"
+ " <arg type='s' name='cluster' direction='in' />"
+ " <arg type='s' name='category' direction='in' />"
+ " <arg type='s' name='lb_file' direction='in' />"
+ " <arg type='s' name='pd_file' direction='in' />"
+ " <arg type='i' name='auto_launch' direction='in' />"
+ " <arg type='d' name='priority' direction='in' />"
+ " <arg type='i' name='size_list' direction='in' />"
+ " <arg type='i' name='is_user' direction='in' />"
+ " <arg type='i' name='pinup_supported' direction='in' />"
+ " <arg type='i' name='text_lb' direction='in' />"
+ " <arg type='i' name='text_pd' direction='in' />"
+ " <arg type='i' name='result' direction='out' />"
+ " </method>"
+ "</interface>"
+ "</node>",
+};
+
+struct cmd_item {
+ char *funcname;
+ GVariant *param;
+ struct livebox *handler;
+ void (*ret_cb)(struct livebox *handler, int ret, void *data);
+ void *data;
+};
+
+GDBusProxy *dbus_get_proxy(void)
+{
+ return s_info.proxy;
+}
+
+static inline int send_acquire(void)
+{
+ GVariant *param;
+ GError *err;
+
+ param = g_variant_new("(i)", getpid());
+ if (!param) {
+ ErrPrint("Failed to create variant\n");
+ return -EFAULT;
+ }
+
+ err = NULL;
+ param = g_dbus_proxy_call_sync(s_info.proxy, "acquire", param,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &err);
+ if (!param) {
+ if (err) {
+ ErrPrint("Error: %s\n", err->message);
+ g_error_free(err);
+ }
+
+ ErrPrint("Failed to send 'acquire'\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static inline int send_release(void)
+{
+ GVariant *param;
+ GError *err;
+
+ param = g_variant_new("(i)", getpid());
+ if (!param) {
+ ErrPrint("Failed to create variant\n");
+ return -EFAULT;
+ }
+
+ err = NULL;
+ param = g_dbus_proxy_call_sync(s_info.proxy, "release", param,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &err);
+
+ if (!param) {
+ if (err) {
+ ErrPrint("Error: %s\n", err->message);
+ g_error_free(err);
+ }
+
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static void on_signal(GDBusProxy *proxy, gchar *sender, gchar *signame, GVariant *param, gpointer data)
+{
+ DbgPrint("Sender: %s\n", sender);
+ DbgPrint("SigName: %s\n", signame);
+}
+
+static void done_cb(GDBusProxy *proxy, GAsyncResult *res, void *data)
+{
+ GVariant *result;
+ GError *err;
+ int r;
+ struct cmd_item *item;
+
+ item = data;
+
+ err = NULL;
+ result = g_dbus_proxy_call_finish(proxy, res, &err);
+ if (!result) {
+ if (err) {
+ DbgPrint("Error: %s\n", err->message);
+ g_error_free(err);
+ }
+
+ /*! \NOTE:
+ * Release resource even if
+ * we failed to finish the method call
+ */
+ goto out;
+ }
+
+ g_variant_get(result, "(i)", &r);
+ g_variant_unref(result);
+
+ DbgPrint("%s Returns: %d\n", item->funcname, r);
+ if (item->ret_cb)
+ item->ret_cb(item->handler, r, item->data);
+
+out:
+ g_variant_unref(item->param);
+ free(item->funcname);
+ free(item);
+}
+
+static gboolean dbus_reconnect_cb(gpointer user_data)
+{
+ dbus_init();
+ s_info.recon_timer = 0;
+ return FALSE;
+}
+
+static gboolean cmd_consumer(gpointer user_data)
+{
+ struct dlist *l;
+ struct cmd_item *item;
+
+ if (!s_info.proxy) {
+ DbgPrint("Proxy is not valid yet\n");
+ s_info.cmd_timer = 0;
+ return FALSE;
+ }
+
+ l = dlist_nth(s_info.cmd_list, 0);
+ if (l) {
+ item = dlist_data(l);
+
+ /*!
+ * \NOTE:
+ * Item will be deleted in the "done_cb"
+ */
+ g_dbus_proxy_call(s_info.proxy,
+ item->funcname,
+ g_variant_ref(item->param),
+ G_DBUS_CALL_FLAGS_NO_AUTO_START,
+ -1, NULL, (GAsyncReadyCallback)done_cb, item);
+
+ s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
+ }
+
+ if (!s_info.cmd_list) {
+ s_info.cmd_timer = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void method_fault_package(GDBusMethodInvocation *inv, GVariant *param)
+{
+ const char *pkgname;
+ const char *filename;
+ const char *function;
+ int ret;
+
+ g_variant_get(param, "(&s&s&s)", &pkgname, &filename, &function);
+
+ ret = lb_invoke_fault_handler("deactivated", pkgname, filename, function);
+
+ g_dbus_method_invocation_return_value(inv, g_variant_new("(i)", ret));
+}
+
+static void method_pd_updated(GDBusMethodInvocation *inv, GVariant *param)
+{
+ const char *pkgname;
+ const char *filename;
+ const char *descfile;
+ int ret;
+ struct livebox *handler;
+ int pd_w;
+ int pd_h;
+ int tmp_w;
+ int tmp_h;
+
+ g_variant_get(param, "(&s&s&sii)",
+ &pkgname, &filename, &descfile, &pd_w, &pd_h);
+
+ handler = lb_find_livebox(pkgname, filename);
+ if (!handler) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ livebox_get_pdsize(handler, &tmp_w, &tmp_h);
+ if (tmp_w != pd_w || tmp_h != pd_h) {
+ /* pd buffer size is updated */
+ DbgPrint("PD buffer size is changed\n");
+ }
+
+ lb_set_pdsize(handler, pd_w, pd_h);
+
+ if (lb_text_pd(handler)) {
+ ret = parse_desc(handler, filename, 1);
+ } else {
+ if (lb_get_pd_fb(handler))
+ fb_sync(lb_get_pd_fb(handler));
+
+ lb_invoke_event_handler(handler, "pd,updated");
+ ret = 0;
+ }
+out:
+ g_dbus_method_invocation_return_value(inv, g_variant_new("(i)", ret));
+}
+
+static void method_lb_updated(GDBusMethodInvocation *inv, GVariant *param)
+{
+ const char *pkgname;
+ const char *filename;
+ int ret;
+ struct livebox *handler;
+ int lb_w;
+ int lb_h;
+ int tmp_w;
+ int tmp_h;
+ double priority;
+
+ g_variant_get(param, "(&s&siid)",
+ &pkgname, &filename,
+ &lb_w, &lb_h, &priority);
+
+ handler = lb_find_livebox(pkgname, filename);
+ if (!handler) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ livebox_get_size(handler, &tmp_w, &tmp_h);
+ if (tmp_w != lb_w || tmp_h != lb_h) {
+ /* livebox buffer is updated */
+ }
+
+ if (lb_get_lb_fb(handler))
+ fb_sync(lb_get_lb_fb(handler));
+
+ lb_set_size(handler, lb_w, lb_h);
+ lb_set_priority(handler, priority);
+
+ if (lb_text_lb(handler)) {
+ ret = parse_desc(handler, filename, 0);
+ } else {
+ lb_invoke_event_handler(handler, "lb,updated");
+ ret = 0;
+ }
+
+out:
+ g_dbus_method_invocation_return_value(inv, g_variant_new("(i)", ret));
+}
+
+static void method_created(GDBusMethodInvocation *inv, GVariant *param)
+{
+ struct livebox *handler;
+ const char *pkgname;
+ const char *filename;
+ int lb_w;
+ int lb_h;
+ int pd_w;
+ int pd_h;
+ const char *content;
+ const char *cluster;
+ const char *category;
+ const char *lb_fname;
+ const char *pd_fname;
+ double timestamp;
+ int auto_launch;
+ int ret;
+ double priority;
+ int size_list;
+ int user;
+ int pinup_supported;
+ int text_lb;
+ int text_pd;
+
+ g_variant_get(param, "(d&s&s&siiii&s&s&s&sidiiiii)",
+ ×tamp,
+ &pkgname, &filename, &content,
+ &lb_w, &lb_h, &pd_w, &pd_h,
+ &cluster, &category, &lb_fname, &pd_fname,
+ &auto_launch, &priority, &size_list, &user, &pinup_supported,
+ &text_lb, &text_pd);
+
+ DbgPrint("[%lf] pkgname: %s, filename: %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: %d, priority: %lf, size_list: %d, user: %d, pinup: %d"
+ "text_lb: %d, text_pd: %d\n",
+ timestamp, pkgname, filename, content,
+ pd_w, pd_h, lb_w, lb_h,
+ cluster, category, lb_fname, pd_fname,
+ auto_launch, priority, size_list, user, pinup_supported,
+ text_lb, text_pd);
+
+ handler = lb_find_livebox_by_timestamp(timestamp);
+ if (!handler) {
+ DbgPrint("create a new livebox instance\n");
+ handler = lb_new_livebox(pkgname, filename);
+ if (!handler) {
+ ErrPrint("Failed to create a new livebox\n");
+ ret = -EFAULT;
+ goto out;
+ }
+ } else {
+ lb_set_filename(handler, filename);
+ }
+
+ lb_set_lb_fb(handler, lb_fname, lb_w, lb_h);
+ lb_set_pd_fb(handler, pd_fname, lb_w, lb_h);
+
+ lb_set_size(handler, lb_w, lb_h);
+ lb_set_pdsize(handler, pd_w, pd_h);
+ lb_set_priority(handler, priority);
+
+ lb_set_size_list(handler, size_list);
+ lb_set_group(handler, cluster, category);
+ lb_set_content(handler, content);
+ lb_set_user(handler, user);
+
+ lb_set_auto_launch(handler, auto_launch);
+ lb_set_pinup(handler, pinup_supported);
+
+ lb_invoke_event_handler(handler, "lb,created");
+
+ ret = 0;
+out:
+ g_dbus_method_invocation_return_value(inv, g_variant_new("(i)", ret));
+}
+
+static void method_deleted(GDBusMethodInvocation *inv, GVariant *param)
+{
+ const char *pkgname;
+ const char *filename;
+ struct livebox *handler;
+ int ret;
+
+ g_variant_get(param, "(&s&s)", &pkgname, &filename);
+
+ handler = lb_find_livebox(pkgname, filename);
+ if (!handler) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ lb_invoke_event_handler(handler, "lb,deleted");
+
+ /* Just try to delete it, if a user didn't remove it from the live box list */
+ livebox_del(handler, 0);
+
+ ret = 0;
+out:
+ g_dbus_method_invocation_return_value(inv, g_variant_new("(i)", ret));
+}
+
+static void method_handler(GDBusConnection *conn,
+ const gchar *sender,
+ const gchar *object_path,
+ const gchar *iface_name,
+ const gchar *method,
+ GVariant *param,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ register int i;
+ struct method_table {
+ const char *name;
+ void (*method)(GDBusMethodInvocation *inv, GVariant *param);
+ } method_table[] = {
+ {
+ .name = "created",
+ .method = method_created,
+ },
+ {
+ .name = "deleted",
+ .method = method_deleted,
+ },
+ {
+ .name = "lb_updated",
+ .method = method_lb_updated,
+ },
+ {
+ .name = "pd_updated",
+ .method = method_pd_updated,
+ },
+ {
+ .name = "fault_package",
+ .method = method_fault_package,
+ },
+ {
+ .name = NULL,
+ .method = NULL,
+ },
+ };
+
+ for (i = 0; method_table[i].name; i++) {
+ if (!g_strcmp0(method, method_table[i].name)) {
+ if (!method_table[i].method) {
+ DbgPrint("Method %s is not available\n", method_table[i].name);
+ break;
+ }
+
+ method_table[i].method(invocation, param);
+ break;
+ }
+ }
+
+ DbgPrint("Method[%s] is processed\n", method);
+}
+
+static const GDBusInterfaceVTable iface_vtable = {
+ method_handler,
+ NULL,
+ NULL,
+};
+
+static inline void register_dbus_object(void)
+{
+ GError *err;
+ GDBusConnection *conn;
+
+ conn = g_dbus_proxy_get_connection(s_info.proxy);
+ if (!conn) {
+ g_object_unref(s_info.proxy);
+ s_info.proxy = NULL;
+ return;
+ }
+
+ err = NULL;
+ s_info.node_info = g_dbus_node_info_new_for_xml(s_info.xml_data, &err);
+ if (!s_info.node_info) {
+ if (err) {
+ ErrPrint("error - %s\n", err->message);
+ g_error_free(err);
+ }
+ return;
+ }
+
+ err = NULL;
+ s_info.reg_id = g_dbus_connection_register_object(conn,
+ OBJECT_PATH,
+ s_info.node_info->interfaces[0],
+ &iface_vtable,
+ NULL, NULL,
+ &err);
+ if (s_info.reg_id <= 0) {
+ if (err) {
+ DbgPrint("Register: %s\n", err->message);
+ g_error_free(err);
+ }
+
+ g_object_unref(s_info.proxy);
+ s_info.proxy = NULL;
+ return;
+ }
+
+ DbgPrint("Registered: %d\n", s_info.reg_id);
+}
+
+static void got_proxy_cb(GObject *obj, GAsyncResult *res, gpointer user_data)
+{
+ GError *err;
+
+ err = NULL;
+ s_info.proxy = g_dbus_proxy_new_for_bus_finish(res, &err);
+ if (!s_info.proxy) {
+ if (err) {
+ ErrPrint("Error: %s\n", err->message);
+ g_error_free(err);
+ }
+
+ if (!s_info.recon_timer)
+ s_info.recon_timer = g_timeout_add(1000, dbus_reconnect_cb, NULL);
+ return;
+ }
+
+ g_signal_connect(s_info.proxy, "g-signal", G_CALLBACK(on_signal), NULL);
+ register_dbus_object();
+ send_acquire();
+
+ if (s_info.cmd_list && !s_info.cmd_timer) {
+ DbgPrint("10ms timer is adding\n");
+ s_info.cmd_timer = g_timeout_add(10, cmd_consumer, NULL);
+ if (!s_info.cmd_timer)
+ ErrPrint("Failed to add timer\n");
+ }
+}
+
+int dbus_sync_command(const char *funcname, GVariant *param)
+{
+ GError *err;
+ int ret;
+
+ err = NULL;
+ param = g_dbus_proxy_call_sync(s_info.proxy, funcname, param,
+ G_DBUS_CALL_FLAGS_NO_AUTO_START, -1, NULL, &err);
+ if (!param) {
+ if (err) {
+ ErrPrint("funcname: %s, Error: %s\n", funcname, err->message);
+ g_error_free(err);
+ }
+
+ return -EIO;
+ }
+
+ g_variant_get(param, "(i)", &ret);
+ g_variant_unref(param);
+
+ return ret;
+}
+
+int dbus_push_command(struct livebox *handler, const char *funcname, GVariant *param, void (*ret_cb)(struct livebox *handler, int ret, void *data), void *data)
+{
+ struct cmd_item *item;
+
+ item = malloc(sizeof(*item));
+ if (!item) {
+ ErrPrint("Failed to allocate mem for cmd_item\n");
+ return -ENOMEM;
+ }
+
+ item->funcname = strdup(funcname);
+ if (!item->funcname) {
+ ErrPrint("Failed to allocate mem for funcname - %s\n", funcname);
+ free(item);
+ return -ENOMEM;
+ }
+
+ item->param = param;
+ item->handler = handler;
+ item->ret_cb = ret_cb;
+ item->data = data;
+
+ s_info.cmd_list = dlist_append(s_info.cmd_list, item);
+
+ if (!s_info.cmd_timer && s_info.proxy) {
+ DbgPrint("10ms timer is adding\n");
+ s_info.cmd_timer = g_timeout_add(10, cmd_consumer, NULL);
+ if (!s_info.cmd_timer)
+ ErrPrint("Failed to add timer\n");
+ }
+
+ return 0;
+}
+
+int dbus_init(void)
+{
+ g_dbus_proxy_new_for_bus(BUS_TYPE,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ SERVICE_NAME,
+ OBJECT_PATH,
+ SERVICE_INTERFACE,
+ NULL,
+ got_proxy_cb, NULL);
+
+ return 0;
+}
+
+int dbus_fini(void)
+{
+ if (s_info.proxy) {
+ GDBusConnection *conn;
+
+ send_release();
+
+ conn = g_dbus_proxy_get_connection(s_info.proxy);
+ if (conn) {
+ /* FIXME: Do I really need to do this? */
+ g_dbus_connection_unregister_object(conn, s_info.reg_id);
+ s_info.reg_id = 0;
+ }
+
+ g_object_unref(s_info.proxy);
+ s_info.proxy = NULL;
+ }
+
+ if (s_info.node_info) {
+ g_dbus_node_info_unref(s_info.node_info);
+ s_info.node_info = NULL;
+ }
+
+ return 0;
+}
+
+/* End of a file */
--- /dev/null
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h> /* malloc */
+#include <string.h> /* strdup */
+#include <ctype.h>
+#include <libgen.h>
+
+#include <dlog.h>
+
+#include "debug.h"
+#include "livebox.h"
+#include "livebox0.h"
+#include "desc_parser.h"
+#include "dlist.h"
+
+#define TYPE_TEXT "text"
+#define TYPE_IMAGE "image"
+#define TYPE_EDJE "edje"
+#define TYPE_SIGNAL "signal"
+#define TYPE_INFO "info"
+#define TYPE_DRAG "drag"
+
+#define INFO_SIZE "size"
+#define INFO_CATEGORY "category"
+
+struct block {
+ char *type;
+ int type_len;
+
+ char *part;
+ int part_len;
+
+ char *data;
+ int data_len;
+
+ char *file;
+ int file_len;
+
+ char *group;
+ int group_len;
+
+ char *id;
+ int id_len;
+};
+
+static int update_text(struct livebox *handle, struct block *block, int is_pd)
+{
+ struct livebox_script_operators *ops;
+
+ if (!block || !block->part || !block->data)
+ return -EINVAL;
+
+ ops = is_pd ? &handle->pd_ops : &handle->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)
+ return -EINVAL;
+
+ ops = is_pd ? &handle->pd_ops : &handle->ops;
+ if (ops->update_image)
+ ops->update_image(handle, block->id, block->part, block->data);
+
+ return 0;
+}
+
+static int update_edje(struct livebox *handle, struct block *block, int is_pd)
+{
+ struct livebox_script_operators *ops;
+ if (!block || !block->part)
+ return -EINVAL;
+
+ ops = is_pd ? &handle->pd_ops : &handle->ops;
+ if (ops->update_edje)
+ ops->update_edje(handle, block->id, block->part, block->data, block->group);
+
+ return 0;
+}
+
+static int update_signal(struct livebox *handle, struct block *block, int is_pd)
+{
+ struct livebox_script_operators *ops;
+
+ if (!block)
+ return -EINVAL;
+
+ ops = is_pd ? &handle->pd_ops : &handle->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)
+ return -EINVAL;
+
+ ops = is_pd ? &handle->pd_ops : &handle->ops;
+
+ if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
+ ErrPrint("Invalid format of data\n");
+ return -EINVAL;
+ }
+
+ 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)
+ return -EINVAL;
+
+
+ ops = is_pd ? &handle->pd_ops : &handle->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 -EINVAL;
+ }
+
+ 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 inline int update_begin(struct livebox *handle, int is_pd)
+{
+ struct livebox_script_operators *ops;
+
+ ops = is_pd ? &handle->pd_ops : &handle->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->pd_ops : &handle->ops;
+
+ if (ops->update_end)
+ ops->update_end(handle);
+
+ return 0;
+}
+
+int parse_desc(struct livebox *handle, const char *descfile, int is_pd)
+{
+ FILE *fp;
+ int ch;
+ const char *filename;
+ enum state {
+ UNKNOWN = 0x10,
+ BLOCK_OPEN = 0x11,
+ FIELD = 0x12,
+ VALUE = 0x13,
+ BLOCK_CLOSE = 0x14,
+
+ VALUE_TYPE = 0x00,
+ VALUE_PART = 0x01,
+ VALUE_DATA = 0x02,
+ VALUE_FILE = 0x03,
+ VALUE_GROUP = 0x04,
+ VALUE_ID = 0x05,
+ };
+ const char *field_name[] = {
+ "type",
+ "part",
+ "data",
+ "file",
+ "group",
+ "id",
+ NULL
+ };
+ enum state state;
+ register int field_idx;
+ register int idx = 0;
+ register int i;
+ struct block *block;
+ struct {
+ const char *type;
+ int (*handler)(struct livebox *handle, struct block *block, int is_pd);
+ } handlers[] = {
+ {
+ .type = TYPE_TEXT,
+ .handler = update_text,
+ },
+ {
+ .type = TYPE_IMAGE,
+ .handler = update_image,
+ },
+ {
+ .type = TYPE_EDJE,
+ .handler = update_edje,
+ },
+ {
+ .type = TYPE_SIGNAL,
+ .handler = update_signal,
+ },
+ {
+ .type = TYPE_DRAG,
+ .handler = update_drag,
+ },
+ {
+ .type = TYPE_INFO,
+ .handler = update_info,
+ },
+ {
+ .type = NULL,
+ .handler = NULL,
+ },
+ };
+
+ fp = fopen(descfile, "rt");
+ if (!fp) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ return -EIO;
+ }
+
+ update_begin(handle, is_pd);
+
+ filename = handle->filename;
+
+ state = UNKNOWN;
+ field_idx = 0;
+
+ block = NULL;
+ while (!feof(fp)) {
+ ch = getc(fp);
+
+ switch (state) {
+ case UNKNOWN:
+ if (ch == '{') {
+ state = BLOCK_OPEN;
+ break;
+ }
+
+ if (!isspace(ch)) {
+ update_end(handle, is_pd);
+ fclose(fp);
+ return -EINVAL;
+ }
+ break;
+
+ case BLOCK_OPEN:
+ if (isblank(ch))
+ break;
+
+ if (ch != '\n')
+ goto errout;
+
+ block = calloc(1, sizeof(*block));
+ if (!block) {
+ ErrPrint("Heap: %s\n", strerror(errno));
+ update_end(handle, is_pd);
+ fclose(fp);
+ return -ENOMEM;
+ }
+
+ state = FIELD;
+ idx = 0;
+ field_idx = 0;
+ break;
+
+ case FIELD:
+ if (isspace(ch))
+ break;
+
+ if (ch == '}') {
+ state = BLOCK_CLOSE;
+ break;
+ }
+
+ if (ch == '=') {
+ if (field_name[field_idx][idx] != '\0')
+ goto errout;
+
+ switch (field_idx) {
+ case 0:
+ state = VALUE_TYPE;
+ if (block->type) {
+ free(block->type);
+ block->type = NULL;
+ block->type_len = 0;
+ }
+ idx = 0;
+ break;
+ case 1:
+ state = VALUE_PART;
+ if (block->part) {
+ free(block->part);
+ block->part = NULL;
+ block->part_len = 0;
+ }
+ idx = 0;
+ break;
+ case 2:
+ state = VALUE_DATA;
+ if (block->data) {
+ free(block->data);
+ block->data = NULL;
+ block->data_len = 0;
+ }
+ idx = 0;
+ break;
+ case 3:
+ state = VALUE_FILE;
+ if (block->file) {
+ free(block->file);
+ block->file = NULL;
+ block->file_len = 0;
+ }
+ idx = 0;
+ break;
+ case 4:
+ state = VALUE_GROUP;
+ if (block->group) {
+ free(block->group);
+ block->group = NULL;
+ block->group_len = 0;
+ }
+ idx = 0;
+ break;
+ case 5:
+ state = VALUE_ID;
+ if (block->id) {
+ free(block->id);
+ block->id = NULL;
+ block->id_len = 0;
+ }
+ idx = 0;
+ break;
+ default:
+ goto errout;
+ }
+
+ break;
+ }
+
+ if (ch == '\n')
+ goto errout;
+
+ if (field_name[field_idx][idx] != ch) {
+ ungetc(ch, fp);
+ while (--idx >= 0)
+ ungetc(field_name[field_idx][idx], fp);
+
+ field_idx++;
+ if (field_name[field_idx] == NULL)
+ goto errout;
+
+ idx = 0;
+ break;
+ }
+
+ idx++;
+ break;
+
+ case VALUE_TYPE:
+ if (idx == block->type_len) {
+ block->type_len += 256;
+ block->type =
+ realloc(block->type, block->type_len);
+ if (!block->type)
+ goto errout;
+ }
+
+ if (ch == '\n') {
+ block->type[idx] = '\0';
+ state = FIELD;
+ idx = 0;
+ field_idx = 0;
+ break;
+ }
+
+ block->type[idx] = ch;
+ idx++;
+ break;
+
+ case VALUE_PART:
+ if (idx == block->part_len) {
+ block->part_len += 256;
+ block->part =
+ realloc(block->part, block->part_len);
+ if (!block->part)
+ goto errout;
+ }
+
+ if (ch == '\n') {
+ block->part[idx] = '\0';
+ state = FIELD;
+ idx = 0;
+ field_idx = 0;
+ break;
+ }
+
+ block->part[idx] = ch;
+ idx++;
+ break;
+
+ case VALUE_DATA:
+ if (idx == block->data_len) {
+ block->data_len += 256;
+ block->data =
+ realloc(block->data, block->data_len);
+ if (!block->data)
+ goto errout;
+ }
+
+ if (ch == '\n') {
+ block->data[idx] = '\0';
+ state = FIELD;
+ idx = 0;
+ field_idx = 0;
+ break;
+ }
+
+ block->data[idx] = ch;
+ idx++;
+ break;
+
+ case VALUE_FILE:
+ if (idx == block->file_len) {
+ block->file_len += 256;
+ block->file =
+ realloc(block->file, block->file_len);
+ if (!block->file)
+ goto errout;
+ }
+
+ if (ch == '\n') {
+ block->file[idx] = '\0';
+ state = FIELD;
+ idx = 0;
+ field_idx = 0;
+ break;
+ }
+
+ block->file[idx] = ch;
+ idx++;
+ break;
+
+ case VALUE_GROUP:
+ if (idx == block->group_len) {
+ block->group_len += 256;
+ block->group = realloc(block->group,
+ block->group_len);
+ if (!block->group)
+ goto errout;
+ }
+
+ if (ch == '\n') {
+ block->group[idx] = '\0';
+ state = FIELD;
+ idx = 0;
+ field_idx = 0;
+ break;
+ }
+
+ block->group[idx] = ch;
+ idx++;
+ break;
+ case VALUE_ID:
+ if (idx == block->id_len) {
+ block->id_len += 256;
+ block->id = realloc(block->id, block->id_len);
+ if (!block->id)
+ goto errout;
+ }
+
+ if (ch == '\n') {
+ block->id[idx] = '\0';
+ state = FIELD;
+ idx = 0;
+ field_idx = 0;
+ break;
+ }
+
+ block->id[idx] = ch;
+ idx++;
+ break;
+ case BLOCK_CLOSE:
+ if (!block->file) {
+ block->file = strdup(filename);
+ if (!block->file)
+ goto errout;
+ }
+
+ i = 0;
+ while (handlers[i].type) {
+ if (!strcasecmp(handlers[i].type, block->type)) {
+ handlers[i].handler(handle, block, is_pd);
+ break;
+ }
+ i++;
+ }
+
+ if (!handlers[i].type)
+ ErrPrint("Unknown block type: %s\n", block->type);
+
+ free(block->file);
+ free(block->type);
+ free(block->part);
+ free(block->data);
+ free(block->group);
+ free(block->id);
+ free(block);
+
+ state = UNKNOWN;
+ break;
+
+ default:
+ break;
+ } /* switch */
+ } /* while */
+
+ if (state != UNKNOWN)
+ goto errout;
+
+ update_end(handle, is_pd);
+
+ fclose(fp);
+ return 0;
+
+errout:
+ ErrPrint("Parse error\n");
+ if (block) {
+ free(block->file);
+ free(block->type);
+ free(block->part);
+ free(block->data);
+ free(block->group);
+ free(block->id);
+ free(block);
+ }
+
+ update_end(handle, is_pd);
+
+ fclose(fp);
+ return -EINVAL;
+}
+
+/* End of a file */
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "dlist.h"
+
+struct dlist {
+ struct dlist *next;
+ struct dlist *prev;
+ void *data;
+};
+
+struct dlist *dlist_append(struct dlist *list, void *data)
+{
+ struct dlist *item;
+
+ item = malloc(sizeof(*item));
+ if (!item)
+ return NULL;
+
+ item->next = NULL;
+ item->data = data;
+
+ if (!list) {
+ item->prev = item;
+
+ list = item;
+ } else {
+ item->prev = list->prev;
+ item->prev->next = item;
+
+ list->prev = item;
+ }
+
+ assert(!list->prev->next && "item NEXT");
+
+ return list;
+}
+
+struct dlist *dlist_prepend(struct dlist *list, void *data)
+{
+ struct dlist *item;
+
+ item = malloc(sizeof(*item));
+ if (!item)
+ return NULL;
+
+ if (!list) {
+ item->prev = item;
+ item->next = NULL;
+ } else {
+ item->prev = list->prev;
+ list->prev = item;
+ item->next = list;
+ }
+
+ return item;
+}
+
+struct dlist *dlist_remove(struct dlist *list, struct dlist *l)
+{
+ if (!list || !l)
+ return NULL;
+
+ if (l == list) {
+ l->prev = list->prev;
+ list = l->next;
+ } else {
+ l->prev->next = l->next;
+ }
+
+ if (l->next)
+ l->next->prev = l->prev;
+
+ free(l);
+ return list;
+}
+
+struct dlist *dlist_find_data(struct dlist *list, void *data)
+{
+ struct dlist *l;
+ void *_data;
+
+ dlist_foreach(list, l, _data) {
+ if (data == _data)
+ return l;
+ }
+
+ return NULL;
+}
+
+void *dlist_data(struct dlist *l)
+{
+ return l ? l->data : NULL;
+}
+
+struct dlist *dlist_next(struct dlist *l)
+{
+ return l ? l->next : NULL;
+}
+
+struct dlist *dlist_prev(struct dlist *l)
+{
+ return l ? l->prev : NULL;
+}
+
+int dlist_count(struct dlist *l)
+{
+ register int i;
+ struct dlist *n;
+ void *data;
+
+ i = 0;
+ dlist_foreach(l, n, data) {
+ i++;
+ }
+
+ return i;
+}
+
+struct dlist *dlist_nth(struct dlist *l, int nth)
+{
+ register int i;
+ struct dlist *n;
+ void *data;
+
+ i = 0;
+ dlist_foreach(l, n, data) {
+ if (i == nth)
+ return l;
+
+ i++;
+ }
+
+ return NULL;
+}
+
+/* End of a file */
--- /dev/null
+#include <stdio.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <libgen.h>
+
+#include <dlog.h>
+
+#include "debug.h"
+
+int errno;
+
+struct fb_info {
+ char *filename;
+ int w;
+ int h;
+ int bufsz;
+ int fd;
+ void *buffer;
+ int created;
+};
+
+int fb_init(void)
+{
+ return 0;
+}
+
+int fb_fini(void)
+{
+ return 0;
+}
+
+static inline struct flock *file_lock(short type, short whence)
+{
+ static struct flock ret;
+
+ ret.l_type = type;
+ ret.l_start = 0;
+ ret.l_whence = whence;
+ ret.l_len = 0;
+ ret.l_pid = getpid();
+ return &ret;
+}
+
+int fb_sync(struct fb_info *info)
+{
+ if (info->fd < 0 || !info->buffer)
+ return -EINVAL;
+
+// fcntl(info->fd, F_SETLKW, file_lock(F_RDLCK, SEEK_SET));
+ if (lseek(info->fd, 0l, SEEK_SET) != 0) {
+ ErrPrint("seek: %s\n", strerror(errno));
+// fcntl(info->fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));
+ return -EIO;
+ }
+
+ if (read(info->fd, info->buffer, info->bufsz) != info->bufsz) {
+ ErrPrint("read: %s\n", strerror(errno));
+// fcntl(info->fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));
+ return -EIO;
+ }
+// fcntl(info->fd, F_SETLKW, file_lock(F_UNLCK, SEEK_SET));
+
+ return 0;
+}
+
+struct fb_info *fb_create(const char *filename, int w, int h)
+{
+ struct fb_info *info;
+
+ if (!filename || filename[0] == '\0')
+ return NULL;
+
+ info = calloc(1, sizeof(*info));
+ if (!info) {
+ ErrPrint("Memory: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ info->filename = strdup(filename);
+ if (!info->filename) {
+ ErrPrint("Memory: %s\n", strerror(errno));
+ free(info);
+ return NULL;
+ }
+
+ info->fd = -EINVAL;
+ info->bufsz = -EINVAL;
+ info->buffer = NULL;
+ info->w = w;
+ info->h = h;
+ info->created = 0;
+
+ return info;
+}
+
+int fb_create_buffer(struct fb_info *info)
+{
+ if (!info)
+ return -EINVAL;
+
+ if (info->created == 1)
+ return -EALREADY;
+
+ info->fd = open(info->filename, O_RDWR);
+ if (info->fd < 0) {
+ ErrPrint("Open: %s\n", strerror(errno));
+ return -EIO;
+ }
+
+ info->bufsz = lseek(info->fd, 0l, SEEK_END);
+ if (info->bufsz < 0) {
+ ErrPrint("lseek: %s\n", strerror(errno));
+ close(info->fd);
+ info->fd = -EINVAL;
+ return -EIO;
+ }
+
+ lseek(info->fd, 0l, SEEK_SET);
+
+ info->buffer = calloc(1, info->bufsz);
+ if (!info->buffer) {
+ ErrPrint("calloc: %s\n", strerror(errno));
+ close(info->fd);
+ info->fd = -EINVAL;
+ return -ENOMEM;
+ }
+
+ info->created = 1;
+ return 0;
+}
+
+int fb_destroy_buffer(struct fb_info *info)
+{
+ if (!info)
+ return -EINVAL;
+
+ if (info->created != 1)
+ return -EINVAL;
+
+ if (info->fd > 0) {
+ close(info->fd);
+ info->fd = -EINVAL;
+ }
+
+ if (info->buffer) {
+ free(info->buffer);
+ info->buffer = NULL;
+ }
+
+ info->created = 0;
+ return 0;
+}
+
+int fb_destroy(struct fb_info *info)
+{
+ if (!info || info->created)
+ return -EINVAL;
+
+ free(info->filename);
+ free(info);
+ return 0;
+}
+
+int fb_is_created(struct fb_info *info)
+{
+ if (!info)
+ return -EINVAL;
+
+ return info->created;
+}
+
+void *fb_buffer(struct fb_info *info)
+{
+ return info ? info->buffer : NULL;
+}
+
+const char *fb_filename(struct fb_info *info)
+{
+ return info ? info->filename : NULL;
+}
+
+int fb_get_size(struct fb_info *info, int *w, int *h)
+{
+ if (!info)
+ return -EINVAL;
+
+ *w = info->w;
+ *h = info->h;
+ return 0;
+}
+
+int fb_size(struct fb_info *info)
+{
+ return info->bufsz;
+}
+/* End of a file */
--- /dev/null
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h> /* malloc */
+#include <string.h> /* strdup */
+#include <libgen.h>
+
+#include <gio/gio.h>
+
+#include <aul.h>
+#include <dlog.h>
+
+#include "debug.h"
+#include "fb_file.h"
+#include "livebox.h"
+#include "livebox0.h"
+#include "dlist.h"
+#include "util.h"
+#include "dbus.h"
+
+#define EAPI __attribute__((visibility("default")))
+
+#if defined(FLOG)
+FILE *__file_log_fp;
+#endif
+
+struct info {
+ struct dlist *livebox_list;
+ struct dlist *event_list;
+ struct dlist *fault_list;
+} s_info = {
+ .livebox_list = NULL,
+ .event_list = NULL,
+ .fault_list = NULL,
+};
+
+struct event_info {
+ int (*handler)(struct livebox *handler, const char *event, void *data);
+ void *user_data;
+};
+
+struct fault_info {
+ int (*handler)(const char *event, const char *pkgname, const char *filename, const char *func, void *data);
+ void *user_data;
+};
+
+EAPI int livebox_init(void)
+{
+#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
+
+ dbus_init();
+ return 0;
+}
+
+EAPI int livebox_fini(void)
+{
+ dbus_fini();
+ return 0;
+}
+
+static void event_ret_cb(struct livebox *handler, int ret, void *data)
+{
+ if (ret < 0) {
+ lb_invoke_event_handler(handler, "event,ignored");
+ } else {
+ }
+}
+
+static void ret_cb(struct livebox *handler, int ret, void *data)
+{
+ if (ret < 0) {
+ lb_invoke_event_handler(handler, "lb,deleted");
+ livebox_del(handler, 0);
+ } else {
+ }
+}
+
+EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category)
+{
+ struct livebox *handler;
+ GVariant *param;
+ int ret;
+
+ if (!pkgname || !cluster || !category)
+ return NULL;
+
+ handler = calloc(1, sizeof(*handler));
+ if (!handler) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ handler->pkgname = strdup(pkgname);
+ if (!handler->pkgname) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ free(handler);
+ return NULL;
+ }
+
+ if (content) {
+ handler->content = strdup(content);
+ if (!handler->content) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ free(handler->pkgname);
+ free(handler);
+ return NULL;
+ }
+ }
+
+ handler->cluster = strdup(cluster);
+ if (!handler->cluster) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ free(handler->content);
+ free(handler->pkgname);
+ free(handler);
+ return NULL;
+ }
+
+ handler->category = strdup(category);
+ if (!handler->category) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ free(handler->cluster);
+ free(handler->content);
+ free(handler->pkgname);
+ free(handler);
+ return NULL;
+ }
+
+ /* Data provider will set this */
+ handler->data_type = FILEDATA;
+
+ /* Cluster infomration is not determined yet */
+ handler->nr_of_sizes = 0x01;
+
+ handler->timestamp = util_get_timestamp();
+
+ s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
+
+ param = g_variant_new("(dssss)", handler->timestamp, pkgname, content, cluster, category);
+ if (!param) {
+ free(handler->category);
+ free(handler->cluster);
+ free(handler->content);
+ free(handler->pkgname);
+ free(handler);
+ return NULL;
+ }
+
+ ret = dbus_push_command(handler, "new", param, ret_cb, handler);
+ if (ret < 0) {
+ free(handler->category);
+ free(handler->cluster);
+ free(handler->content);
+ free(handler->pkgname);
+ free(handler);
+ g_variant_unref(param);
+ return NULL;
+ }
+
+ return handler;
+}
+
+EAPI int livebox_del(struct livebox *handler, int server)
+{
+ if (!handler)
+ return -EINVAL;
+
+ if (server) {
+ GVariant *param;
+ int ret;
+
+ param = g_variant_new("(ss)", handler->pkgname, handler->filename);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, "delete", param, ret_cb, handler);
+ if (ret < 0) {
+ g_variant_unref(param);
+ return ret;
+ }
+
+ return 0;
+ }
+
+ dlist_remove_data(s_info.livebox_list, handler);
+
+ free(handler->cluster);
+ free(handler->category);
+ free(handler->filename);
+ free(handler->pkgname);
+
+ if (handler->lb_fb) {
+ fb_destroy_buffer(handler->lb_fb);
+ fb_destroy(handler->lb_fb);
+ handler->lb_fb = NULL;
+ }
+
+ if (handler->pd_fb) {
+ fb_destroy_buffer(handler->pd_fb);
+ fb_destroy(handler->pd_fb);
+ handler->pd_fb = NULL;
+ }
+
+ return 0;
+}
+
+EAPI int livebox_fault_handler_set(int (*cb)(const char *, const char *, const char *, const char *, void *), void *data)
+{
+ struct fault_info *info;
+
+ if (!cb)
+ return -EINVAL;
+
+ info = malloc(sizeof(*info));
+ if (!info)
+ return -ENOMEM;
+
+ info->handler = cb;
+ info->user_data = data;
+
+ s_info.fault_list = dlist_append(s_info.fault_list, info);
+ return 0;
+}
+
+EAPI void *livebox_fault_handler_unset(int (*cb)(const char *, 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;
+ s_info.fault_list = dlist_remove(s_info.fault_list, l);
+ data = info->user_data;
+ free(info);
+
+ return data;
+ }
+ }
+
+ return NULL;
+}
+
+EAPI int livebox_event_handler_set(int (*cb)(struct livebox *, const char *, void *), void *data)
+{
+ struct event_info *info;
+
+ DbgPrint("event callback adding\n");
+ if (!cb)
+ return -EINVAL;
+
+ DbgPrint("event callback cb found, adding\n");
+ info = malloc(sizeof(*info));
+ if (!info)
+ return -ENOMEM;
+
+ info->handler = cb;
+ info->user_data = data;
+
+ s_info.event_list = dlist_append(s_info.event_list, info);
+ DbgPrint("event callback added\n");
+ return 0;
+}
+
+EAPI void *livebox_event_handler_unset(int (*cb)(struct livebox *, const char *, void *))
+{
+ struct event_info *info;
+ struct dlist *l;
+
+ dlist_foreach(s_info.event_list, l, info) {
+ if (info->handler == cb) {
+ void *data;
+
+ s_info.event_list = dlist_remove(s_info.event_list, l);
+ data = info->user_data;
+ free(info);
+
+ return data;
+ }
+ }
+
+ return NULL;
+}
+
+EAPI int livebox_resize(struct livebox *handler, int w, int h)
+{
+ GVariant *param;
+ int ret;
+
+ if (!handler)
+ return -EINVAL;
+
+ param = g_variant_new("(ssii)", handler->pkgname, handler->filename, w, h);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, "resize", param, event_ret_cb, handler);
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+EAPI int livebox_click(struct livebox *handler, double x, double y)
+{
+ GVariant *param;
+ double timestamp;
+ int ret;
+
+ if (!handler)
+ return -EINVAL;
+
+ if (handler->auto_launch)
+ if (aul_launch_app(handler->pkgname, NULL) < 0)
+ ErrPrint("Failed to launch app %s\n", handler->pkgname);
+
+ timestamp = util_get_timestamp();
+ param = g_variant_new("(sssddd)", handler->pkgname, handler->filename, "clicked", timestamp, x, y);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, "clicked", param, event_ret_cb, handler);
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+static inline int send_mouse_event(struct livebox *handler, const char *event, double x, double y)
+{
+ GVariant *param;
+ double timestamp;
+ int ret;
+
+ timestamp = util_get_timestamp();
+ param = g_variant_new("(ssiiddd)", handler->pkgname, handler->filename,
+ handler->pd_w, handler->pd_h,
+ timestamp, x, y);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, event, param, event_ret_cb, handler);
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+EAPI int livebox_has_pd(struct livebox *handler)
+{
+ if (!handler)
+ return -EINVAL;
+
+ return !!handler->pd_fb;
+}
+
+EAPI int livebox_pd_is_created(struct livebox *handler)
+{
+ if (!handler || !handler->pd_fb)
+ return -EINVAL;
+
+ return fb_is_created(handler->pd_fb);
+}
+
+static void pd_created_cb(struct livebox *handler, int ret, void *data)
+{
+ if (ret == 0) {
+ fb_create_buffer(data);
+ lb_invoke_event_handler(handler, "pd,created");
+ } else {
+ lb_invoke_event_handler(handler, "pd,create,failed");
+ }
+}
+
+static void activated_cb(struct livebox *handler, int ret, void *data)
+{
+ char *pkgname = data;
+
+ if (ret == 0)
+ lb_invoke_fault_handler("activated", pkgname, NULL, NULL);
+ else if (ret == -EINVAL)
+ lb_invoke_fault_handler("invalid,request", pkgname, NULL, NULL);
+ else
+ lb_invoke_fault_handler("activation,failed", pkgname, NULL, NULL);
+
+ free(pkgname);
+}
+
+EAPI int livebox_create_pd(struct livebox *handler)
+{
+ GVariant *param;
+ int ret;
+
+ if (!handler || !handler->pd_fb)
+ return -EINVAL;
+
+ if (fb_is_created(handler->pd_fb) == 1)
+ return 0;
+
+ param = g_variant_new("(ss)", handler->pkgname, handler->filename);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, "create_pd", param, pd_created_cb, handler->pd_fb);
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+EAPI int livebox_activate(const char *pkgname)
+{
+ GVariant *param;
+ int ret;
+
+ if (!pkgname)
+ return -EINVAL;
+
+ param = g_variant_new("(s)", pkgname);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(NULL, "activate_package", param, activated_cb, strdup(pkgname));
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+static void pd_destroy_cb(struct livebox *handler, int ret, void *data)
+{
+ DbgPrint("destroy_pd returns %d\n", ret);
+ fb_destroy_buffer(data);
+ lb_invoke_event_handler(handler, "pd,deleted");
+}
+
+EAPI int livebox_destroy_pd(struct livebox *handler)
+{
+ GVariant *param;
+ int ret;
+
+ if (!handler || !handler->pd_fb)
+ return -EINVAL;
+
+ if (fb_is_created(handler->pd_fb) != 1)
+ return -EINVAL;
+
+ param = g_variant_new("(ss)", handler->pkgname, handler->filename);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, "destroy_pd", param, pd_destroy_cb, handler->pd_fb);
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+EAPI int livebox_pd_mouse_down(struct livebox *handler, double x, double y)
+{
+ if (!handler || !handler->pd_fb)
+ return -EINVAL;
+
+ return send_mouse_event(handler, "pd_mouse_down", x, y);
+}
+
+EAPI int livebox_pd_mouse_up(struct livebox *handler, double x, double y)
+{
+ if (!handler || !handler->pd_fb)
+ return -EINVAL;
+
+ return send_mouse_event(handler, "pd_mouse_up", x, y);
+}
+
+EAPI int livebox_pd_mouse_move(struct livebox *handler, double x, double y)
+{
+ if (!handler || !handler->pd_fb)
+ return -EINVAL;
+
+ return send_mouse_event(handler, "pd_mouse_move", x, y);
+}
+
+EAPI int livebox_livebox_mouse_down(struct livebox *handler, double x, double y)
+{
+ if (!handler || !handler->lb_fb)
+ return -EINVAL;
+
+ return send_mouse_event(handler, "lb_mouse_down", x, y);
+}
+
+EAPI int livebox_livebox_mouse_up(struct livebox *handler, double x, double y)
+{
+ if (!handler || !handler->lb_fb)
+ return -EINVAL;
+
+ return send_mouse_event(handler, "lb_mouse_up", x, y);
+}
+
+EAPI int livebox_livebox_mouse_move(struct livebox *handler, double x, double y)
+{
+ if (!handler || !handler->lb_fb)
+ return -EINVAL;
+
+ return send_mouse_event(handler, "lb_mouse_move", x, y);
+}
+
+EAPI const char *livebox_filename(struct livebox *handler)
+{
+ if (!handler)
+ return NULL;
+
+ return handler->filename;
+}
+
+EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
+{
+ int _w;
+ int _h;
+
+ if (!handler)
+ return -EINVAL;
+
+ if (!w)
+ w = &_w;
+ if (!h)
+ h = &_h;
+
+ *w = handler->pd_w;
+ *h = handler->pd_h;
+ return 0;
+}
+
+EAPI int livebox_get_size(struct livebox *handler, int *w, int *h)
+{
+ int _w;
+ int _h;
+
+ if (!handler)
+ return -EINVAL;
+
+ if (!w)
+ w = &_w;
+ if (!h)
+ h = &_h;
+
+ *w = handler->lb_w;
+ *h = handler->lb_h;
+ return 0;
+}
+
+EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category)
+{
+ GVariant *param;
+ int ret;
+
+ if (!handler || !cluster || !category)
+ return -EINVAL;
+
+ param = g_variant_new("(ssss)", handler->pkgname, handler->filename, cluster, category);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, "change_group", param, event_ret_cb, handler);
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+EAPI int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category)
+{
+ if (!handler || !cluster || !category)
+ return -EINVAL;
+
+ *cluster = handler->cluster;
+ *category = handler->category;
+ return 0;
+}
+
+EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *w, int *h)
+{
+ register int i;
+ register int j;
+
+ if (!handler || !cnt)
+ return -EINVAL;
+
+ for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
+ if (handler->size_list & (0x01 << i)) {
+ if (j == *cnt)
+ break;
+
+ if (w)
+ w[j] = SIZE_LIST[i].w;
+ if (h)
+ h[j] = SIZE_LIST[i].h;
+ j++;
+ }
+ }
+
+ *cnt = j;
+ return 0;
+}
+
+EAPI const char *livebox_pkgname(struct livebox *handler)
+{
+ if (!handler)
+ return NULL;
+
+ return handler->pkgname;
+}
+
+EAPI double livebox_priority(struct livebox *handler)
+{
+ if (!handler)
+ return 0.0f;
+
+ return handler->priority;
+}
+
+EAPI int livebox_delete_cluster(const char *cluster)
+{
+ return -ENOSYS;
+}
+
+EAPI int livebox_delete_category(const char *cluster, const char *category)
+{
+ return -ENOSYS;
+}
+
+EAPI int livebox_is_file(struct livebox *handler)
+{
+ if (!handler)
+ return -EINVAL;
+
+ return handler->data_type == FILEDATA;
+}
+
+EAPI int livebox_is_text(struct livebox *handler)
+{
+ if (!handler)
+ return -EINVAL;
+
+ return handler->text_lb;
+}
+
+EAPI int livebox_pd_is_text(struct livebox *handler)
+{
+ if (!handler)
+ return -EINVAL;
+
+ return handler->text_pd;
+}
+
+EAPI int livebox_pd_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
+{
+ if (!handler)
+ return -EINVAL;
+
+ memcpy(&handler->pd_ops, ops, sizeof(*ops));
+ return 0;
+}
+
+EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
+{
+ if (!handler)
+ return -EINVAL;
+
+ memcpy(&handler->ops, ops, sizeof(*ops));
+ return 0;
+}
+
+EAPI void *livebox_fb(struct livebox *handler)
+{
+ if (!handler)
+ return NULL;
+
+ if (handler->data_type == FBDATA)
+ return fb_buffer(handler->lb_fb);
+
+ return NULL;
+}
+
+EAPI void *livebox_pdfb(struct livebox *handler)
+{
+ if (!handler)
+ return NULL;
+
+ return fb_buffer(handler->pd_fb);
+}
+
+EAPI int livebox_pdfb_bufsz(struct livebox *handler)
+{
+ if (!handler)
+ return -EINVAL;
+
+ return fb_size(handler->pd_fb);
+}
+
+EAPI int livebox_lbfb_bufsz(struct livebox *handler)
+{
+ if (!handler)
+ return -EINVAL;
+
+ return fb_size(handler->lb_fb);
+}
+
+EAPI int livebox_is_user(struct livebox *handler)
+{
+ if (!handler)
+ return -EINVAL;
+
+ return handler->is_user;
+}
+
+static void pinup_done_cb(struct livebox *handler, int ret, void *data)
+{
+ if (ret != 0) {
+ ErrPrint("Pinup is not changed: %s\n", strerror(ret));
+ lb_invoke_event_handler(handler, "pinup,failed");
+ } else {
+ handler->is_pinned_up = (int)data;
+ lb_invoke_event_handler(handler, "pinup,changed");
+ }
+}
+
+EAPI int livebox_set_pinup(struct livebox *handler, int flag)
+{
+ GVariant *param;
+ int ret;
+
+ if (!handler)
+ return -EINVAL;
+
+ if (handler->is_pinned_up == flag)
+ return 0;
+
+ param = g_variant_new("(ssi)", handler->pkgname, handler->filename, flag);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_push_command(handler, "pinup_changed", param, pinup_done_cb, (void *)flag);
+ if (ret < 0)
+ g_variant_unref(param);
+
+ return ret;
+}
+
+EAPI int livebox_pinup(struct livebox *handler)
+{
+ return handler->is_pinned_up;
+}
+
+EAPI int livebox_has_pinup(struct livebox *handler)
+{
+ return handler->pinup_supported;
+}
+
+EAPI int livebox_set_data(struct livebox *handler, void *data)
+{
+ if (!handler)
+ return -EINVAL;
+
+ DbgPrint("%p carry data %p\n", handler, data);
+ handler->data = data;
+ return 0;
+}
+
+EAPI void *livebox_get_data(struct livebox *handler)
+{
+ if (!handler)
+ return NULL;
+
+ DbgPrint("Get carried data of %p\n", handler);
+ return handler->data;
+}
+
+EAPI int livebox_is_exists(const char *pkgname)
+{
+ GVariant *param;
+ int ret;
+
+ param = g_variant_new("(s)", pkgname);
+ if (!param)
+ return -EFAULT;
+
+ ret = dbus_sync_command("livebox_is_exists", param);
+ return (ret == 0) ? 1 : ret;
+}
+
+int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
+{
+ void *pc;
+ void *ps;
+
+ pc = strdup(cluster);
+ if (!pc)
+ return -ENOMEM;
+
+ ps = strdup(category);
+ if (!ps) {
+ free(pc);
+ return -ENOMEM;
+ }
+
+ if (handler->cluster)
+ free(handler->cluster);
+
+ if (handler->category)
+ free(handler->category);
+
+ handler->cluster = pc;
+ handler->category = ps;
+
+ return 0;
+}
+
+int lb_set_size(struct livebox *handler, int w, int h)
+{
+ handler->lb_w = w;
+ handler->lb_h = h;
+ return 0;
+}
+
+int lb_set_pdsize(struct livebox *handler, int w, int h)
+{
+ handler->pd_w = w;
+ handler->pd_h = h;
+ return 0;
+}
+
+int lb_invoke_fault_handler(const char *event, const char *pkgname, const char *file, const char *func)
+{
+ struct dlist *l;
+ struct dlist *n;
+ struct fault_info *info;
+
+ dlist_foreach_safe(s_info.fault_list, l, n, info) {
+ if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE)
+ s_info.fault_list = dlist_remove(s_info.fault_list, l);
+ }
+
+ return 0;
+}
+
+int lb_invoke_event_handler(struct livebox *handler, const char *event)
+{
+ struct dlist *l;
+ struct dlist *n;
+ struct event_info *info;
+
+ dlist_foreach_safe(s_info.event_list, l, n, info) {
+ if (info->handler(handler, event, info->user_data) == EXIT_FAILURE)
+ s_info.event_list = dlist_remove(s_info.event_list, l);
+ }
+
+ return 0;
+}
+
+struct livebox *lb_find_livebox(const char *pkgname, const char *filename)
+{
+ struct dlist *l;
+ struct livebox *handler;
+
+ dlist_foreach(s_info.livebox_list, l, handler) {
+ if (!handler->filename)
+ continue;
+
+ if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->filename, filename))
+ return handler;
+ }
+
+ return NULL;
+}
+
+struct livebox *lb_find_livebox_by_timestamp(double timestamp)
+{
+ struct dlist *l;
+ struct livebox *handler;
+
+ dlist_foreach(s_info.livebox_list, l, handler) {
+ if (handler->timestamp == timestamp)
+ return handler;
+ }
+
+ return NULL;
+}
+
+struct livebox *lb_new_livebox(const char *pkgname, const char *filename)
+{
+ struct livebox *handler;
+
+ handler = calloc(1, sizeof(*handler));
+ if (!handler) {
+ ErrPrint("Failed to create a new livebox\n");
+ return NULL;
+ }
+
+ handler->pkgname = strdup(pkgname);
+ if (!handler->pkgname) {
+ ErrPrint("%s\n", strerror(errno));
+ free(handler);
+ return NULL;
+ }
+
+ handler->filename = strdup(filename);
+ if (!handler->filename) {
+ ErrPrint("%s\n", strerror(errno));
+ free(handler->pkgname);
+ free(handler);
+ return NULL;
+ }
+
+ s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
+ return handler;
+}
+
+int lb_set_content(struct livebox *handler, const char *content)
+{
+ if (handler->content) {
+ free(handler->content);
+ handler->content = NULL;
+ }
+
+ if (content) {
+ handler->content = strdup(content);
+ if (!handler->content)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+void lb_set_size_list(struct livebox *handler, int size_list)
+{
+ handler->size_list = size_list;
+}
+
+int lb_set_auto_launch(struct livebox *handler, int auto_launch)
+{
+ handler->auto_launch = auto_launch;
+ return 0;
+}
+
+void lb_set_priority(struct livebox *handler, double priority)
+{
+ handler->priority = priority;
+}
+
+void lb_set_filename(struct livebox *handler, const char *filename)
+{
+ if (handler->filename)
+ free(handler->filename);
+
+ handler->filename = strdup(filename);
+ if (!handler->filename)
+ ErrPrint("Error: %s\n", strerror(errno));
+}
+
+void lb_update_lb_fb(struct livebox *handler, int w, int h)
+{
+ int ow;
+ int oh;
+ char *filename;
+ const char *tmp;
+
+ if (!handler)
+ return;
+
+ if (!handler->lb_fb)
+ return;
+
+ fb_get_size(handler->lb_fb, &ow, &oh);
+ if (ow == w && oh == h) {
+ DbgPrint("Buffer size is not changed\n");
+ return;
+ }
+
+ tmp = fb_filename(handler->lb_fb);
+ if (!tmp) {
+ ErrPrint("Filename for LB fb is not exists\n");
+ return;
+ }
+
+ filename = strdup(tmp);
+ if (!filename) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ return;
+ }
+
+ fb_destroy_buffer(handler->lb_fb);
+ fb_destroy(handler->lb_fb);
+
+ handler->lb_fb = fb_create(filename, w, h);
+ free(filename);
+ if (!handler->lb_fb) {
+ ErrPrint("Faield to create a FB\n");
+ return;
+ }
+
+ if (fb_create_buffer(handler->lb_fb) < 0) {
+ ErrPrint("Failed to create a FB\n");
+ fb_destroy(handler->lb_fb);
+ handler->lb_fb = NULL;
+ return;
+ }
+}
+
+void lb_update_pd_fb(struct livebox *handler, int w, int h)
+{
+ int ow;
+ int oh;
+ char *filename;
+ const char *tmp;
+ int ret;
+
+ if (!handler)
+ return;
+
+ if (!handler->pd_fb)
+ return;
+
+ fb_get_size(handler->pd_fb, &ow, &oh);
+ if (ow == w && oh == h) {
+ DbgPrint("Buffer size is not changed\n");
+ return;
+ }
+
+ tmp = fb_filename(handler->pd_fb);
+ if (!tmp) {
+ ErrPrint("PD fb has no file\n");
+ return;
+ }
+
+ filename = strdup(tmp);
+ if (!filename) {
+ ErrPrint("Error: %s\n", strerror(errno));
+ return;
+ }
+
+ fb_destroy_buffer(handler->pd_fb);
+ fb_destroy(handler->pd_fb);
+
+ handler->pd_fb = fb_create(filename, w, h);
+ free(filename);
+ if (!handler->pd_fb) {
+ ErrPrint("Failed to create a FB\n");
+ return;
+ }
+
+ ret = fb_create_buffer(handler->pd_fb);
+ if (ret < 0) {
+ ErrPrint("Error: %s\n", strerror(ret));
+ fb_destroy(handler->pd_fb);
+ handler->pd_fb = NULL;
+ }
+}
+
+void lb_set_lb_fb(struct livebox *handler, const char *filename, int w, int h)
+{
+ if (!handler)
+ return;
+
+ if (handler->lb_fb) {
+ fb_destroy_buffer(handler->lb_fb);
+ fb_destroy(handler->lb_fb);
+ handler->lb_fb = NULL;
+ }
+
+ if (!filename || filename[0] == '\0')
+ return;
+
+ handler->lb_fb = fb_create(filename, w, h);
+ if (!handler->lb_fb) {
+ ErrPrint("Faield to create a FB\n");
+ return;
+ }
+
+ if (fb_create_buffer(handler->lb_fb) < 0) {
+ fb_destroy(handler->lb_fb);
+ handler->lb_fb = NULL;
+ ErrPrint("Failed to create frame buffer\n");
+ return;
+ }
+
+ handler->data_type = FBDATA;
+}
+
+void lb_set_pd_fb(struct livebox *handler, const char *filename, int w, int h)
+{
+ if (!handler)
+ return;
+
+ if (handler->pd_fb) {
+ fb_destroy_buffer(handler->pd_fb);
+ fb_destroy(handler->pd_fb);
+ handler->pd_fb = NULL;
+ }
+
+ if (!filename || filename[0] == '\0')
+ return;
+
+ handler->pd_fb = fb_create(filename, w, h);
+ if (!handler->pd_fb) {
+ ErrPrint("Failed to create a FB\n");
+ return;
+ }
+}
+
+struct fb_info *lb_get_lb_fb(struct livebox *handler)
+{
+ return handler->lb_fb;
+}
+
+struct fb_info *lb_get_pd_fb(struct livebox *handler)
+{
+ return handler->pd_fb;
+}
+
+void lb_set_user(struct livebox *handler, int user)
+{
+ handler->is_user = user;
+}
+
+void lb_set_pinup(struct livebox *handler, int pinup_supported)
+{
+ handler->pinup_supported = pinup_supported;
+}
+
+void lb_set_text_lb(struct livebox *handler, int flag)
+{
+ handler->text_lb = flag;
+}
+
+void lb_set_text_pd(struct livebox *handler, int flag)
+{
+ handler->text_pd = flag;
+}
+
+int lb_text_lb(struct livebox *handler)
+{
+ return handler->text_lb;
+}
+
+int lb_text_pd(struct livebox *handler)
+{
+ return handler->text_pd;
+}
+
+/* End of a file */
--- /dev/null
+/*
+ * com.samsung.live-magazine
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Sung-jae Park <nicesj.park@samsung.com>, Youngjoo Park <yjoo93.park@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+
+#include <dlog.h>
+
+#include "debug.h"
+#include "util.h"
+
+int errno;
+
+int util_check_extension(const char *filename, const char *check_ptr)
+{
+ int name_len;
+
+ name_len = strlen(filename);
+ while (--name_len >= 0 && *check_ptr) {
+ if (filename[name_len] != *check_ptr)
+ return -EINVAL;
+
+ check_ptr ++;
+ }
+
+ return 0;
+}
+
+double util_get_timestamp(void)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
+}
+
+/* End of a file */