Import the library for viewer of livebox from a local git
authorSung-jae Park <nicesj.park@samsung.com>
Thu, 17 May 2012 05:06:18 +0000 (14:06 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Thu, 17 May 2012 05:06:18 +0000 (14:06 +0900)
Change-Id: I85a9a7d541bd0193d21a729a96a5f2dbb5170978

26 files changed:
CMakeLists.txt [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/liblivebox-viewer-dev.install.in [new file with mode: 0644]
debian/liblivebox-viewer.install.in [new file with mode: 0644]
debian/rules [new file with mode: 0755]
include/dbus.h [new file with mode: 0644]
include/debug.h [new file with mode: 0644]
include/desc_parser.h [new file with mode: 0644]
include/dlist.h [new file with mode: 0644]
include/fb_file.h [new file with mode: 0644]
include/livebox-viewer_PG.h [new file with mode: 0644]
include/livebox.h [new file with mode: 0644]
include/livebox0.h [new file with mode: 0644]
include/util.h [new file with mode: 0644]
livebox-viewer.pc.in [new file with mode: 0644]
sample/Makefile [new file with mode: 0644]
sample/sample [new file with mode: 0755]
sample/sample.c [new file with mode: 0644]
src/dbus.c [new file with mode: 0644]
src/desc_parser.c [new file with mode: 0644]
src/dlist.c [new file with mode: 0644]
src/fb_file.c [new file with mode: 0644]
src/livebox.c [new file with mode: 0644]
src/util.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..e88e632
--- /dev/null
@@ -0,0 +1,70 @@
+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)
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..7f897a3
--- /dev/null
@@ -0,0 +1,9 @@
+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
+
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..f9fdeca
--- /dev/null
@@ -0,0 +1,25 @@
+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)
+
diff --git a/debian/liblivebox-viewer-dev.install.in b/debian/liblivebox-viewer-dev.install.in
new file mode 100644 (file)
index 0000000..358946a
--- /dev/null
@@ -0,0 +1,3 @@
+@PREFIX@/include/@PROJECT_NAME@/livebox.h
+@PREFIX@/share/doc/@PROJECT_NAME@/livebox-viewer_PG.h
+@PREFIX@/lib/pkgconfig/*.pc
diff --git a/debian/liblivebox-viewer.install.in b/debian/liblivebox-viewer.install.in
new file mode 100644 (file)
index 0000000..bf766f0
--- /dev/null
@@ -0,0 +1 @@
+@PREFIX@/lib/*.so*
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..74d632d
--- /dev/null
@@ -0,0 +1,116 @@
+#!/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
diff --git a/include/dbus.h b/include/dbus.h
new file mode 100644 (file)
index 0000000..1e59c45
--- /dev/null
@@ -0,0 +1,8 @@
+
+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 */
diff --git a/include/debug.h b/include/debug.h
new file mode 100644 (file)
index 0000000..3e3c382
--- /dev/null
@@ -0,0 +1,11 @@
+#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 */
diff --git a/include/desc_parser.h b/include/desc_parser.h
new file mode 100644 (file)
index 0000000..9f5e5f3
--- /dev/null
@@ -0,0 +1,3 @@
+extern int parse_desc(struct livebox *handle, const char *descfile, int is_pd);
+
+/* End of a file */
diff --git a/include/dlist.h b/include/dlist.h
new file mode 100644 (file)
index 0000000..4a02fed
--- /dev/null
@@ -0,0 +1,27 @@
+#define dlist_remove_data(list, data) do { \
+       struct dlist *l; \
+       l = dlist_find_data(list, data); \
+       list = dlist_remove(list, l); \
+} while (0)
+
+#define dlist_foreach(list, l, data) \
+       for ((l) = (list); ((data) = dlist_data(l)); (l) = dlist_next(l))
+
+#define dlist_foreach_safe(list, l, n, data) \
+       for ((l) = (list), (n) = dlist_next(l); \
+               ((data) = dlist_data(l)); \
+               (l) = (n), (n) = dlist_next(l))
+
+struct dlist;
+
+extern struct dlist *dlist_append(struct dlist *list, void *data);
+extern struct dlist *dlist_prepend(struct dlist *list, void *data);
+extern struct dlist *dlist_remove(struct dlist *list, struct dlist *l);
+extern struct dlist *dlist_find_data(struct dlist *list, void *data);
+extern void *dlist_data(struct dlist *l);
+extern struct dlist *dlist_next(struct dlist *l);
+extern struct dlist *dlist_prev(struct dlist *l);
+extern int dlist_count(struct dlist *l);
+extern struct dlist *dlist_nth(struct dlist *l, int nth);
+
+/* End of a file */
diff --git a/include/fb_file.h b/include/fb_file.h
new file mode 100644 (file)
index 0000000..32ac598
--- /dev/null
@@ -0,0 +1,17 @@
+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 */
diff --git a/include/livebox-viewer_PG.h b/include/livebox-viewer_PG.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/include/livebox.h b/include/livebox.h
new file mode 100644 (file)
index 0000000..68d668d
--- /dev/null
@@ -0,0 +1,143 @@
+#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 */
diff --git a/include/livebox0.h b/include/livebox0.h
new file mode 100644 (file)
index 0000000..a1873d5
--- /dev/null
@@ -0,0 +1,68 @@
+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 */
diff --git a/include/util.h b/include/util.h
new file mode 100644 (file)
index 0000000..6202410
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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 */
diff --git a/livebox-viewer.pc.in b/livebox-viewer.pc.in
new file mode 100644 (file)
index 0000000..c3bc978
--- /dev/null
@@ -0,0 +1,10 @@
+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}
diff --git a/sample/Makefile b/sample/Makefile
new file mode 100644 (file)
index 0000000..9721a92
--- /dev/null
@@ -0,0 +1,2 @@
+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`
diff --git a/sample/sample b/sample/sample
new file mode 100755 (executable)
index 0000000..bb4639b
Binary files /dev/null and b/sample/sample differ
diff --git a/sample/sample.c b/sample/sample.c
new file mode 100644 (file)
index 0000000..2caac11
--- /dev/null
@@ -0,0 +1,857 @@
+#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 */
diff --git a/src/dbus.c b/src/dbus.c
new file mode 100644 (file)
index 0000000..46cebe6
--- /dev/null
@@ -0,0 +1,675 @@
+#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)",
+                       &timestamp,
+                       &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 */
diff --git a/src/desc_parser.c b/src/desc_parser.c
new file mode 100644 (file)
index 0000000..3a7090e
--- /dev/null
@@ -0,0 +1,570 @@
+#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 */
diff --git a/src/dlist.c b/src/dlist.c
new file mode 100644 (file)
index 0000000..c8f62c3
--- /dev/null
@@ -0,0 +1,138 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "dlist.h"
+
+struct dlist {
+       struct dlist *next;
+       struct dlist *prev;
+       void *data;
+};
+
+struct dlist *dlist_append(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item)
+               return NULL;
+
+       item->next = NULL;
+       item->data = data;
+
+       if (!list) {
+               item->prev = item;
+
+               list = item;
+       } else {
+               item->prev = list->prev;
+               item->prev->next = item;
+
+               list->prev = item;
+       }
+
+       assert(!list->prev->next && "item NEXT");
+
+       return list;
+}
+
+struct dlist *dlist_prepend(struct dlist *list, void *data)
+{
+       struct dlist *item;
+
+       item = malloc(sizeof(*item));
+       if (!item)
+               return NULL;
+
+       if (!list) {
+               item->prev = item;
+               item->next = NULL;
+       } else {
+               item->prev = list->prev;
+               list->prev = item;
+               item->next = list;
+       }
+
+       return item;
+}
+
+struct dlist *dlist_remove(struct dlist *list, struct dlist *l)
+{
+       if (!list || !l)
+               return NULL;
+
+       if (l == list) {
+               l->prev = list->prev;
+               list = l->next;
+       } else {
+               l->prev->next = l->next;
+       }
+
+       if (l->next)
+               l->next->prev = l->prev;
+
+       free(l);
+       return list;
+}
+
+struct dlist *dlist_find_data(struct dlist *list, void *data)
+{
+       struct dlist *l;
+       void *_data;
+
+       dlist_foreach(list, l, _data) {
+               if (data == _data)
+                       return l;
+       }
+
+       return NULL;
+}
+
+void *dlist_data(struct dlist *l)
+{
+       return l ? l->data : NULL;
+}
+
+struct dlist *dlist_next(struct dlist *l)
+{
+       return l ? l->next : NULL;
+}
+
+struct dlist *dlist_prev(struct dlist *l)
+{
+       return l ? l->prev : NULL;
+}
+
+int dlist_count(struct dlist *l)
+{
+       register int i;
+       struct dlist *n;
+       void *data;
+
+       i = 0;
+       dlist_foreach(l, n, data) {
+               i++;
+       }
+
+       return i;
+}
+
+struct dlist *dlist_nth(struct dlist *l, int nth)
+{
+       register int i;
+       struct dlist *n;
+       void *data;
+
+       i = 0;
+       dlist_foreach(l, n, data) {
+               if (i == nth)
+                       return l;
+
+               i++;
+       }
+
+       return NULL;
+}
+
+/* End of a file */
diff --git a/src/fb_file.c b/src/fb_file.c
new file mode 100644 (file)
index 0000000..d31d46d
--- /dev/null
@@ -0,0 +1,202 @@
+#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 */
diff --git a/src/livebox.c b/src/livebox.c
new file mode 100644 (file)
index 0000000..e81cd80
--- /dev/null
@@ -0,0 +1,1155 @@
+#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 */
diff --git a/src/util.c b/src/util.c
new file mode 100644 (file)
index 0000000..61d3a13
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 */