[Experimental] Implement the "shared view" concept
authorSung-jae Park <nicesj.park@samsung.com>
Sat, 11 Jan 2014 03:14:17 +0000 (12:14 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Sun, 12 Jan 2014 06:48:53 +0000 (15:48 +0900)
One livebox instance can be shown at multiple position.
It will be dealt as a separated instance.
But internally, it is managed by one instance.

To save the communication(IPC) overhead, and storage, power consumption.

Change-Id: I9460c3d1b199befdc6b13f87b95420fb8e5ae0b3

13 files changed:
TC/testcase/utc_livebox_viewer.c
include/conf.h
include/debug.h
include/desc_parser.h
include/livebox.h
include/livebox_internal.h
packaging/liblivebox-viewer.spec
src/client.c
src/conf.c
src/desc_parser.c
src/fb.c
src/livebox.c
src/master_rpc.c

index 0e46f01..83ec85d 100644 (file)
@@ -2065,7 +2065,7 @@ static void utc_livebox_set_manual_sync_n(void)
 
 static void utc_livebox_set_manual_sync_p(void)
 {
-       livebox_set_manual_sync(0);
+       livebox_set_option(LB_OPTION_MANUAL_SYNC, 0);
        dts_pass("livebox_set_manual_sync", "Pass!");
 }
 
@@ -2073,7 +2073,7 @@ static void utc_livebox_manual_sync_p(void)
 {
        int ret;
 
-       ret = livebox_manual_sync();
+       ret = livebox_option(LB_OPTION_MANUAL_SYNC);
        dts_check_eq("livebox_manual_sync", ret, 0, "ok");
 }
 
@@ -2097,7 +2097,7 @@ static void utc_livebox_set_frame_drop_for_resizing_n(void)
 
 static void utc_livebox_set_frame_drop_for_resizing_p(void)
 {
-       livebox_set_frame_drop_for_resizing(1);
+       livebox_set_option(LB_OPTION_FRAME_DROP_FOR_RESIZE, 1);
        dts_pass("livebox_set_frame_drop_for_resizing", "pass");
 }
 
@@ -2114,7 +2114,7 @@ static void utc_livebox_frame_drop_for_resizing_p(void)
 {
        int ret;
 
-       ret = livebox_frame_drop_for_resizing();
+       ret = livebox_option(LB_OPTION_FRAME_DROP_FOR_RESIZE);
        dts_check_eq("livebox_frame_drop_for_resizing", ret, 1, "drop_for_resizing");
 }
 
index f134310..487aea1 100644 (file)
@@ -34,5 +34,7 @@ extern void conf_set_manual_sync(int flag);
 extern int conf_manual_sync(void);
 extern void conf_set_frame_drop_for_resizing(int flag);
 extern int conf_frame_drop_for_resizing(void);
+extern void conf_set_shared_content(int flag);
+extern int conf_shared_content(void);
 
 /* End of a file */
index ed0b9b8..d06862c 100644 (file)
@@ -24,4 +24,5 @@ extern FILE *__file_log_fp;
 #define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [\e[32m%s/%s\e[0m:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0)
 #endif
 
+
 /* End of a file */
index 0ba13ef..a7e0092 100644 (file)
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-extern int parse_desc(struct livebox *handle, const char *descfile, int is_pd);
+extern int parse_desc(struct livebox_common *common, const char *filename, int is_pd);
 
 /* End of a file */
index d97c217..bead828 100644 (file)
@@ -203,6 +203,14 @@ enum livebox_event_type { /*!< livebox_event_handler_set Event list */
        LB_EVENT_IGNORED /*!< Request is ignored */
 };
 
+enum livebox_option_type {
+       LB_OPTION_MANUAL_SYNC,                  /*!< Sync manually */
+       LB_OPTION_FRAME_DROP_FOR_RESIZE,        /*!< Drop frames while resizing */
+       LB_OPTION_SHARED_CONTENT,               /*!< Use only one real instance for multiple fake instances if user creates it using same content */
+
+       LB_OPTION_ERROR = 0xFFFFFFFF            /*!< To specify the size of this enumeration type */
+};
+
 enum livebox_fault_type {
        LB_FAULT_DEACTIVATED, /*!< Livebox is deactivated by its fault operation */
        LB_FAULT_PROVIDER_DISCONNECTED /*!< Provider is disconnected */
@@ -213,12 +221,12 @@ enum livebox_fault_type {
  * Must be sync'd with the provider
  */
 enum livebox_visible_state {
-       LB_SHOW = 0x00, /*!< Livebox is showed. Default state */
-       LB_HIDE = 0x01, /*!< Livebox is hide, Update timer is not be freezed. but you cannot receive any updates events. you should refresh(reload) the content of a livebox when you make this show again */
+       LB_SHOW = 0x00, /*!< Livebox is shown. Default state */
+       LB_HIDE = 0x01, /*!< Livebox is hidden, Update timer will not be freezed. but you cannot receive any updates events. */
 
-       LB_HIDE_WITH_PAUSE = 0x02, /*!< Livebix is hide, it will paused the update timer, but if a livebox update its contents, update event will come to you */
+       LB_HIDE_WITH_PAUSE = 0x02, /*!< Livebix is hidden, it will pause the update timer, but if a livebox updates its contents, update event will be triggered */
 
-       LB_VISIBLE_ERROR = 0xFFFFFFFF /* To enlarge the size of this enumeration type */
+       LB_VISIBLE_ERROR = 0xFFFFFFFF /*!< To specify the size of this enumeration type */
 };
 
 /*!
@@ -227,11 +235,11 @@ enum livebox_visible_state {
  */
 struct livebox_script_operators {
        int (*update_begin)(struct livebox *handle); /*!< Content parser is started */
-       int (*update_end)(struct livebox *handle); /*!< Content parser is stopped */
+       int (*update_end)(struct livebox *handle); /*!< Content parser is finished */
 
        /*!
         * \brief
-        * Listed functions will be called when parser meets each typed component
+        * Listed functions will be called when parser meets each typed content
         */
        int (*update_text)(struct livebox *handle, const char *id, const char *part, const char *data); /*!< Update text content */
        int (*update_image)(struct livebox *handle, const char *id, const char *part, const char *data, const char *option); /*!< Update image content */
@@ -242,6 +250,7 @@ struct livebox_script_operators {
        int (*update_info_category)(struct livebox *handle, const char *id, const char *category); /*!< Update content category info */
        int (*update_access)(struct livebox *handle, const char *id, const char *part, const char *text, const char *option); /*!< Update access information */
        int (*operate_access)(struct livebox *handle, const char *id, const char *part, const char *operation, const char *option); /*!< Update access operation */
+       int (*update_color)(struct livebox *handle, const char *id, const char *part, const char *data, const char *option); /*!< Update color */
 };
 
 /*!
@@ -1559,63 +1568,6 @@ extern int livebox_set_update_mode(struct livebox *handler, int active_update, r
 extern int livebox_is_active_update(struct livebox *handler);
 
 /*!
- * \brief Use the manual sync for S/W buffer
- * \details N/A
- * \remarks N/A
- * param[in] flag
- * \return void
- * \pre N/A
- * \post N/A
- * \see livebox_manual_sync
- * \see livebox_sync_pd_fb
- * \see livebox_sync_lb_fb
- */
-extern void livebox_set_manual_sync(int flag);
-
-/*!
- * \brief Get current mode
- * \details N/A
- * \remarks N/A
- * \return int
- * \retval 0 if auto sync
- * \retval 1 if manual sync
- * \pre N/A
- * \post N/A
- * \see livebox_set_manual_sync
- * \see livebox_sync_pd_fb
- * \see livebox_sync_lb_fb
- */
-extern int livebox_manual_sync(void);
-
-/*!
- * \brief Use the frame drop while resizing contents
- * \details N/A
- * \remarks N/A
- * \param[in] flag 1 for dropping frames of old size or 0.
- * \return void
- * \pre N/A
- * \post N/A
- * \see livebox_frame_drop_for_resizing
- */
-extern void livebox_set_frame_drop_for_resizing(int flag);
-
-/*!
- * \brief Get current mode
- * \details
- *   While resizing the box, viewer doesn't want to know the updaed frames of old size anymore,
- *   In that case, if this mode is turnned on, the provider will not send the updated event to the viewer about old size.
- *   So the viewer can reduce its burden to update (or ignore) unnecessary frames
- * \remarks N/A
- * \return int
- * \retval 0 if it is disabled
- * \retval 1 if it is enabled
- * \pre N/A
- * \post N/A
- * \see livebox_set_frame_drop_for_resizing
- */
-extern int livebox_frame_drop_for_resizing(void);
-
-/*!
  * \brief Sync manually
  * \details N/A
  * \remarks N/A
@@ -1713,6 +1665,54 @@ extern int livebox_acquire_fb_lock(struct livebox *handler, int is_pd);
 extern int livebox_release_fb_lock(struct livebox *handler, int is_pd);
 
 /*!
+ * \brief Set options for controlling livebox sub-system.
+ * \details
+ *   LB_OPTION_FRAME_DROP_FOR_RESIZE
+ *     While resizing the box, viewer doesn't want to know the updated frames of old size content anymore,
+ *     In that case, turn this on, the provider will not send the updated event to the viewer about old content.
+ *     So the viewer can reduce its burden to update unnecessary frames
+ *   LB_OPTION_MANUAL_SYNC
+ *     If you don't want updates frame automatically,
+ *     Only you want reload the frames by your hands,(manually)
+ *     Turn it on.
+ *     After turnned it on, you should sync it using
+ *       livebox_sync_pd_fb
+ *       livebox_sync_lb_pfb
+ *   LB_OPTION_SHARED_CONTENT
+ *     If this option is turnned on, even though you create a new livebox,
+ *     If there are already added same instance has same content, the instance will not be created again
+ *     Instead of creating a new instance, viewer will provides old instance with new handle.
+ * \remarks N/A
+ * \param[in] option option which will be affected by this call
+ * \param[in] state new value for given option
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID Unknown option
+ * \retval LB_STATUS_ERROR_FAULT Failed to change the state of option
+ * \retval LB_STATUS_SUCCESS Successfully changed
+ * \pre N/A
+ * \post N/A
+ * \see livebox_get_option
+ * \see livebox_sync_pd_fb
+ * \see livebox_sync_lb_fb
+ */
+extern int livebox_set_option(enum livebox_option_type option, int state);
+
+/*!
+ * \brief Get options livebox sub-system
+ * \details N/A
+ * \remarks N/A
+ * \param[in] option type of option
+ * \return int
+ * \retval LB_STATUS_ERROR_INVALID invalid option
+ * \retval LB_STATUS_ERROR_FAULT Failed to get option
+ * \retval >=0 Value of given option. must has to be >=0
+ * \pre N/A
+ * \post N/A
+ * \see livebox_set_option
+ */
+extern int livebox_option(enum livebox_option_type option);
+
+/*!
  * \}
  */
 
index fb9da64..a6f92f9 100644 (file)
  * limitations under the License.
  */
 
-extern int lb_set_group(struct livebox *handler, const char *cluster, const char *category);
-extern void lb_set_size(struct livebox *handler, int w, int h);
-extern void lb_set_pdsize(struct livebox *handler, int w, int h);
-extern void lb_set_default_pdsize(struct livebox *handler, int w, int h);
 extern void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event);
 extern void lb_invoke_fault_handler(enum livebox_fault_type type, const char *pkgname, const char *filename, const char *function);
-extern int lb_set_content(struct livebox *handler, const char *content);
-extern int lb_set_title(struct livebox *handler, const char *title);
-extern void lb_set_auto_launch(struct livebox *handler, const char *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, double timestamp);
-extern struct livebox *lb_find_livebox_by_timestamp(double timestamp);
-extern void lb_set_id(struct livebox *handler, const char *id);
-extern void lb_set_size_list(struct livebox *handler, int size_list);
-extern void lb_set_priority(struct livebox *handler, double priority);
-extern int lb_set_lb_fb(struct livebox *handler, const char *filename);
-extern int lb_set_pd_fb(struct livebox *handler, const char *filename);
-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_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);
-extern void lb_set_text_pd(struct livebox *handler);
-extern int lb_text_lb(struct livebox *handler);
-extern int lb_text_pd(struct livebox *handler);
-extern void lb_set_period(struct livebox *handler, double period);
-extern void lb_set_update_mode(struct livebox *handler, int active_mode);
+
+extern struct livebox_common *lb_find_common_handle(const char *pkgname, const char *filename);
+extern struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category);
+extern struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp);
+
+extern int lb_set_group(struct livebox_common *common, const char *cluster, const char *category);
+extern void lb_set_size(struct livebox_common *common, int w, int h);
+extern void lb_set_pdsize(struct livebox_common *common, int w, int h);
+extern void lb_set_default_pdsize(struct livebox_common *common, int w, int h);
+extern int lb_set_content(struct livebox_common *common, const char *content);
+extern int lb_set_title(struct livebox_common *handler, const char *title);
+extern void lb_set_auto_launch(struct livebox_common *handler, const char *auto_launch);
+extern void lb_set_id(struct livebox_common *handler, const char *id);
+extern void lb_set_size_list(struct livebox_common *handler, int size_list);
+extern void lb_set_priority(struct livebox_common *handler, double priority);
+extern int lb_set_lb_fb(struct livebox_common *handler, const char *filename);
+extern int lb_set_pd_fb(struct livebox_common *handler, const char *filename);
+extern struct fb_info *lb_get_pd_fb(struct livebox_common *handler);
+extern struct fb_info *lb_get_lb_fb(struct livebox_common *handler);
+extern void lb_set_user(struct livebox_common *handler, int user);
+extern void lb_set_pinup(struct livebox_common *handler, int pinup);
+extern void lb_set_text_lb(struct livebox_common *handler);
+extern void lb_set_text_pd(struct livebox_common *handler);
+extern int lb_text_lb(struct livebox_common *handler);
+extern int lb_text_pd(struct livebox_common *handler);
+extern void lb_set_period(struct livebox_common *handler, double period);
+extern void lb_set_update_mode(struct livebox_common *handler, int active_mode);
+extern void lb_set_filename(struct livebox_common *handler, const char *filename);
+extern void lb_set_alt_info(struct livebox_common *handler, const char *icon, const char *name);
+extern int lb_destroy_lock_file(struct livebox_common *common, int is_pd);
+extern int lb_create_lock_file(struct livebox_common *common, int is_pd);
+extern int lb_destroy_common_handle(struct livebox_common *common);
+extern struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category);
+extern int lb_sync_pd_fb(struct livebox_common *common);
+extern int lb_sync_lb_fb(struct livebox_common *common);
+extern int lb_common_unref(struct livebox_common *common, struct livebox *handle);
+extern int lb_common_ref(struct livebox_common *common, struct livebox *handle);
+
 extern struct livebox *lb_ref(struct livebox *handler);
-extern struct livebox *lb_unref(struct livebox *handler);
+extern struct livebox *lb_unref(struct livebox *handler, int destroy_common);
 extern int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data);
 extern int lb_delete_all(void);
-extern void lb_set_filename(struct livebox *handler, const char *filename);
-extern void lb_set_alt_info(struct livebox *handler, const char *icon, const char *name);
-extern int lb_destroy_lock_file(struct livebox *info, int is_pd);
-extern int lb_create_lock_file(struct livebox *info, int is_pd);
 
 enum lb_type { /*!< Must have to be sync with data-provider-master */
        _LB_TYPE_NONE = 0x0,
@@ -65,41 +74,46 @@ enum pd_type { /*!< Must have to be sync with data-provider-master */
        _PD_TYPE_BUFFER
 };
 
-struct livebox {
+enum livebox_state {
+       CREATE = 0xBEEFbeef,
+       DELETE = 0xDEADdead, /* Delete only for this client */
+       DESTROYED = 0x00DEAD00
+};
+
+struct livebox_common {
+       enum livebox_state state;
+
+       struct dlist *livebox_list;
        int refcnt;
-       enum {
-               CREATE = 0xBEEFbeef,
-               DELETE = 0xDEADdead, /* Delete only for this client */
-               DESTROYED = 0x00DEAD00
-       } state;
 
        char *cluster;
        char *category;
 
        char *pkgname;
        char *id;
+
        char *content;
        char *title;
        char *filename;
-       char *icon;
-       char *name;
 
        double timestamp;
 
-       enum livebox_visible_state visible;
+       struct alt_info {
+               char *icon;
+               char *name;
+       } alt;
+
        enum livebox_delete_type delete_type;
 
        int is_user;
        int is_pd_created;
        int is_pinned_up;
        int is_active_update;
+       enum livebox_visible_state visible;
 
        struct {
                enum lb_type type;
-               union {
-                       struct fb_info *fb;
-                       struct livebox_script_operators ops;
-               } data;
+               struct fb_info *fb;
 
                int size_list;
 
@@ -121,10 +135,7 @@ struct livebox {
 
        struct {
                enum pd_type type;
-               union {
-                       struct fb_info *fb;
-                       struct livebox_script_operators ops;
-               } data;
+               struct fb_info *fb;
 
                int width;
                int height;
@@ -141,40 +152,104 @@ struct livebox {
 
        int nr_of_sizes;
 
-       void *data;
-
-       ret_cb_t created_cb;
-       void *created_cbdata;
-
-       ret_cb_t deleted_cb;
-       void *deleted_cbdata;
-
-       ret_cb_t pinup_cb;
-       void *pinup_cbdata;
-
-       ret_cb_t group_changed_cb;
-       void *group_cbdata;
-
-       ret_cb_t period_changed_cb;
-       void *period_cbdata;
+       struct requested_flag {
+               unsigned int created:1;
+               unsigned int deleted:1;
+               unsigned int pinup:1;
+               unsigned int group_changed:1;
+               unsigned int period_changed:1;
+               unsigned int size_changed:1;
+               unsigned int pd_created:1;
+               unsigned int pd_destroyed:1;
+               unsigned int update_mode:1;
+               unsigned int access_event:1;
+               unsigned int key_event:1;
+
+               /*!
+                * \note
+                * Reserved
+                */
+               unsigned int reserved:21;
+       } request;
+};
 
-       ret_cb_t size_changed_cb;
-       void *size_cbdata;
+struct job_item {
+       struct livebox *handle;
+       ret_cb_t cb;
+       int ret;
+       void *data;
+};
 
-       ret_cb_t pd_created_cb;
-       void *pd_created_cbdata;
+struct livebox {
+       enum livebox_state state;
 
-       ret_cb_t pd_destroyed_cb;
-       void *pd_destroyed_cbdata;
+       int refcnt;
+       int paused_updating;
 
-       ret_cb_t update_mode_cb;
-       void *update_mode_cbdata;
+       enum livebox_visible_state visible;
+       struct livebox_common *common;
 
-       ret_cb_t access_event_cb;
-       void *access_event_cbdata;
+       void *data;
 
-       ret_cb_t key_event_cb;
-       void *key_event_cbdata;
+       struct callback_table {
+               struct livebox_script_operators lb_ops;
+               struct livebox_script_operators pd_ops;
+
+               struct created {
+                       ret_cb_t cb;
+                       void *data;
+               } created;
+
+               struct deleted {
+                       ret_cb_t cb;
+                       void *data;
+               } deleted;
+
+               struct pinup {
+                       ret_cb_t cb;
+                       void *data;
+               } pinup;
+
+               struct group_changed {
+                       ret_cb_t cb;
+                       void *data;
+               } group_changed;
+
+               struct period_changed {
+                       ret_cb_t cb;
+                       void *data;
+               } period_changed;
+
+               struct size_changed {
+                       ret_cb_t cb;
+                       void *data;
+               } size_changed;
+
+               struct pd_created {
+                       ret_cb_t cb;
+                       void *data;
+               } pd_created;
+
+               struct pd_destroyed {
+                       ret_cb_t cb;
+                       void *data;
+               } pd_destroyed;
+
+               struct update_mode {
+                       ret_cb_t cb;
+                       void *data;
+               } update_mode;
+
+               struct access_event {
+                       ret_cb_t cb;
+                       void *data;
+               } access_event;
+
+               struct key_event {
+                       ret_cb_t cb;
+                       void *data;
+               } key_event;
+       } cbs;
 };
 
 /* End of a file */
index 86e61c4..6c3a0ea 100644 (file)
@@ -1,6 +1,6 @@
 Name: liblivebox-viewer
 Summary: Library for developing the application
-Version: 0.19.0
+Version: 0.20.0
 Release: 1
 Group: HomeTF/Livebox
 License: Flora
index 3a3266d..3604787 100644 (file)
@@ -44,6 +44,7 @@
 #include "master_rpc.h"
 #include "conf.h"
 #include "file_service.h"
+#include "dlist.h"
 
 int errno;
 
@@ -75,11 +76,13 @@ static struct packet *master_fault_package(pid_t pid, int handle, const struct p
 
 static struct packet *master_hold_scroll(pid_t pid, int handle, const struct packet *packet)
 {
-       struct livebox *handler;
+       struct livebox_common *common;
+       struct livebox *livebox;
        const char *pkgname;
        const char *id;
        int seize;
        int ret;
+       struct dlist *l;
 
        ret = packet_get(packet, "ssi", &pkgname, &id, &seize);
        if (ret != 3) {
@@ -87,14 +90,17 @@ static struct packet *master_hold_scroll(pid_t pid, int handle, const struct pac
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance(%s) is not exists\n", id);
                goto out;
        }
 
        DbgPrint("HOLD: %s %d\n", id, seize);
-       lb_invoke_event_handler(handler, seize ? LB_EVENT_HOLD_SCROLL : LB_EVENT_RELEASE_SCROLL);
+       seize = seize ? LB_EVENT_HOLD_SCROLL : LB_EVENT_RELEASE_SCROLL;
+       dlist_foreach(common->livebox_list, l, livebox) {
+               lb_invoke_event_handler(livebox, seize);
+       }
 
 out:
        return NULL;
@@ -106,6 +112,8 @@ static struct packet *master_pinup(pid_t pid, int handle, const struct packet *p
        const char *id;
        const char *content;
        struct livebox *handler;
+       struct dlist *l;
+       struct livebox_common *common;
        char *new_content;
        int ret;
        int status;
@@ -117,8 +125,8 @@ static struct packet *master_pinup(pid_t pid, int handle, const struct packet *p
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance (%s) is not exists\n", id);
                goto out;
        }
@@ -126,29 +134,33 @@ static struct packet *master_pinup(pid_t pid, int handle, const struct packet *p
        if (status == 0) {
                new_content = strdup(content);
                if (new_content) {
-                       free(handler->content);
-                       handler->content = new_content;
-                       handler->is_pinned_up = pinup;
+                       free(common->content);
+                       common->content = new_content;
+                       common->is_pinned_up = pinup;
                } else {
                        ErrPrint("Heap: %s\n", strerror(errno));
                        status = LB_STATUS_ERROR_MEMORY;
                }
        }
 
-       if (handler->pinup_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       common->request.pinup = 0;
+
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.pinup.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
 
-               /* Make sure that user can call pinup API in its result callback */
-               cb = handler->pinup_cb;
-               cbdata = handler->pinup_cbdata;
+                       /* Make sure that user can call pinup API in its result callback */
+                       cb = handler->cbs.pinup.cb;
+                       cbdata = handler->cbs.pinup.data;
 
-               handler->pinup_cb = NULL;
-               handler->pinup_cbdata = NULL;
+                       handler->cbs.pinup.cb = NULL;
+                       handler->cbs.pinup.data = NULL;
 
-               cb(handler, status, cbdata);
-       } else if (status == 0) {
-               lb_invoke_event_handler(handler, LB_EVENT_PINUP_CHANGED);
+                       cb(handler, status, cbdata);
+               } else if (status == 0) {
+                       lb_invoke_event_handler(handler, LB_EVENT_PINUP_CHANGED);
+               }
        }
 
 out:
@@ -161,6 +173,9 @@ static struct packet *master_deleted(pid_t pid, int handle, const struct packet
        const char *id;
        double timestamp;
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
+       struct dlist *n;
        int reason;
 
        if (packet_get(packet, "ssdi", &pkgname, &id, &timestamp, &reason) != 4) {
@@ -168,8 +183,8 @@ static struct packet *master_deleted(pid_t pid, int handle, const struct packet
                goto out;
        }
 
-       handler = lb_find_livebox_by_timestamp(timestamp);
-       if (!handler) {
+       common = lb_find_common_handle_by_timestamp(timestamp);
+       if (!common) {
                /*!
                 * \note
                 * This can be happens only if the user delete a livebox
@@ -179,8 +194,8 @@ static struct packet *master_deleted(pid_t pid, int handle, const struct packet
        }
 
        /*!< Check validity of this "handler" */
-       if (handler->state != CREATE) {
-               if (handler->state != DELETE) {
+       if (common->state != CREATE) {
+               if (common->state != DELETE) {
                        /*!
                         * \note
                         * This is not possible
@@ -190,65 +205,79 @@ static struct packet *master_deleted(pid_t pid, int handle, const struct packet
                }
        }
 
-       if (handler->created_cb) {
-               ret_cb_t cb;
-               void *cbdata;
-               /*!
-                * \note
-                *
-                * "if (handler->id == NULL) {"
-                *
-                * The instance is not created yet.
-                * But the master forcely destroy it and send destroyed event to this
-                * without the created event.
-                *
-                * It could be destroyed when a slave has critical error(fault)
-                * before creating an instance successfully.
-                */
-               if (handler->created_cb == handler->deleted_cb) {
-                       if (handler->created_cbdata != handler->deleted_cbdata) {
-                               DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id);
+       common->request.deleted = 0;
+       /*!
+        * We should change the state of "common handler' before handling the callbacks.
+        * Because if user tries to create a new handle in the callbacks,
+        * find_sharable_common_handle will returns destroying object.
+        * Then we will get panic.
+        * To prevent it, we should change its state first.
+        */
+       common->state = DELETE;
+
+       dlist_foreach_safe(common->livebox_list, l, n, handler) {
+               if (handler->cbs.created.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
+                       /*!
+                        * \note
+                        *
+                        * "if (handler->id == NULL) {"
+                        *
+                        * The instance is not created yet.
+                        * But the master forcely destroy it and send destroyed event to this
+                        * without the created event.
+                        *
+                        * It could be destroyed when a slave has critical error(fault)
+                        * before creating an instance successfully.
+                        */
+                       if (handler->cbs.created.cb == handler->cbs.deleted.cb) {
+                               if (handler->cbs.created.data != handler->cbs.deleted.data) {
+                                       DbgPrint("cb is same but cbdata is different (%s - %s)\n", pkgname, id);
+                               }
+
+                               handler->cbs.deleted.cb = NULL;
+                               handler->cbs.deleted.data = NULL;
                        }
 
-                       handler->deleted_cb = NULL;
-                       handler->deleted_cbdata = NULL;
-               }
+                       cb = handler->cbs.created.cb;
+                       cbdata = handler->cbs.created.data;
 
-               cb = handler->created_cb;
-               cbdata = handler->created_cbdata;
+                       handler->cbs.created.cb = NULL;
+                       handler->cbs.created.data = NULL;
 
-               handler->created_cb = NULL;
-               handler->created_cbdata = NULL;
+                       if (reason == LB_STATUS_SUCCESS) {
+                               reason = LB_STATUS_ERROR_CANCEL;
+                       }
 
-               if (reason == LB_STATUS_SUCCESS) {
-                       reason = LB_STATUS_ERROR_CANCEL;
-               }
-               cb(handler, reason, cbdata);
-       } else if (handler->id) {
-               if (handler->deleted_cb) {
-                       ret_cb_t cb;
-                       void *cbdata;
+                       cb(handler, reason, cbdata);
+               } else if (common->id) {
+                       if (handler->cbs.deleted.cb) {
+                               ret_cb_t cb;
+                               void *cbdata;
 
-                       cb = handler->deleted_cb;
-                       cbdata = handler->deleted_cbdata;
+                               cb = handler->cbs.deleted.cb;
+                               cbdata = handler->cbs.deleted.data;
 
-                       handler->deleted_cb = NULL;
-                       handler->deleted_cbdata = NULL;
+                               handler->cbs.deleted.cb = NULL;
+                               handler->cbs.deleted.data = NULL;
 
-                       cb(handler, reason, cbdata);
-               } else {
-                       lb_invoke_event_handler(handler, LB_EVENT_DELETED);
+                               cb(handler, reason, cbdata);
+                       } else {
+                               lb_invoke_event_handler(handler, LB_EVENT_DELETED);
+                       }
                }
+
+               /* Just try to delete it, if a user didn't remove it from the live box list */
+               lb_unref(handler, 0);
        }
 
        /*!
         * \note
         * Lock file should be deleted after all callbacks are processed.
         */
-       lb_destroy_lock_file(handler, 0);
-
-       /* Just try to delete it, if a user didn't remove it from the live box list */
-       lb_unref(handler);
+       lb_destroy_lock_file(common, 0);
+       lb_destroy_common_handle(common);
 
 out:
        return NULL;
@@ -257,6 +286,7 @@ out:
 static struct packet *master_lb_update_begin(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
        const char *pkgname;
        const char *id;
        const char *content;
@@ -271,20 +301,20 @@ static struct packet *master_lb_update_begin(pid_t pid, int handle, const struct
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance[%s] is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("(%s) is not created\n", id);
                goto out;
        }
 
-       lb_set_priority(handler, priority);
-       lb_set_content(handler, content);
-       lb_set_title(handler, title);
+       lb_set_priority(common, priority);
+       lb_set_content(common, content);
+       lb_set_title(common, title);
 
        /*!
         * \NOTE
@@ -293,14 +323,18 @@ static struct packet *master_lb_update_begin(pid_t pid, int handle, const struct
         * And if the size is changed, the provider should finish the updating first.
         * And then begin updating again after change its size.
         */
-       if (lb_get_lb_fb(handler)) {
-               (void)lb_set_lb_fb(handler, fbfile);
+       if (lb_get_lb_fb(common)) {
+               (void)lb_set_lb_fb(common, fbfile);
+
+               ret = lb_sync_lb_fb(common);
 
-               ret = livebox_sync_lb_fb(handler);
                if (ret != LB_STATUS_SUCCESS) {
                        ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
                } else {
-                       lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_BEGIN);
+                       struct dlist *l;
+                       dlist_foreach(common->livebox_list, l, handler) {
+                               lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_BEGIN);
+                       }
                }
        } else {
                ErrPrint("Invalid request[%s], %s\n", id, fbfile);
@@ -313,6 +347,7 @@ out:
 static struct packet *master_pd_update_begin(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
        const char *pkgname;
        const char *id;
        const char *fbfile;
@@ -324,25 +359,28 @@ static struct packet *master_pd_update_begin(pid_t pid, int handle, const struct
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance[%s] is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("[%s] is not created\n", id);
                goto out;
        }
 
-       if (lb_get_pd_fb(handler)) {
-               (void)lb_set_lb_fb(handler, fbfile);
+       if (lb_get_pd_fb(common)) {
+               (void)lb_set_pd_fb(common, fbfile);
 
-               ret = livebox_sync_lb_fb(handler);
+               ret = lb_sync_pd_fb(common);
                if (ret != LB_STATUS_SUCCESS) {
                        ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, fbfile, ret);
                } else {
-                       lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_BEGIN);
+                       struct dlist *l;
+                       dlist_foreach(common->livebox_list, l, handler) {
+                               lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_BEGIN);
+                       }
                }
        } else {
                ErrPrint("Invalid request[%s], %s\n", id, fbfile);
@@ -355,6 +393,7 @@ out:
 static struct packet *master_lb_update_end(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
        const char *pkgname;
        const char *id;
        int ret;
@@ -365,19 +404,22 @@ static struct packet *master_lb_update_end(pid_t pid, int handle, const struct p
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance[%s] is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("[%s] is not created\n", id);
                goto out;
        }
 
-       if (lb_get_lb_fb(handler)) {
-               lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_END);
+       if (lb_get_lb_fb(common)) {
+               struct dlist *l;
+               dlist_foreach(common->livebox_list, l, handler) {
+                       lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATE_END);
+               }
        } else {
                ErrPrint("Invalid request[%s]\n", id);
        }
@@ -389,6 +431,8 @@ out:
 static struct packet *master_key_status(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        const char *pkgname;
        const char *id;
        int ret;
@@ -400,31 +444,35 @@ static struct packet *master_key_status(pid_t pid, int handle, const struct pack
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance[%s] is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("[%s] is not created\n", id);
                goto out;
        }
 
-       if (handler->key_event_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       common->request.key_event = 0;
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.key_event.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
 
-               cb = handler->key_event_cb;
-               cbdata = handler->key_event_cbdata;
+                       cb = handler->cbs.key_event.cb;
+                       cbdata = handler->cbs.key_event.data;
 
-               handler->key_event_cb = NULL;
-               handler->key_event_cbdata = NULL;
+                       handler->cbs.key_event.cb = NULL;
+                       handler->cbs.key_event.data = NULL;
 
-               cb(handler, status, cbdata);
-       } else {
-               ErrPrint("Invalid event[%s]\n", id);
+                       cb(handler, status, cbdata);
+               } else {
+                       ErrPrint("Invalid event[%s]\n", id);
+               }
        }
+
 out:
        return NULL;
 }
@@ -432,6 +480,8 @@ out:
 static struct packet *master_request_close_pd(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        const char *pkgname;
        const char *id;
        int ret;
@@ -443,19 +493,27 @@ static struct packet *master_request_close_pd(pid_t pid, int handle, const struc
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance[%s] is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("[%s] is not created\n", id);
                goto out;
        }
 
+       if (!common->is_pd_created) {
+               DbgPrint("PD is not created, closing what?(%s)\n", id);
+               goto out;
+       }
+
        DbgPrint("Reason: %d\n", reason);
-       lb_invoke_event_handler(handler, LB_EVENT_REQUEST_CLOSE_PD);
+
+       dlist_foreach(common->livebox_list, l, handler) {
+               lb_invoke_event_handler(handler, LB_EVENT_REQUEST_CLOSE_PD);
+       }
 out:
        return NULL;
 }
@@ -463,6 +521,8 @@ out:
 static struct packet *master_access_status(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        const char *pkgname;
        const char *id;
        int ret;
@@ -474,30 +534,31 @@ static struct packet *master_access_status(pid_t pid, int handle, const struct p
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance[%s] is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("[%s] is not created\n", id);
                goto out;
        }
 
-       if (handler->access_event_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       common->request.access_event = 0;
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.access_event.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
 
-               cb = handler->access_event_cb;
-               cbdata = handler->access_event_cbdata;
+                       cb = handler->cbs.access_event.cb;
+                       cbdata = handler->cbs.access_event.data;
 
-               handler->access_event_cb = NULL;
-               handler->access_event_cbdata = NULL;
+                       handler->cbs.access_event.cb = NULL;
+                       handler->cbs.access_event.data = NULL;
 
-               cb(handler, status, cbdata);
-       } else {
-               ErrPrint("Invalid event[%s]\n", id);
+                       cb(handler, status, cbdata);
+               }
        }
 out:
        return NULL;
@@ -506,6 +567,7 @@ out:
 static struct packet *master_pd_update_end(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
        const char *pkgname;
        const char *id;
        int ret;
@@ -516,19 +578,23 @@ static struct packet *master_pd_update_end(pid_t pid, int handle, const struct p
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance[%s] is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("[%s] is not created\n", id);
                goto out;
        }
 
-       if (lb_get_lb_fb(handler)) {
-               lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_END);
+       if (lb_get_lb_fb(common)) {
+               struct dlist *l;
+
+               dlist_foreach(common->livebox_list, l, handler) {
+                       lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATE_END);
+               }
        } else {
                ErrPrint("Invalid request[%s]", id);
        }
@@ -548,6 +614,7 @@ static struct packet *master_lb_updated(pid_t pid, int handle, const struct pack
        const char *icon;
        const char *name;
        struct livebox *handler;
+       struct livebox_common *common;
        int lb_w;
        int lb_h;
        double priority;
@@ -563,13 +630,13 @@ static struct packet *master_lb_updated(pid_t pid, int handle, const struct pack
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("instance(%s) is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                /*!
                 * \note
                 * Already deleted by the user.
@@ -580,30 +647,38 @@ static struct packet *master_lb_updated(pid_t pid, int handle, const struct pack
                goto out;
        }
 
-       lb_set_priority(handler, priority);
-       lb_set_content(handler, content);
-       lb_set_title(handler, title);
-       lb_set_size(handler, lb_w, lb_h);
-       lb_set_filename(handler, safe_file);
+       lb_set_priority(common, priority);
+       lb_set_content(common, content);
+       lb_set_title(common, title);
+       lb_set_size(common, lb_w, lb_h);
+       lb_set_filename(common, safe_file);
+
+       if (lb_text_lb(common)) {
+               const char *common_filename;
+
+               common_filename = common->filename ? common->filename : util_uri_to_path(common->id); 
 
-       if (lb_text_lb(handler)) {
-               (void)parse_desc(handler, livebox_filename(handler), 0);
+               (void)parse_desc(common, common_filename, 0);
                /*!
                 * \note
                 * DESC parser will call the "text event callback".
                 * Don't need to call global event callback in this case.
                 */
                goto out;
-       } else if (lb_get_lb_fb(handler)) {
-               if (conf_frame_drop_for_resizing() && handler->size_changed_cb) {
+       } else if (lb_get_lb_fb(common)) {
+               /*!
+                * \todo
+                * replace this with "flag" instead of "callback address"
+                */
+               if (conf_frame_drop_for_resizing() && common->request.size_changed) {
                        /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
                        DbgPrint("Discards obsoloted update event\n");
                        ret = LB_STATUS_ERROR_BUSY;
                } else {
-                       (void)lb_set_lb_fb(handler, fbfile);
+                       (void)lb_set_lb_fb(common, fbfile);
 
                        if (!conf_manual_sync()) {
-                               ret = livebox_sync_lb_fb(handler);
+                               ret = lb_sync_lb_fb(common);
                                if (ret != LB_STATUS_SUCCESS) {
                                        ErrPrint("Failed to do sync FB (%s - %s) (%d)\n", pkgname, util_basename(util_uri_to_path(id)), ret);
                                }
@@ -616,7 +691,12 @@ static struct packet *master_lb_updated(pid_t pid, int handle, const struct pack
        }
 
        if (ret == LB_STATUS_SUCCESS) {
-               lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
+               struct dlist *l;
+               struct dlist *n;
+
+               dlist_foreach_safe(common->livebox_list, l, n, handler) {
+                       lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
+               }
        }
 
 out:
@@ -626,9 +706,11 @@ out:
 static struct packet *master_pd_created(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
        const char *pkgname;
        const char *id;
        const char *buf_id;
+       struct dlist *l;
        int width;
        int height;
        int ret;
@@ -640,37 +722,38 @@ static struct packet *master_pd_created(pid_t pid, int handle, const struct pack
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance(%s) is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("Instance(%s) is not created\n", id);
                goto out;
        }
 
-       lb_set_pdsize(handler, width, height);
-       if (lb_text_pd(handler)) {
+       lb_set_pdsize(common, width, height);
+       if (lb_text_pd(common)) {
                DbgPrint("Text TYPE does not need to handle this\n");
        } else {
-               (void)lb_set_pd_fb(handler, buf_id);
-               ret = livebox_sync_pd_fb(handler);
+               (void)lb_set_pd_fb(common, buf_id);
+
+               ret = lb_sync_pd_fb(common);
                if (ret < 0) {
                        ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
                }
        }
 
-       handler->is_pd_created = (status == 0);
+       common->is_pd_created = (status == 0);
 
-       switch (handler->pd.type) {
+       switch (common->pd.type) {
        case _PD_TYPE_SCRIPT:
        case _PD_TYPE_BUFFER:
-               switch (fb_type(lb_get_pd_fb(handler))) {
+               switch (fb_type(lb_get_pd_fb(common))) {
                case BUFFER_TYPE_FILE:
                case BUFFER_TYPE_SHM:
-                       lb_create_lock_file(handler, 1);
+                       lb_create_lock_file(common, 1);
                        break;
                case BUFFER_TYPE_PIXMAP:
                case BUFFER_TYPE_ERROR:
@@ -683,25 +766,28 @@ static struct packet *master_pd_created(pid_t pid, int handle, const struct pack
                break;
        }
 
-       if (handler->pd_created_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       DbgPrint("PERF_DBOX\n");
+       common->request.pd_created = 0;
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.pd_created.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
 
-               cb = handler->pd_created_cb;
-               cbdata = handler->pd_created_cbdata;
+                       cb = handler->cbs.pd_created.cb;
+                       cbdata = handler->cbs.pd_created.data;
 
-               handler->pd_created_cb = NULL;
-               handler->pd_created_cbdata = NULL;
+                       handler->cbs.pd_created.cb = NULL;
+                       handler->cbs.pd_created.data = NULL;
 
-               /*!
-                * Before call the Callback function,
-                * pd_create_cb must be reset.
-                * Because, in the create callback, user can call create_pd function again.
-                */
-               DbgPrint("PERF_DBOX\n");
-               cb(handler, status, cbdata);
-       } else if (handler->is_pd_created) {
-               lb_invoke_event_handler(handler, LB_EVENT_PD_CREATED);
+                       /*!
+                        * Before call the Callback function,
+                        * pd_create_cb must be reset.
+                        * Because, in the create callback, user can call create_pd function again.
+                        */
+                       cb(handler, status, cbdata);
+               } else {
+                       lb_invoke_event_handler(handler, LB_EVENT_PD_CREATED);
+               }
        }
 
 out:
@@ -711,6 +797,8 @@ out:
 static struct packet *master_pd_destroyed(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct dlist *l;
+       struct livebox_common *common;
        const char *pkgname;
        const char *id;
        int ret;
@@ -722,50 +810,53 @@ static struct packet *master_pd_destroyed(pid_t pid, int handle, const struct pa
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance(%s) is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("Instance(%s) is not created\n", id);
                goto out;
        }
 
-       handler->is_pd_created = 0;
+       common->is_pd_created = 0;
+       common->request.pd_destroyed = 0;
 
-       if (handler->pd_destroyed_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.pd_destroyed.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
 
-               cb = handler->pd_destroyed_cb;
-               cbdata = handler->pd_destroyed_cbdata;
+                       cb = handler->cbs.pd_destroyed.cb;
+                       cbdata = handler->cbs.pd_destroyed.data;
 
-               handler->pd_destroyed_cb = NULL;
-               handler->pd_destroyed_cbdata = NULL;
+                       handler->cbs.pd_destroyed.cb = NULL;
+                       handler->cbs.pd_destroyed.data = NULL;
 
-               /*!
-                * Before call the Callback function,
-                * pd_destroyed_cb must be reset.
-                * Because, in the create callback, user can call destroy_pd function again.
-                */
-               cb(handler, status, cbdata);
-       } else if (status == 0) {
-               lb_invoke_event_handler(handler, LB_EVENT_PD_DESTROYED);
+                       /*!
+                        * Before call the Callback function,
+                        * pd_destroyed_cb must be reset.
+                        * Because, in the create callback, user can call destroy_pd function again.
+                        */
+                       cb(handler, status, cbdata);
+               } else if (status == 0) {
+                       lb_invoke_event_handler(handler, LB_EVENT_PD_DESTROYED);
+               }
        }
 
        /*!
         * \note
         * Lock file should be deleted after all callbacks are processed.
         */
-       switch (handler->pd.type) {
+       switch (common->pd.type) {
        case _PD_TYPE_SCRIPT:
        case _PD_TYPE_BUFFER:
-               switch (fb_type(lb_get_pd_fb(handler))) {
+               switch (fb_type(lb_get_pd_fb(common))) {
                case BUFFER_TYPE_FILE:
                case BUFFER_TYPE_SHM:
-                       lb_destroy_lock_file(handler, 1);
+                       lb_destroy_lock_file(common, 1);
                        break;
                case BUFFER_TYPE_PIXMAP:
                case BUFFER_TYPE_ERROR:
@@ -790,6 +881,8 @@ static struct packet *master_pd_updated(pid_t pid, int handle, const struct pack
        const char *fbfile;
        int ret;
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        int pd_w;
        int pd_h;
 
@@ -802,13 +895,13 @@ static struct packet *master_pd_updated(pid_t pid, int handle, const struct pack
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Instance(%s) is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                /*!
                 * \note
                 * This handler is already deleted by the user.
@@ -819,26 +912,30 @@ static struct packet *master_pd_updated(pid_t pid, int handle, const struct pack
                goto out;
        }
 
-       lb_set_pdsize(handler, pd_w, pd_h);
+       lb_set_pdsize(common, pd_w, pd_h);
 
-       if (lb_text_pd(handler)) {
-               (void)parse_desc(handler, descfile, 1);
+       if (lb_text_pd(common)) {
+               (void)parse_desc(common, descfile, 1);
        } else {
-               if (conf_frame_drop_for_resizing() && handler->size_changed_cb) {
+               if (conf_frame_drop_for_resizing() && common->request.size_changed) {
                        /* Just for skipping the update event callback call, After request to resize buffer, update event will be discarded */
                        DbgPrint("Discards obsoloted update event\n");
                } else {
-                       (void)lb_set_pd_fb(handler, fbfile);
+                       (void)lb_set_pd_fb(common, fbfile);
 
                         if (!conf_manual_sync()) {
-                               ret = livebox_sync_pd_fb(handler);
+                               ret = lb_sync_pd_fb(common);
                                if (ret < 0) {
                                        ErrPrint("Failed to do sync FB (%s - %s), %d\n", pkgname, util_basename(util_uri_to_path(id)), ret);
                                } else {
-                                       lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
+                                       dlist_foreach(common->livebox_list, l, handler) {
+                                               lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
+                                       }
                                }
                        } else {
-                               lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
+                               dlist_foreach(common->livebox_list, l, handler) {
+                                       lb_invoke_event_handler(handler, LB_EVENT_PD_UPDATED);
+                               }
                        }
                }
        }
@@ -850,6 +947,8 @@ out:
 static struct packet *master_update_mode(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        const char *pkgname;
        const char *id;
        int active_mode;
@@ -867,34 +966,37 @@ static struct packet *master_update_mode(pid_t pid, int handle, const struct pac
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Livebox(%s) is not found\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("Livebox(%s) is not created yet\n", id);
                goto out;
        }
 
        if (status == LB_STATUS_SUCCESS) {
-               lb_set_update_mode(handler, active_mode);
+               lb_set_update_mode(common, active_mode);
        }
 
-       if (handler->update_mode_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       common->request.update_mode = 0;
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.update_mode.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
 
-               cb = handler->update_mode_cb;
-               cbdata = handler->update_mode_cbdata;
+                       cb = handler->cbs.update_mode.cb;
+                       cbdata = handler->cbs.update_mode.data;
 
-               handler->update_mode_cb = NULL;
-               handler->update_mode_cbdata = NULL;
+                       handler->cbs.update_mode.cb = NULL;
+                       handler->cbs.update_mode.data = NULL;
 
-               cb(handler, status, cbdata);
-       } else {
-               lb_invoke_event_handler(handler, LB_EVENT_UPDATE_MODE_CHANGED);
+                       cb(handler, status, cbdata);
+               } else {
+                       lb_invoke_event_handler(handler, LB_EVENT_UPDATE_MODE_CHANGED);
+               }
        }
 
 out:
@@ -904,6 +1006,8 @@ out:
 static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        const char *pkgname;
        const char *id;
        const char *fbfile;
@@ -924,17 +1028,18 @@ static struct packet *master_size_changed(pid_t pid, int handle, const struct pa
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Livebox(%s) is not found\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("Livebox(%s) is not created yet\n", id);
                goto out;
        }
 
+       common->request.size_changed = 0;
        if (is_pd) {
                /*!
                 * \NOTE
@@ -944,63 +1049,54 @@ static struct packet *master_size_changed(pid_t pid, int handle, const struct pa
                 * Notify it via global event handler only.
                 */
                if (status == 0) {
-                       lb_set_pdsize(handler, w, h);
-                       lb_invoke_event_handler(handler, LB_EVENT_PD_SIZE_CHANGED);
+                       lb_set_pdsize(common, w, h);
+                       dlist_foreach(common->livebox_list, l, handler) {
+                               lb_invoke_event_handler(handler, LB_EVENT_PD_SIZE_CHANGED);
+                       }
                } else {
                        ErrPrint("This is not possible. PD Size is changed but the return value is not ZERO (%d)\n", status);
                }
        } else {
                if (status == 0) {
-                       lb_set_size(handler, w, h);
+                       lb_set_size(common, w, h);
 
                        /*!
                         * \NOTE
                         * If there is a created LB FB, 
                         * Update it too.
                         */
-                       if (lb_get_lb_fb(handler)) {
-                               (void)lb_set_lb_fb(handler, fbfile);
+                       if (lb_get_lb_fb(common)) {
+                               (void)lb_set_lb_fb(common, fbfile);
 
-                               ret = livebox_sync_lb_fb(handler);
+                               ret = lb_sync_lb_fb(common);
                                if (ret < 0) {
                                        ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
                                }
 
                                /* Just update the size info only. */
                        }
+               }
 
-                       /*!
-                        * \NOTE
-                        * I cannot believe client.
-                        * So I added some log before & after call the user callback.
-                        */
-                       if (handler->size_changed_cb) {
+               /*!
+                * \NOTE
+                * I cannot believe client.
+                * So I added some log before & after call the user callback.
+                */
+               dlist_foreach(common->livebox_list, l, handler) {
+                       if (handler->cbs.size_changed.cb) {
                                ret_cb_t cb;
                                void *cbdata;
 
-                               cb = handler->size_changed_cb;
-                               cbdata = handler->size_cbdata;
+                               cb = handler->cbs.size_changed.cb;
+                               cbdata = handler->cbs.size_changed.data;
 
-                               handler->size_changed_cb = NULL;
-                               handler->size_cbdata = NULL;
+                               handler->cbs.size_changed.cb = NULL;
+                               handler->cbs.size_changed.data = NULL;
 
                                cb(handler, status, cbdata);
-                       } else {
+                       } else if (status == 0) {
                                lb_invoke_event_handler(handler, LB_EVENT_LB_SIZE_CHANGED);
                        }
-               } else {
-                       if (handler->size_changed_cb) {
-                               ret_cb_t cb;
-                               void *cbdata;
-
-                               cb = handler->size_changed_cb;
-                               cbdata = handler->size_cbdata;
-
-                               handler->size_changed_cb = NULL;
-                               handler->size_cbdata = NULL;
-
-                               cb(handler, status, cbdata);
-                       }
                }
        }
 
@@ -1011,6 +1107,8 @@ out:
 static struct packet *master_period_changed(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        const char *pkgname;
        const char *id;
        int ret;
@@ -1023,34 +1121,38 @@ static struct packet *master_period_changed(pid_t pid, int handle, const struct
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Livebox(%s) is not found\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                ErrPrint("Livebox(%s) is not created\n", id);
                goto out;
        }
 
        if (status == 0) {
-               lb_set_period(handler, period);
+               lb_set_period(common, period);
        }
 
-       if (handler->period_changed_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       common->request.period_changed = 0;
 
-               cb = handler->period_changed_cb;
-               cbdata = handler->period_cbdata;
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.period_changed.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
+
+                       cb = handler->cbs.period_changed.cb;
+                       cbdata = handler->cbs.period_changed.data;
 
-               handler->period_changed_cb = NULL;
-               handler->period_cbdata = NULL;
+                       handler->cbs.period_changed.cb = NULL;
+                       handler->cbs.period_changed.data = NULL;
 
-               cb(handler, status, cbdata);
-       } else if (status == 0) {
-               lb_invoke_event_handler(handler, LB_EVENT_PERIOD_CHANGED);
+                       cb(handler, status, cbdata);
+               } else if (status == 0) {
+                       lb_invoke_event_handler(handler, LB_EVENT_PERIOD_CHANGED);
+               }
        }
 
 out:
@@ -1060,6 +1162,8 @@ out:
 static struct packet *master_group_changed(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
        const char *pkgname;
        const char *id;
        int ret;
@@ -1073,13 +1177,13 @@ static struct packet *master_group_changed(pid_t pid, int handle, const struct p
                goto out;
        }
 
-       handler = lb_find_livebox(pkgname, id);
-       if (!handler) {
+       common = lb_find_common_handle(pkgname, id);
+       if (!common) {
                ErrPrint("Livebox(%s) is not exists\n", id);
                goto out;
        }
 
-       if (handler->state != CREATE) {
+       if (common->state != CREATE) {
                /*!
                 * \note
                 * Do no access this handler,
@@ -1090,22 +1194,26 @@ static struct packet *master_group_changed(pid_t pid, int handle, const struct p
        }
 
        if (status == 0) {
-               (void)lb_set_group(handler, cluster, category);
+               (void)lb_set_group(common, cluster, category);
        }
 
-       if (handler->group_changed_cb) {
-               ret_cb_t cb;
-               void *cbdata;
+       common->request.group_changed = 0;
 
-               cb = handler->group_changed_cb;
-               cbdata = handler->group_cbdata;
+       dlist_foreach(common->livebox_list, l, handler) {
+               if (handler->cbs.group_changed.cb) {
+                       ret_cb_t cb;
+                       void *cbdata;
+
+                       cb = handler->cbs.group_changed.cb;
+                       cbdata = handler->cbs.group_changed.data;
 
-               handler->group_changed_cb = NULL;
-               handler->group_cbdata = NULL;
+                       handler->cbs.group_changed.cb = NULL;
+                       handler->cbs.group_changed.data = NULL;
 
-               cb(handler, status, cbdata);
-       } else if (status == 0) {
-               lb_invoke_event_handler(handler, LB_EVENT_GROUP_CHANGED);
+                       cb(handler, status, cbdata);
+               } else if (status == 0) {
+                       lb_invoke_event_handler(handler, LB_EVENT_GROUP_CHANGED);
+               }
        }
 
 out:
@@ -1115,6 +1223,8 @@ out:
 static struct packet *master_created(pid_t pid, int handle, const struct packet *packet)
 {
        struct livebox *handler;
+       struct livebox_common *common;
+       struct dlist *l;
 
        int lb_w;
        int lb_h;
@@ -1169,19 +1279,19 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
                auto_launch, priority, size_list, user, pinup_supported,
                lb_type, pd_type, period, title, is_pinned_up);
 
-       handler = lb_find_livebox_by_timestamp(timestamp);
-       if (!handler) {
-               handler = lb_new_livebox(pkgname, id, timestamp);
+       common = lb_find_common_handle_by_timestamp(timestamp);
+       if (!common) {
+               handler = lb_new_livebox(pkgname, id, timestamp, cluster, category);
                if (!handler) {
                        ErrPrint("Failed to create a new livebox\n");
                        ret = LB_STATUS_ERROR_FAULT;
                        goto out;
                }
-
-               old_state = handler->state;
+               common = handler->common;
+               old_state = common->state;
        } else {
-               if (handler->state != CREATE) {
-                       if (handler->state != DELETE) {
+               if (common->state != CREATE) {
+                       if (common->state != DELETE) {
                                /*!
                                 * \note
                                 * This is not possible!!!
@@ -1198,9 +1308,9 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
                         */
                }
 
-               old_state = handler->state;
+               old_state = common->state;
 
-               if (handler->id) {
+               if (common->id) {
                        ErrPrint("Already created: timestamp[%lf] "
                                "pkgname[%s], id[%s] content[%s] "
                                "cluster[%s] category[%s] lb_fname[%s] pd_fname[%s]\n",
@@ -1212,12 +1322,13 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
                        goto out;
                }
 
-               lb_set_id(handler, id);
+               lb_set_id(common, id);
        }
 
-       lb_set_size(handler, lb_w, lb_h);
-       handler->lb.type = lb_type;
-       handler->is_pinned_up = is_pinned_up;
+       common->request.created = 0;
+       lb_set_size(common, lb_w, lb_h);
+       common->lb.type = lb_type;
+       common->is_pinned_up = is_pinned_up;
 
        switch (lb_type) {
        case _LB_TYPE_FILE:
@@ -1227,7 +1338,7 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
                if (!strlen(lb_fname)) {
                        break;
                }
-               (void)lb_set_lb_fb(handler, lb_fname);
+               (void)lb_set_lb_fb(common, lb_fname);
 
                /*!
                 * \note
@@ -1235,10 +1346,10 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
                 * Even if the old_state == DELETE,
                 * the lock file will be deleted from deleted event callback.
                 */
-               switch (fb_type(lb_get_lb_fb(handler))) {
+               switch (fb_type(lb_get_lb_fb(common))) {
                case BUFFER_TYPE_FILE:
                case BUFFER_TYPE_SHM:
-                       lb_create_lock_file(handler, 0);
+                       lb_create_lock_file(common, 0);
                        break;
                case BUFFER_TYPE_PIXMAP:
                case BUFFER_TYPE_ERROR:
@@ -1246,21 +1357,21 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
                        break;
                }
 
-               ret = livebox_sync_lb_fb(handler);
+               ret = lb_sync_lb_fb(common);
                if (ret < 0) {
                        ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
                }
                break;
        case _LB_TYPE_TEXT:
-               lb_set_text_lb(handler);
+               lb_set_text_lb(common);
                break;
        default:
                break;
        }
 
-       handler->pd.type = pd_type;
-       lb_set_pdsize(handler, pd_w, pd_h);
-       lb_set_default_pdsize(handler, pd_w, pd_h);
+       common->pd.type = pd_type;
+       lb_set_pdsize(common, pd_w, pd_h);
+       lb_set_default_pdsize(common, pd_w, pd_h);
        switch (pd_type) {
        case _PD_TYPE_SCRIPT:
        case _PD_TYPE_BUFFER:
@@ -1268,8 +1379,9 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
                        break;
                }
 
-               lb_set_pd_fb(handler, pd_fname);
-               ret = livebox_sync_pd_fb(handler);
+               lb_set_pd_fb(common, pd_fname);
+
+               ret = lb_sync_pd_fb(common);
                if (ret < 0) {
                        ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id)));
                }
@@ -1282,60 +1394,92 @@ static struct packet *master_created(pid_t pid, int handle, const struct packet
 
                break;
        case _PD_TYPE_TEXT:
-               lb_set_text_pd(handler);
+               lb_set_text_pd(common);
                break;
        default:
                break;
        }
 
-       lb_set_priority(handler, priority);
+       lb_set_priority(common, priority);
 
-       lb_set_size_list(handler, size_list);
-       lb_set_group(handler, cluster, category);
+       lb_set_size_list(common, size_list);
+       lb_set_group(common, cluster, category);
 
-       lb_set_content(handler, content);
-       lb_set_title(handler, title);
+       lb_set_content(common, content);
+       lb_set_title(common, title);
 
-       lb_set_user(handler, user);
+       lb_set_user(common, user);
 
-       lb_set_auto_launch(handler, auto_launch);
-       lb_set_pinup(handler, pinup_supported);
+       lb_set_auto_launch(common, auto_launch);
+       lb_set_pinup(common, pinup_supported);
 
-       lb_set_period(handler, period);
+       lb_set_period(common, period);
 
        ret = 0;
 
-       if (handler->state == CREATE) {
-               /*!
-                * \note
-                * These callback can change the handler->state.
-                * So we have to use the "old_state" which stored state before call these callbacks
-                */
+       if (common->state == CREATE) {
+               dlist_foreach(common->livebox_list, l, handler) {
+                       /*!
+                        * \note
+                        * These callback can change the handler->state.
+                        * So we have to use the "old_state" which stored state before call these callbacks
+                        */
 
-               if (handler->created_cb) {
-                       ret_cb_t cb;
-                       void *cbdata;
+                       if (handler->cbs.created.cb) {
+                               ret_cb_t cb;
+                               void *cbdata;
 
-                       cb = handler->created_cb;
-                       cbdata = handler->created_cbdata;
+                               cb = handler->cbs.created.cb;
+                               cbdata = handler->cbs.created.data;
 
-                       handler->created_cb = NULL;
-                       handler->created_cbdata = NULL;
+                               handler->cbs.created.cb = NULL;
+                               handler->cbs.created.data = NULL;
 
-                       cb(handler, ret, cbdata);
-               } else {
-                       lb_invoke_event_handler(handler, LB_EVENT_CREATED);
+                               cb(handler, ret, cbdata);
+                       } else {
+                               lb_invoke_event_handler(handler, LB_EVENT_CREATED);
+                       }
                }
        }
 
 out:
        if (ret == 0 && old_state == DELETE) {
-               lb_send_delete(handler, handler->delete_type, handler->created_cb, handler->created_cbdata);
+               int delete_event_sent = 0;
+               int cnt;
+
+               DbgPrint("Take place unexpected case\n");
+               cnt = common->refcnt;
+               while (cnt > 0) {
+                       l = dlist_nth(common->livebox_list, 0);
+                       handler = dlist_data(l);
+
+                       if (handler->cbs.created.cb) {
+                               if (delete_event_sent == 0) {
+                                       if (lb_send_delete(handler, common->delete_type, handler->cbs.created.cb, handler->cbs.created.data) < 0) {
+                                               /*!
+                                                * \note
+                                                * Already sent or something else happens.
+                                                * Callback will be called in any cases
+                                                */
+                                       }
+
+                                       delete_event_sent = 1;
+                               } else {
+                                       handler->cbs.created.cb(handler, LB_STATUS_ERROR_CANCEL, handler->cbs.created.data);
+                                       lb_unref(handler, 1);
+                               }
+                       } else {
+                               lb_invoke_event_handler(handler, LB_EVENT_DELETED);
+                               lb_unref(handler, 1);
+                       }
+
+                       cnt--;
+               }
 
                /*!
                 * \note
-                * handler->created_cb = NULL;
-                * handler->created_cbdata = NULL;
+                * handler->cbs.created.cb = NULL;
+                * handler->cbs.created.data = NULL;
                 *
                 * Do not clear this to use this from the deleted event callback.
                 * if this value is not cleared when the deleted event callback check it,
index 9a9063b..95446aa 100644 (file)
@@ -3,9 +3,11 @@
 static struct info {
        int manual_sync;
        int frame_drop_for_resizing;
+       int shared_content;
 } s_info = {
        .manual_sync = 0,
        .frame_drop_for_resizing = 1,
+       .shared_content = 0,
 };
 
 void conf_set_manual_sync(int flag)
@@ -28,4 +30,14 @@ int conf_frame_drop_for_resizing(void)
        return s_info.frame_drop_for_resizing;
 }
 
+void conf_set_shared_content(int flag)
+{
+       s_info.shared_content = flag;
+}
+
+int conf_shared_content(void)
+{
+       return s_info.shared_content;
+}
+
 /* End of a file */
index d0fa14c..73ec31f 100644 (file)
 #include <stdlib.h> /* malloc */
 #include <string.h> /* strdup */
 #include <ctype.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 
+#include <gio/gio.h>
 #include <dlog.h>
 #include <livebox-errno.h>
 #include <livebox-service.h>
 #include "dlist.h"
 #include "util.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 TYPE_ACCESS "access"
-#define TYPE_OPERATE_ACCESS "access,operation"
-
 #define INFO_SIZE "size"
 #define INFO_CATEGORY "category"
 
-struct block {
-       char *type;
-       int type_len;
+static const char *type_list[] = {
+       "access",
+       "access,operation",
+       "color",
+       "drag",
+       "image",
+       "info",
+       "script",
+       "signal",
+       "text",
+       NULL
+};
 
-       char *part;
-       int part_len;
+static const char *field_list[] = {
+       "type",
+       "part",
+       "data",
+       "option",
+       "id",
+       "target",
+       "file",
+       NULL
+};
 
-       char *data;
-       int data_len;
+enum block_type {
+       TYPE_ACCESS,
+       TYPE_ACCESS_OP,
+       TYPE_COLOR,
+       TYPE_DRAG,
+       TYPE_IMAGE,
+       TYPE_INFO,
+       TYPE_SCRIPT,
+       TYPE_SIGNAL,
+       TYPE_TEXT,
+       TYPE_MAX
+};
 
-       char *file;
-       int file_len;
+enum field_type {
+       FIELD_TYPE,
+       FIELD_PART,
+       FIELD_DATA,
+       FIELD_OPTION,
+       FIELD_ID,
+       FIELD_TARGET,
+       FIELD_FILE
+};
 
+struct block {
+       enum block_type type;
+       char *part;
+       char *data;
        char *option;
-       int option_len;
-
        char *id;
-       int id_len;
+       char *target;
+       char *file;
+
+       /* Should be released */
+       char *filebuf;
+       const char *filename;
 };
 
 static int update_text(struct livebox *handle, struct block *block, int is_pd)
@@ -72,7 +109,7 @@ static int update_text(struct livebox *handle, struct block *block, int is_pd)
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_text) {
                ops->update_text(handle, (const char *)block->id, (const char *)block->part, (const char *)block->data);
        }
@@ -83,12 +120,13 @@ static int update_text(struct livebox *handle, struct block *block, int is_pd)
 static int update_image(struct livebox *handle, struct block *block, int is_pd)
 {
        struct livebox_script_operators *ops;
+
        if (!block || !block->part) {
                ErrPrint("Invalid argument\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_image) {
                ops->update_image(handle, block->id, block->part, block->data, block->option);
        }
@@ -99,12 +137,13 @@ static int update_image(struct livebox *handle, struct block *block, int is_pd)
 static int update_script(struct livebox *handle, struct block *block, int is_pd)
 {
        struct livebox_script_operators *ops;
+
        if (!block || !block->part) {
                ErrPrint("Invalid argument\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_script) {
                ops->update_script(handle, block->id, block->part, block->data, block->option);
        }
@@ -121,7 +160,7 @@ static int update_signal(struct livebox *handle, struct block *block, int is_pd)
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_signal) {
                ops->update_signal(handle, block->id, block->data, block->part);
        }
@@ -139,13 +178,12 @@ static int update_drag(struct livebox *handle, struct block *block, int is_pd)
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
-
        if (sscanf(block->data, "%lfx%lf", &dx, &dy) != 2) {
                ErrPrint("Invalid format of data\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_drag) {
                ops->update_drag(handle, block->id, block->part, dx, dy);
        }
@@ -162,8 +200,7 @@ static int update_info(struct livebox *handle, struct block *block, int is_pd)
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
-
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (!strcasecmp(block->part, INFO_SIZE)) {
                int w, h;
 
@@ -193,7 +230,7 @@ static int update_access(struct livebox *handle, struct block *block, int is_pd)
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_access) {
                ops->update_access(handle, block->id, block->part, block->data, block->option);
        }
@@ -210,7 +247,7 @@ static int operate_access(struct livebox *handle, struct block *block, int is_pd
                return LB_STATUS_ERROR_INVALID;
        }
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->operate_access) {
                ops->operate_access(handle, block->id, block->part, block->data, block->option);
        }
@@ -218,12 +255,28 @@ static int operate_access(struct livebox *handle, struct block *block, int is_pd
        return 0;
 }
 
-static inline int update_begin(struct livebox *handle, int is_pd)
+static int update_color(struct livebox *handle, struct block *block, int is_pd)
 {
        struct livebox_script_operators *ops;
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
+       if (!block) {
+               ErrPrint("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
+       if (ops->update_color) {
+               ops->update_color(handle, block->id, block->part, block->data, block->option);
+       }
+
+       return 0;
+}
+
+static inline int update_begin(struct livebox *handle, int is_pd)
+{
+       struct livebox_script_operators *ops;
 
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_begin) {
                ops->update_begin(handle);
        }
@@ -235,8 +288,7 @@ static inline int update_end(struct livebox *handle, int is_pd)
 {
        struct livebox_script_operators *ops;
 
-       ops = is_pd ? &handle->pd.data.ops : &handle->lb.data.ops;
-
+       ops = is_pd ? &handle->cbs.pd_ops : &handle->cbs.lb_ops;
        if (ops->update_end) {
                ops->update_end(handle);
        }
@@ -244,436 +296,402 @@ static inline int update_end(struct livebox *handle, int is_pd)
        return 0;
 }
 
-int parse_desc(struct livebox *handle, const char *descfile, int is_pd)
+static inline void delete_block(struct block *block)
 {
-       FILE *fp;
-       int ch;
-       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_OPTION = 0x04,
-               VALUE_ID = 0x05
-       };
-       const char *field_name[] = {
-               "type",
-               "part",
-               "data",
-               "file",
-               "option",
-               "id",
+       free(block->filebuf);
+       free(block);
+}
+
+static inline void consuming_parsed_block(struct livebox *handle, int is_pd, struct block *block)
+{
+       typedef int (*update_function_t)(struct livebox *handle, struct block *block, int is_pd);
+       static update_function_t updators[] = {
+               update_access,
+               operate_access,
+               update_color,
+               update_drag,
+               update_image,
+               update_info,
+               update_script,
+               update_signal,
+               update_text,
                NULL
        };
-       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_script,
-               },
-               {
-                       .type = TYPE_SIGNAL,
-                       .handler = update_signal,
-               },
-               {
-                       .type = TYPE_DRAG,
-                       .handler = update_drag,
-               },
-               {
-                       .type = TYPE_INFO,
-                       .handler = update_info,
-               },
-               {
-                       .type = TYPE_ACCESS,
-                       .handler = update_access,
-               },
-               {
-                       .type = TYPE_OPERATE_ACCESS,
-                       .handler = operate_access,
-               },
-               {
-                       .type = NULL,
-                       .handler = NULL,
-               },
-       };
 
-       fp = fopen(descfile, "rt");
-       if (!fp) {
-               ErrPrint("Error: %s\n", strerror(errno));
-               return LB_STATUS_ERROR_IO;
+       if (block->type >= 0 || block->type < TYPE_MAX) {
+               (void)updators[block->type](handle, block, is_pd);
+       } else {
+               ErrPrint("Block type[%d] is not valid\n", block->type);
        }
+}
 
-       update_begin(handle, is_pd);
+static inline char *load_file(const char *filename)
+{
+       char *filebuf = NULL;
+       int fd;
+       off_t filesize;
+       int ret;
+       size_t readsize = 0;
+
+       fd = open(filename, O_RDONLY);
+       if (fd < 0) {
+               ErrPrint("open: %s\n", strerror(errno));
+               return NULL;
+       }
 
-       state = UNKNOWN;
-       field_idx = 0;
+       filesize = lseek(fd, 0L, SEEK_END);
+       if (filesize == (off_t)-1) {
+               ErrPrint("lseek: %s\n", strerror(errno));
+               goto errout;
+       }
 
-       block = NULL;
-       while (!feof(fp)) {
-               ch = getc(fp);
+       if (lseek(fd, 0L, SEEK_SET) < 0) {
+               ErrPrint("lseek: %s\n", strerror(errno));
+               goto errout;
+       }
 
-               switch (state) {
-               case UNKNOWN:
-                       if (ch == '{') {
-                               state = BLOCK_OPEN;
-                               break;
-                       }
+       filebuf = malloc(filesize + 1);
+       if (!filebuf) {
+               ErrPrint("malloc: %s\n", strerror(errno));
+               goto errout;
+       }
 
-                       if (!isspace(ch)) {
-                               update_end(handle, is_pd);
-                               if (fclose(fp) != 0) {
-                                       ErrPrint("fclose: %s\n", strerror(errno));
-                               }
-                               return LB_STATUS_ERROR_INVALID;
+       while (readsize < filesize) {
+               ret = read(fd, filebuf + readsize, (size_t)filesize - readsize);
+               if (ret < 0) {
+                       if (errno == EINTR) {
+                               DbgPrint("Read is interrupted\n");
+                               continue;
                        }
+
+                       ErrPrint("read: %s\n", strerror(errno));
+                       free(filebuf);
+                       filebuf = NULL;
                        break;
+               }
 
-               case BLOCK_OPEN:
-                       if (isblank(ch)) {
-                               break;
-                       }
+               readsize += ret;
+       }
 
-                       if (ch != '\n') {
-                               goto errout;
-                       }
+       if (filebuf) {
+               filebuf[readsize] = '\0';
+       }
 
-                       block = calloc(1, sizeof(*block));
-                       if (!block) {
-                               ErrPrint("Heap: %s\n", strerror(errno));
-                               update_end(handle, is_pd);
-                               if (fclose(fp) != 0) {
-                                       ErrPrint("fclose: %s\n", strerror(errno));
+       /*!
+        * \note
+        * Now, we are ready to parse the filebuf.
+        */
+
+errout:
+       if (close(fd) < 0) {
+               ErrPrint("close: %s\n", strerror(errno));
+       }
+
+       return filebuf;
+}
+
+int parse_desc(struct livebox_common *common, const char *filename, int is_pd)
+{
+       int type_idx = 0;
+       int type_len = 0;
+       int field_idx = 0;
+       int field_len = 0;
+       char *filebuf;
+       char *fileptr;
+       char *ptr = NULL;
+       struct block *block = NULL;
+       struct dlist *block_list = NULL;
+       struct dlist *l;
+       struct dlist *n;
+       struct dlist *handle_iterator;
+       struct livebox *handler;
+       enum state {
+               BEGIN,
+               FIELD,
+               DATA,
+               END,
+               DONE,
+               ERROR,
+       } state;
+
+       filebuf = load_file(filename);
+       if (!filebuf) {
+               return LB_STATUS_ERROR_IO;
+       }
+
+       fileptr = filebuf;
+
+       state = BEGIN;
+       while (*fileptr && state != ERROR) {
+               switch (state) {
+               case BEGIN:
+                       if (*fileptr == '{') {
+                               block = calloc(1, sizeof(*block));
+                               if (!block) {
+                                       ErrPrint("calloc: %s\n", strerror(errno));
+                                       state = ERROR;
+                                       continue;
                                }
-                               return LB_STATUS_ERROR_MEMORY;
+                               state = FIELD;
+                               ptr = NULL;
                        }
-
-                       state = FIELD;
-                       idx = 0;
-                       field_idx = 0;
                        break;
-
                case FIELD:
-                       if (isspace(ch)) {
-                               break;
-                       }
+                       if (isspace(*fileptr)) {
+                               if (ptr != NULL) {
+                                       *fileptr = '\0';
+                               }
+                       } else if (*fileptr == '=') {
+                               *fileptr = '\0';
+                               ptr = NULL;
+                               state = DATA;
+                       } else if (ptr == NULL) {
+                               ptr = fileptr;
+                               field_idx = 0;
+                               field_len = 0;
 
-                       if (ch == '}') {
-                               state = BLOCK_CLOSE;
-                               break;
-                       }
+                               while (field_list[field_idx]) {
+                                       if (field_list[field_idx][field_len] == *fileptr) {
+                                               break;
+                                       }
+                                       field_idx++;
+                               }
 
-                       if (ch == '=') {
-                               if (field_name[field_idx][idx] != '\0') {
-                                       goto errout;
+                               if (!field_list[field_idx]) {
+                                       ErrPrint("Invalid field\n");
+                                       state = ERROR;
+                                       continue;
                                }
 
-                               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;
+                               field_len++;
+                       } else {
+                               if (field_list[field_idx][field_len] != *fileptr) {
+                                       field_idx++;
+                                       while (field_list[field_idx]) {
+                                               if (!strncmp(field_list[field_idx], fileptr - field_len, field_len)) {
+                                                       break;
+                                               } else {
+                                                       field_idx++;
+                                               }
                                        }
-                                       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_OPTION;
-                                       if (block->option) {
-                                               free(block->option);
-                                               block->option = NULL;
-                                               block->option_len = 0;
-                                       }
-                                       idx = 0;
-                                       break;
-                               case 5:
-                                       state = VALUE_ID;
-                                       if (block->id) {
-                                               free(block->id);
-                                               block->id = NULL;
-                                               block->id_len = 0;
+
+                                       if (!field_list[field_idx]) {
+                                               state = ERROR;
+                                               ErrPrint("field is not valid\n");
+                                               continue;
                                        }
-                                       idx = 0;
-                                       break;
-                               default:
-                                       goto errout;
                                }
 
-                               break;
-                       }
-
-                       if (ch == '\n') {
-                               goto errout;
+                               field_len++;
                        }
+                       break;
+               case DATA:
+                       switch (field_idx) {
+                       case FIELD_TYPE:
+                               if (ptr == NULL) {
+                                       if (isspace(*fileptr)) {
+                                               break;
+                                       }
 
-                       if (field_name[field_idx][idx] != ch) {
-                               if (ungetc(ch, fp) != ch) {
-                                       ErrPrint("ungetc: %s\n", strerror(errno));
-                               }
-
-                               while (--idx >= 0) {
-                                       if (ungetc(field_name[field_idx][idx], fp) != field_name[field_idx][idx]) {
-                                               ErrPrint("ungetc: %s\n", strerror(errno));
+                                       if (*fileptr == '\0') {
+                                               state = ERROR;
+                                               ErrPrint("Type is not valid\n");
+                                               continue;
                                        }
+
+                                       ptr = fileptr;
+                                       type_idx = 0;
+                                       type_len = 0;
                                }
 
-                               field_idx++;
-                               if (field_name[field_idx] == NULL) {
-                                       goto errout;
+                               if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
+                                       *fileptr = '\0';
                                }
 
-                               idx = 0;
-                               break;
-                       }
+                               if (type_list[type_idx][type_len] != *fileptr) {
+                                       type_idx++;
+                                       while (type_list[type_idx]) {
+                                               if (!strncmp(type_list[type_idx], fileptr - type_len, type_len)) {
+                                                       break;
+                                               } else {
+                                                       type_idx++;
+                                               }
+                                       }
 
-                       idx++;
-                       break;
+                                       if (!type_list[type_idx]) {
+                                               state = ERROR;
+                                               ErrPrint("type is not valid (%s)\n", fileptr - type_len);
+                                               continue;
+                                       }
+                               }
 
-               case VALUE_TYPE:
-                       if (idx == block->type_len) {
-                               block->type_len += 256;
-                               block->type = realloc(block->type, block->type_len);
-                               if (!block->type) {
-                                       ErrPrint("Heap: %s\n", strerror(errno));
-                                       goto errout;
+                               if (!*fileptr) {
+                                       block->type = type_idx;
+                                       state = DONE;
+                                       ptr = NULL;
                                }
-                       }
 
-                       if (ch == '\n') {
-                               block->type[idx] = '\0';
-                               state = FIELD;
-                               idx = 0;
-                               field_idx = 0;
+                               type_len++;
                                break;
-                       }
-
-                       block->type[idx] = ch;
-                       idx++;
-                       break;
+                       case FIELD_PART:
+                               if (ptr == NULL) {
+                                       ptr = fileptr;
+                               }
 
-               case VALUE_PART:
-                       if (idx == block->part_len) {
-                               block->part_len += 256;
-                               block->part = realloc(block->part, block->part_len);
-                               if (!block->part) {
-                                       ErrPrint("Heap: %s\n", strerror(errno));
-                                       goto errout;
+                               if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
+                                       *fileptr = '\0';
                                }
-                       }
 
-                       if (ch == '\n') {
-                               block->part[idx] = '\0';
-                               state = FIELD;
-                               idx = 0;
-                               field_idx = 0;
+                               if (!*fileptr) {
+                                       block->part = ptr;
+                                       state = DONE;
+                                       ptr = NULL;
+                               }
                                break;
-                       }
-
-                       block->part[idx] = ch;
-                       idx++;
-                       break;
+                       case FIELD_DATA:
+                               if (ptr == NULL) {
+                                       ptr = fileptr;
+                               }
 
-               case VALUE_DATA:
-                       if (idx == block->data_len) {
-                               block->data_len += 256;
-                               block->data = realloc(block->data, block->data_len);
-                               if (!block->data) {
-                                       ErrPrint("Heap: %s\n", strerror(errno));
-                                       goto errout;
+                               if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
+                                       *fileptr = '\0';
                                }
-                       }
 
-                       if (ch == '\n') {
-                               block->data[idx] = '\0';
-                               state = FIELD;
-                               idx = 0;
-                               field_idx = 0;
+                               if (!*fileptr) {
+                                       block->data = ptr;
+                                       state = DONE;
+                                       ptr = NULL;
+                               }
                                break;
-                       }
-
-                       block->data[idx] = ch;
-                       idx++;
-                       break;
+                       case FIELD_OPTION:
+                               if (ptr == NULL) {
+                                       ptr = fileptr;
+                               }
 
-               case VALUE_FILE:
-                       if (idx == block->file_len) {
-                               block->file_len += 256;
-                               block->file = realloc(block->file, block->file_len);
-                               if (!block->file) {
-                                       ErrPrint("Heap: %s\n", strerror(errno));
-                                       goto errout;
+                               if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
+                                       *fileptr = '\0';
                                }
-                       }
 
-                       if (ch == '\n') {
-                               block->file[idx] = '\0';
-                               state = FIELD;
-                               idx = 0;
-                               field_idx = 0;
+                               if (!*fileptr) {
+                                       block->option = ptr;
+                                       state = DONE;
+                                       ptr = NULL;
+                               }
                                break;
-                       }
-
-                       block->file[idx] = ch;
-                       idx++;
-                       break;
+                       case FIELD_ID:
+                               if (ptr == NULL) {
+                                       ptr = fileptr;
+                               }
 
-               case VALUE_OPTION:
-                       if (idx == block->option_len) {
-                               block->option_len += 256;
-                               block->option = realloc(block->option, block->option_len);
-                               if (!block->option) {
-                                       ErrPrint("Heap: %s\n", strerror(errno));
-                                       goto errout;
+                               if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
+                                       *fileptr = '\0';
                                }
-                       }
 
-                       if (ch == '\n') {
-                               block->option[idx] = '\0';
-                               state = FIELD;
-                               idx = 0;
-                               field_idx = 0;
+                               if (!*fileptr) {
+                                       block->id = ptr;
+                                       state = DONE;
+                                       ptr = NULL;
+                               }
                                break;
-                       }
+                       case FIELD_TARGET:
+                               if (ptr == NULL) {
+                                       ptr = fileptr;
+                               }
 
-                       block->option[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) {
-                                       ErrPrint("Heap: %s\n", strerror(errno));
-                                       goto errout;
+                               if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
+                                       *fileptr = '\0';
                                }
-                       }
 
-                       if (ch == '\n') {
-                               block->id[idx] = '\0';
-                               state = FIELD;
-                               idx = 0;
-                               field_idx = 0;
+                               if (!*fileptr) {
+                                       block->target = ptr;
+                                       state = DONE;
+                                       ptr = NULL;
+                               }
                                break;
-                       }
+                       case FIELD_FILE:
+                               if (ptr == NULL) {
+                                       ptr = fileptr;
+                               }
 
-                       block->id[idx] = ch;
-                       idx++;
-                       break;
-               case BLOCK_CLOSE:
-                       if (!block->file) {
-                               block->file = strdup(util_uri_to_path(handle->id));
-                               if (!block->file) {
-                                       goto errout;
+                               if (*fileptr && (*fileptr == '\n' || *fileptr == '\r' || *fileptr == '\f')) {
+                                       *fileptr = '\0';
                                }
-                       }
 
-                       i = 0;
-                       while (handlers[i].type) {
-                               if (!strcasecmp(handlers[i].type, block->type)) {
-                                       handlers[i].handler(handle, block, is_pd);
-                                       break;
+                               if (!*fileptr) {
+                                       block->target = ptr;
+                                       state = DONE;
+                                       ptr = NULL;
                                }
-                               i++;
+                       default:
+                               break;
                        }
 
-                       if (!handlers[i].type) {
-                               ErrPrint("Unknown block type: %s\n", block->type);
+                       break;
+               case DONE:
+                       if (isspace(*fileptr)) {
+                       } else if (*fileptr == '}') {
+                                       state = BEGIN;
+                                       block->filename = filename;
+                                       block_list = dlist_append(block_list, block);
+                                       block = NULL;
+                       } else {
+                               state = FIELD;
+                               continue;
                        }
-
-                       free(block->file);
-                       free(block->type);
-                       free(block->part);
-                       free(block->data);
-                       free(block->option);
-                       free(block->id);
-                       free(block);
-                       block = NULL;
-
-                       state = UNKNOWN;
                        break;
-
+               case END:
                default:
                        break;
-               } /* switch */
-       } /* while */
+               }
 
-       if (state != UNKNOWN) {
-               goto errout;
+               fileptr++;
        }
 
-       update_end(handle, is_pd);
+       if (state != BEGIN) {
+               struct dlist *l;
+               struct dlist *n;
+               ErrPrint("State %d\n", state);
+
+               free(filebuf);
+               free(block);
 
-       if (fclose(fp) != 0) {
-               ErrPrint("fclose: %s\n", strerror(errno));
+               dlist_foreach_safe(block_list, l, n, block) {
+                       free(block);
+                       block_list = dlist_remove(block_list, l);
+               }
+
+               return LB_STATUS_ERROR_FAULT;
        }
-       return 0;
 
-errout:
-       ErrPrint("Parse error\n");
+               
+       block = dlist_data(dlist_prev(block_list));
        if (block) {
-               free(block->file);
-               free(block->type);
-               free(block->part);
-               free(block->data);
-               free(block->option);
-               free(block->id);
-               free(block);
+               block->filebuf = filebuf;
+       } else {
+               ErrPrint("Last block is not exists (There is no parsed block)\n");
+               free(filebuf);
+       }
+
+       ErrPrint("Begin: Set content for object\n");
+       dlist_foreach(common->livebox_list, l, handler) {
+               update_begin(handler, is_pd);
        }
 
-       update_end(handle, is_pd);
+       dlist_foreach_safe(block_list, l, n, block) {
+               dlist_foreach(common->livebox_list, handle_iterator, handler) {
+                       consuming_parsed_block(handler, is_pd, block);
+               }
 
-       if (fclose(fp) != 0) {
-               ErrPrint("fclose: %s\n", strerror(errno));
+               block_list = dlist_remove(block_list, l);
+               delete_block(block);
        }
-       return LB_STATUS_ERROR_INVALID;
+
+       dlist_foreach(common->livebox_list, l, handler) {
+               update_end(handler, is_pd);
+       }
+       ErrPrint("End: Set content for object\n");
+
+       return LB_STATUS_SUCCESS;
 }
 
 /* End of a file */
index 69c5dde..1dda034 100644 (file)
--- a/src/fb.c
+++ b/src/fb.c
@@ -436,7 +436,7 @@ void *fb_acquire_buffer(struct fb_info *info)
                } else if (!strncasecmp(info->id, SCHEMA_SHM, strlen(SCHEMA_SHM))) {
                        buffer = shmat(info->handle, NULL, 0);
                        if (buffer == (void *)-1) {
-                               ErrPrint("shmat: %s\n", strerror(errno));
+                               ErrPrint("shmat: %s (%d)\n", strerror(errno), info->handle);
                                return NULL;
                        }
 
index c9d3635..d8c6bc2 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 
+#include <gio/gio.h>
 #include <aul.h>
 #include <dlog.h>
 
 FILE *__file_log_fp;
 #endif
 
+enum event_state {
+       INFO_STATE_CALLBACK_IN_IDLE = 0x00,
+       INFO_STATE_CALLBACK_IN_PROCESSING = 0x01,
+};
+
 static struct info {
        struct dlist *livebox_list;
+       struct dlist *livebox_common_list;
+
        struct dlist *event_list;
        struct dlist *fault_list;
+
        int init_count;
        int prevent_overwrite;
        double event_filter;
+       enum event_state event_state;
+       enum event_state fault_state;
+       guint job_timer;
+       struct dlist *job_list;
 } s_info = {
        .livebox_list = NULL,
        .event_list = NULL,
@@ -63,6 +76,10 @@ static struct info {
        .init_count = 0,
        .prevent_overwrite = 0,
        .event_filter = 0.01f,
+       .event_state = INFO_STATE_CALLBACK_IN_IDLE,
+       .fault_state = INFO_STATE_CALLBACK_IN_IDLE,
+       .job_timer = 0,
+       .job_list = NULL,
 };
 
 struct cb_info {
@@ -71,15 +88,20 @@ struct cb_info {
 };
 
 struct event_info {
+       int is_deleted;
        int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data);
        void *user_data;
 };
 
 struct fault_info {
+       int is_deleted;
        int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data);
        void *user_data;
 };
 
+static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data);
+static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data);
+
 static inline void default_create_cb(struct livebox *handler, int ret, void *data)
 {
        DbgPrint("Default created event handler: %d\n", ret);
@@ -199,80 +221,80 @@ static int do_fb_unlock(int fd)
        return ret;
 }
 
-int lb_destroy_lock_file(struct livebox *info, int is_pd)
+int lb_destroy_lock_file(struct livebox_common *common, int is_pd)
 {
        if (is_pd) {
-               if (!info->pd.lock) {
-                       return -EINVAL;
+               if (!common->pd.lock) {
+                       return LB_STATUS_ERROR_INVALID;
                }
 
-               if (close(info->pd.lock_fd) < 0) {
+               if (close(common->pd.lock_fd) < 0) {
                        ErrPrint("close: %s\n", strerror(errno));
                }
-               info->pd.lock_fd = -1;
+               common->pd.lock_fd = -1;
 
-               if (unlink(info->pd.lock) < 0) {
+               if (unlink(common->pd.lock) < 0) {
                        ErrPrint("unlink: %s\n", strerror(errno));
                }
 
-               free(info->pd.lock);
-               info->pd.lock = NULL;
+               free(common->pd.lock);
+               common->pd.lock = NULL;
        } else {
-               if (!info->lb.lock) {
-                       return -EINVAL;
+               if (!common->lb.lock) {
+                       return LB_STATUS_ERROR_INVALID;
                }
 
-               if (close(info->lb.lock_fd) < 0) {
+               if (close(common->lb.lock_fd) < 0) {
                        ErrPrint("close: %s\n", strerror(errno));
                }
-               info->lb.lock_fd = -1;
+               common->lb.lock_fd = -1;
 
-               if (unlink(info->lb.lock) < 0) {
+               if (unlink(common->lb.lock) < 0) {
                        ErrPrint("unlink: %s\n", strerror(errno));
                }
 
-               free(info->lb.lock);
-               info->lb.lock = NULL;
+               free(common->lb.lock);
+               common->lb.lock = NULL;
        }
 
-       return 0;
+       return LB_STATUS_SUCCESS;
 }
 
-int lb_create_lock_file(struct livebox *info, int is_pd)
+int lb_create_lock_file(struct livebox_common *common, int is_pd)
 {
        int len;
        char *file;
 
-       len = strlen(info->id);
+       len = strlen(common->id);
        file = malloc(len + 20);
        if (!file) {
                ErrPrint("Heap: %s\n", strerror(errno));
-               return -ENOMEM;
+               return LB_STATUS_ERROR_MEMORY;
        }
 
-       snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(info->id), is_pd ? "pd" : "lb");
+       snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(common->id), is_pd ? "pd" : "lb");
 
        if (is_pd) {
-               info->pd.lock_fd = open(file, O_RDONLY);
-               if (info->pd.lock_fd < 0) {
+               common->pd.lock_fd = open(file, O_RDONLY);
+               if (common->pd.lock_fd < 0) {
                        ErrPrint("open: %s\n", strerror(errno));
                        free(file);
-                       return -EIO;
+                       return LB_STATUS_ERROR_IO;
                }
 
-               info->pd.lock = file;
+               common->pd.lock = file;
        } else {
-               info->lb.lock_fd = open(file, O_RDONLY);
-               if (info->lb.lock_fd < 0) {
+               common->lb.lock_fd = open(file, O_RDONLY);
+               if (common->lb.lock_fd < 0) {
                        ErrPrint("open: %s\n", strerror(errno));
                        free(file);
-                       return -EIO;
+                       return LB_STATUS_ERROR_IO;
                }
 
-               info->lb.lock = file;
+               common->lb.lock = file;
        }
 
-       return 0;
+       return LB_STATUS_SUCCESS;
 }
 
 static void update_mode_cb(struct livebox *handler, const struct packet *result, void *data)
@@ -296,9 +318,9 @@ static void update_mode_cb(struct livebox *handler, const struct packet *result,
        return;
 
 errout:
-       handler->update_mode_cb(handler, ret, handler->update_mode_cbdata);
-       handler->update_mode_cb = NULL;
-       handler->update_mode_cbdata = NULL;
+       handler->cbs.update_mode.cb(handler, ret, handler->cbs.update_mode.data);
+       handler->cbs.update_mode.cb = NULL;
+       handler->cbs.update_mode.data = NULL;
        return;
 }
 
@@ -332,9 +354,9 @@ static void resize_cb(struct livebox *handler, const struct packet *result, void
        return;
 
 errout:
-       handler->size_changed_cb(handler, ret, handler->size_cbdata);
-       handler->size_changed_cb = NULL;
-       handler->size_cbdata = NULL;
+       handler->cbs.size_changed.cb(handler, ret, handler->cbs.size_changed.data);
+       handler->cbs.size_changed.cb = NULL;
+       handler->cbs.size_changed.data = NULL;
 }
 
 static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data)
@@ -381,9 +403,9 @@ static void set_group_ret_cb(struct livebox *handler, const struct packet *resul
        return;
 
 errout:
-       handler->group_changed_cb(handler, ret, handler->group_cbdata);
-       handler->group_changed_cb = NULL;
-       handler->group_cbdata = NULL;
+       handler->cbs.group_changed.cb(handler, ret, handler->cbs.group_changed.data);
+       handler->cbs.group_changed.cb = NULL;
+       handler->cbs.group_changed.data = NULL;
 }
 
 static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data)
@@ -406,9 +428,9 @@ static void period_ret_cb(struct livebox *handler, const struct packet *result,
        return;
 
 errout:
-       handler->period_changed_cb(handler, ret, handler->period_cbdata);
-       handler->period_changed_cb = NULL;
-       handler->period_cbdata = NULL;
+       handler->cbs.period_changed.cb(handler, ret, handler->cbs.period_changed.data);
+       handler->cbs.period_changed.cb = NULL;
+       handler->cbs.period_changed.data = NULL;
 }
 
 static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data)
@@ -431,8 +453,8 @@ static void del_ret_cb(struct livebox *handler, const struct packet *result, voi
        }
 
        if (ret == 0) {
-               handler->deleted_cb = cb;
-               handler->deleted_cbdata = cbdata;
+               handler->cbs.deleted.cb = cb;
+               handler->cbs.deleted.data = cbdata;
        } else if (cb) {
                cb(handler, ret, cbdata);
        }
@@ -443,8 +465,8 @@ static void del_ret_cb(struct livebox *handler, const struct packet *result, voi
         * master will send the "deleted" event.
         * Then invoke this callback.
         *
-        * if (handler->deleted_cb)
-        *      handler->deleted_cb(handler, ret, handler->deleted_cbdata);
+        * if (handler->cbs.deleted.cb)
+        *      handler->cbs.deleted.cb(handler, ret, handler->cbs.deleted.data);
         */
 }
 
@@ -466,8 +488,8 @@ static void new_ret_cb(struct livebox *handler, const struct packet *result, voi
        }
 
        if (ret >= 0) {
-               handler->created_cb = cb;
-               handler->created_cbdata = cbdata;
+               handler->cbs.created.cb = cb;
+               handler->cbs.created.data = cbdata;
 
                /*!
                 * \note
@@ -484,7 +506,7 @@ static void new_ret_cb(struct livebox *handler, const struct packet *result, voi
                cb(handler, ret, cbdata);
        }
 
-       lb_unref(handler);
+       lb_unref(handler, 1);
 }
 
 static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data)
@@ -507,9 +529,9 @@ static void pd_create_cb(struct livebox *handler, const struct packet *result, v
        return;
 
 errout:
-       handler->pd_created_cb(handler, ret, handler->pd_created_cbdata);
-       handler->pd_created_cb = NULL;
-       handler->pd_created_cbdata = NULL;
+       handler->cbs.pd_created.cb(handler, ret, handler->cbs.pd_created.data);
+       handler->cbs.pd_created.cb = NULL;
+       handler->cbs.pd_created.data = NULL;
 }
 
 static void activated_cb(struct livebox *handler, const struct packet *result, void *data)
@@ -555,10 +577,10 @@ static void pd_destroy_cb(struct livebox *handler, const struct packet *result,
        }
 
        if (ret == 0) {
-               handler->pd_destroyed_cb = cb;
-               handler->pd_destroyed_cbdata = cbdata;
+               handler->cbs.pd_destroyed.cb = cb;
+               handler->cbs.pd_destroyed.data = cbdata;
        } else if (cb) {
-               handler->is_pd_created = 0;
+               handler->common->is_pd_created = 0;
                cb(handler, ret, cbdata);
        }
 }
@@ -607,6 +629,38 @@ static void delete_category_cb(struct livebox *handler, const struct packet *res
        }
 }
 
+static int lb_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
+{
+       struct packet *packet;
+       struct cb_info *cbinfo;
+       const char *id;
+       int ret;
+
+       id = fb_id(handler->common->lb.fb);
+       if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       packet = packet_create("lb_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
+       if (!packet) {
+               ErrPrint("Failed to build a param\n");
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       cbinfo = create_cb_info(cb, data);
+       if (!cbinfo) {
+               packet_destroy(packet);
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo);
+       if (ret < 0) {
+               destroy_cb_info(cbinfo);
+       }
+
+       return ret;
+}
+
 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
 {
        int pixmap;
@@ -626,7 +680,7 @@ static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *
        }
 
        if (ret == LB_STATUS_ERROR_BUSY) {
-               ret = livebox_acquire_lb_pixmap(handler, cb, cbdata);
+               ret = lb_acquire_lb_pixmap(handler, cb, cbdata);
                DbgPrint("Busy, Try again: %d\n", ret);
                /* Try again */
        } else {
@@ -636,6 +690,42 @@ static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *
        }
 }
 
+static int lb_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
+{
+       struct packet *packet;
+       struct cb_info *cbinfo;
+       const char *id;
+       int ret;
+
+       id = fb_id(handler->common->pd.fb);
+       if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       packet = packet_create("pd_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
+       if (!packet) {
+               ErrPrint("Failed to build a param\n");
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       cbinfo = create_cb_info(cb, data);
+       if (!cbinfo) {
+               packet_destroy(packet);
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo);
+       if (ret < 0) {
+               /*!
+                * \note
+                * Packet will be destroyed by master_rpc_async_request
+                */
+               destroy_cb_info(cbinfo);
+       }
+
+       return ret;
+}
+
 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
 {
        int pixmap;
@@ -657,7 +747,7 @@ static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *
        }
 
        if (ret == LB_STATUS_ERROR_BUSY) {
-               ret = livebox_acquire_pd_pixmap(handler, cb, cbdata);
+               ret = lb_acquire_pd_pixmap(handler, cb, cbdata);
                DbgPrint("Busy, Try again: %d\n", ret);
                /* Try again */
        } else {
@@ -686,9 +776,9 @@ static void pinup_done_cb(struct livebox *handler, const struct packet *result,
        return;
 
 errout:
-       handler->pinup_cb(handler, ret, handler->pinup_cbdata);
-       handler->pinup_cb = NULL;
-       handler->pinup_cbdata = NULL;
+       handler->cbs.pinup.cb(handler, ret, handler->cbs.pinup.data);
+       handler->cbs.pinup.cb = NULL;
+       handler->cbs.pinup.data = NULL;
 }
 
 static void key_ret_cb(struct livebox *handler, const struct packet *result, void *data)
@@ -711,9 +801,9 @@ static void key_ret_cb(struct livebox *handler, const struct packet *result, voi
 
        return;
 errout:
-       handler->key_event_cb(handler, ret, handler->key_event_cbdata);
-       handler->key_event_cb = NULL;
-       handler->key_event_cbdata = NULL;
+       handler->cbs.key_event.cb(handler, ret, handler->cbs.key_event.data);
+       handler->cbs.key_event.cb = NULL;
+       handler->cbs.key_event.data = NULL;
        return;
 }
 
@@ -738,9 +828,9 @@ static void access_ret_cb(struct livebox *handler, const struct packet *result,
        return;
 
 errout:
-       handler->access_event_cb(handler, ret, handler->access_event_cbdata);
-       handler->access_event_cb = NULL;
-       handler->access_event_cbdata = NULL;
+       handler->cbs.access_event.cb(handler, ret, handler->cbs.access_event.data);
+       handler->cbs.access_event.cb = NULL;
+       handler->cbs.access_event.data = NULL;
        return;
 }
 
@@ -751,7 +841,7 @@ static int send_access_event(struct livebox *handler, const char *event, int x,
 
        timestamp = util_timestamp();
 
-       packet = packet_create(event, "ssdii", handler->pkgname, handler->id, timestamp, x, y);
+       packet = packet_create(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
        if (!packet) {
                ErrPrint("Failed to build packet\n");
                return LB_STATUS_ERROR_FAULT;
@@ -766,7 +856,7 @@ static int send_key_event(struct livebox *handler, const char *event, unsigned i
        double timestamp;
 
        timestamp = util_timestamp();
-       packet = packet_create(event, "ssdi", handler->pkgname, handler->id, timestamp, keycode);
+       packet = packet_create(event, "ssdi", handler->common->pkgname, handler->common->id, timestamp, keycode);
        if (!packet) {
                ErrPrint("Failed to build packet\n");
                return LB_STATUS_ERROR_FAULT;
@@ -781,7 +871,7 @@ static int send_mouse_event(struct livebox *handler, const char *event, int x, i
        double timestamp;
 
        timestamp = util_timestamp();
-       packet = packet_create_noack(event, "ssdii", handler->pkgname, handler->id, timestamp, x, y);
+       packet = packet_create_noack(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
        if (!packet) {
                ErrPrint("Failed to build param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -883,6 +973,84 @@ static inline char *lb_pkgname(const char *pkgname)
        return lb;
 }
 
+static struct livebox_common *find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category)
+{
+       struct dlist *l;
+       struct livebox_common *common;
+
+       if (!conf_shared_content()) {
+               /*!
+                * Shared content option is turnned off.
+                */
+               return NULL;
+       }
+
+       dlist_foreach(s_info.livebox_common_list, l, common) {
+               if (common->state != CREATE) {
+                       continue;
+               }
+
+               if (strcmp(common->pkgname, pkgname)) {
+                       continue;
+               }
+
+               if (strcmp(common->cluster, cluster)) {
+                       DbgPrint("Cluster mismatched\n");
+                       continue;
+               }
+
+               if (strcmp(common->category, category)) {
+                       DbgPrint("Category mismatched\n");
+                       continue;
+               }
+
+               if (common->content && content) {
+                       if (strcmp(common->content, content)) {
+                               DbgPrint("%s Content ([%s] <> [%s])\n", common->pkgname, common->content, content);
+                               continue;       
+                       }
+               } else {
+                       int c1_len;
+                       int c2_len;
+
+                       /*!
+                        * \note
+                        * We assumes "" (ZERO length string) to NULL
+                        */
+                       c1_len = common->content ? strlen(common->content) : 0;
+                       c2_len = content ? strlen(content) : 0;
+                       if (c1_len != c2_len) {
+                               DbgPrint("%s Content %p <> %p\n", common->pkgname, common->content, content);
+                               continue;
+                       }
+               }
+
+               if (common->request.size_changed) {
+                       DbgPrint("Changing size\n");
+                       /*!
+                        * \note
+                        * Do not re-use resizing instance.
+                        * We will not use predicted size.
+                        */
+                       continue;
+               }
+
+               if (common->request.created) {
+                       DbgPrint("Creating now but re-use it (%s)\n", common->pkgname);
+               }
+
+               if (common->lb.width != w || common->lb.height != h) {
+                       DbgPrint("Size mismatched\n");
+                       continue;
+               }
+
+               DbgPrint("common handle is found: %p\n", common);
+               return common;
+       }
+
+       return NULL;
+}
+
 /*!
  * Just wrapping the livebox_add_with_size function.
  */
@@ -891,234 +1059,574 @@ EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const
        return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data);
 }
 
-EAPI struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data)
+static gboolean job_execute_cb(void *data)
 {
-       struct livebox *handler;
-       struct packet *packet;
-       int ret;
-       int width = 0;
-       int height = 0;
-       struct cb_info *cbinfo;
-
-       if (!pkgname || !cluster || !category) {
-               ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
-                                                               pkgname, cluster, category);
-               return NULL;
-       }
+       struct job_item *item;
+       struct dlist *l;
 
-       if (type != LB_SIZE_TYPE_UNKNOWN) {
-               (void)livebox_service_get_size(type, &width, &height);
+       l = dlist_nth(s_info.job_list, 0);
+       if (!l) {
+               s_info.job_timer = 0;
+               return FALSE;
        }
 
-       handler = calloc(1, sizeof(*handler));
-       if (!handler) {
-               ErrPrint("Error: %s\n", strerror(errno));
-               return NULL;
-       }
+       item = dlist_data(l);
+       s_info.job_list = dlist_remove(s_info.job_list, l);
 
-       handler->pkgname = lb_pkgname(pkgname);
-       if (!handler->pkgname) {
-               free(handler);
-               return NULL;
+       if (item) {
+               item->cb(item->handle, item->ret, item->data);
+               lb_unref(item->handle, 1);
+               free(item);
        }
 
-       if (livebox_service_is_enabled(handler->pkgname) == 0) {
-               DbgPrint("Livebox [%s](%s) is disabled package\n", handler->pkgname, pkgname);
-               free(handler->pkgname);
-               free(handler);
-               return NULL;
-       }
+       return TRUE;
+}
 
-       if (content && strlen(content)) {
-               handler->content = strdup(content);
-               if (!handler->content) {
-                       ErrPrint("Error: %s\n", strerror(errno));
-                       free(handler->pkgname);
-                       free(handler);
-                       return NULL;
-               }
-       } else {
-               handler->content = livebox_service_content(handler->pkgname);
-       }
+static int job_add(struct livebox *handle, ret_cb_t job_cb, int ret, void *data)
+{
+       struct job_item *item;
 
-       handler->cluster = strdup(cluster);
-       if (!handler->cluster) {
-               ErrPrint("Error: %s\n", strerror(errno));
-               free(handler->content);
-               free(handler->pkgname);
-               free(handler);
-               return NULL;
+       if (!job_cb) {
+               ErrPrint("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
        }
 
-       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;
+       item = malloc(sizeof(*item));
+       if (!item) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return LB_STATUS_ERROR_MEMORY;
        }
 
-       if (!cb) {
-               cb = default_create_cb;
-       }
+       item->handle = lb_ref(handle);
+       item->cb = job_cb;
+       item->data = data;
+       item->ret = ret;
 
-       /* Data provider will set this */
-       handler->lb.type = _LB_TYPE_FILE;
-       handler->pd.type = _PD_TYPE_SCRIPT;
-       handler->lb.period = period;
+       s_info.job_list = dlist_append(s_info.job_list, item);
 
-       /* Used for handling the mouse event on a box */
-       handler->lb.mouse_event = livebox_service_mouse_event(handler->pkgname);
+       if (!s_info.job_timer) {
+               s_info.job_timer = g_timeout_add(1, job_execute_cb, NULL);
+               if (!s_info.job_timer) {
+                       ErrPrint("Failed to create a job timer\n");
+               }
+       }
 
-       /* Cluster infomration is not determined yet */
-       handler->nr_of_sizes = 0x01;
+       return LB_STATUS_SUCCESS;
+}
 
-       handler->timestamp = util_timestamp();
-       handler->is_user = 1;
-       handler->visible = LB_SHOW;
-       handler->delete_type = LB_DELETE_PERMANENTLY;
-       handler->pd.lock = NULL;
-       handler->pd.lock_fd = -1;
-       handler->lb.lock = NULL;
-       handler->lb.lock_fd = -1;
+static int create_real_instance(struct livebox *handler, ret_cb_t cb, void *data)
+{
+       struct cb_info *cbinfo;
+       struct packet *packet;
+       struct livebox_common *common;
+       int ret;
 
-       s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
+       common = handler->common;
 
-       packet = packet_create("new", "dssssdii", handler->timestamp, handler->pkgname, handler->content, cluster, category, period, width, height);
+       packet = packet_create("new", "dssssdii",
+                               common->timestamp, common->pkgname, common->content,
+                               common->cluster, common->category,
+                               common->lb.period, common->lb.width, common->lb.height);
        if (!packet) {
                ErrPrint("Failed to create a new packet\n");
-               free(handler->category);
-               free(handler->cluster);
-               free(handler->content);
-               free(handler->pkgname);
-               free(handler);
-               return NULL;
+               return LB_STATUS_ERROR_FAULT;
        }
 
        cbinfo = create_cb_info(cb, data);
        if (!cbinfo) {
                ErrPrint("Failed to create a cbinfo\n");
                packet_destroy(packet);
-               free(handler->category);
-               free(handler->cluster);
-               free(handler->content);
-               free(handler->pkgname);
-               free(handler);
-               return NULL;
+               return LB_STATUS_ERROR_MEMORY;
        }
 
+       /*!
+        * \note
+        * master_rpc_async_request will destroy the packet (decrease the refcnt)
+        * So be aware the packet object after return from master_rpc_async_request.
+        */
        ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo);
        if (ret < 0) {
                ErrPrint("Failed to send a new packet\n");
                destroy_cb_info(cbinfo);
-               free(handler->category);
-               free(handler->cluster);
-               free(handler->content);
-               free(handler->pkgname);
-               free(handler);
-               return NULL;
+               return LB_STATUS_ERROR_FAULT;
        }
-
-       handler->state = CREATE;
-       return lb_ref(handler);
+       handler->common->request.created = 1;
+       return LB_STATUS_SUCCESS;
 }
 
-EAPI double livebox_period(struct livebox *handler)
+static void create_cb(struct livebox *handle, int ret, void *data)
 {
-       if (!handler || handler->state != CREATE || !handler->id) {
-               ErrPrint("Handler is not valid\n");
-               return 0.0f;
+       struct cb_info *cbinfo = data;
+
+       if (cbinfo->cb) {
+               cbinfo->cb(handle, ret, cbinfo->data);
        }
 
-       return handler->lb.period;
+       destroy_cb_info(cbinfo);
+
+       /*!
+        * \note
+        * Forcely generate "updated" event
+        */
+       lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
 }
 
-EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
+static int create_fake_instance(struct livebox *handler, ret_cb_t cb, void *data)
 {
-       struct packet *packet;
-       int ret;
+       struct cb_info *cbinfo;
 
-       if (!handler || handler->state != CREATE || !handler->id) {
-               ErrPrint("Handler is not valid\n");
-               return LB_STATUS_ERROR_INVALID;
+       cbinfo = create_cb_info(cb, data);
+       if (!cbinfo) {
+               ErrPrint("Failed to create a cbinfo\n");
+               return LB_STATUS_ERROR_MEMORY;
        }
 
-       if (handler->period_changed_cb) {
-               ErrPrint("Previous request for changing period is not finished\n");
-               return LB_STATUS_ERROR_BUSY;
+       if (job_add(handler, create_cb, LB_STATUS_SUCCESS, cbinfo) != LB_STATUS_SUCCESS) {
+               destroy_cb_info(cbinfo);
        }
 
-       if (!handler->is_user) {
-               ErrPrint("CA Livebox is not able to change the period\n");
-               return LB_STATUS_ERROR_PERMISSION;
-       }
+       return LB_STATUS_SUCCESS;
+}
 
-       if (handler->lb.period == period) {
-               DbgPrint("No changes\n");
-               return LB_STATUS_ERROR_ALREADY;
+struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category)
+{
+       struct livebox_common *common;
+
+       common = calloc(1, sizeof(*common));
+       if (!common) {
+               ErrPrint("Heap: %s\n", strerror(errno));
+               return NULL;
        }
 
-       packet = packet_create("set_period", "ssd", handler->pkgname, handler->id, period);
-       if (!packet) {
-               ErrPrint("Failed to build a packet %s\n", handler->pkgname);
-               return LB_STATUS_ERROR_FAULT;
+       common->pkgname = strdup(pkgname);
+       if (!common->pkgname) {
+               free(common);
+               return NULL;
        }
 
-       if (!cb) {
-               cb = default_period_changed_cb;
+       common->cluster = strdup(cluster);
+       if (!common->cluster) {
+               ErrPrint("Error: %s\n", strerror(errno));
+               free(common->pkgname);
+               free(common);
+               return NULL;
        }
 
-       ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
-       if (ret == LB_STATUS_SUCCESS) {
-               handler->period_changed_cb = cb;
-               handler->period_cbdata = data;
+       common->category = strdup(category);
+       if (!common->category) {
+               ErrPrint("Error: %s\n", strerror(errno));
+               free(common->cluster);
+               free(common->pkgname);
+               free(common);
+               return NULL;
        }
 
-       return ret;
+       /* Data provider will set this */
+       common->lb.type = _LB_TYPE_FILE;
+       common->pd.type = _PD_TYPE_SCRIPT;
+
+       /* Used for handling the mouse event on a box */
+       common->lb.mouse_event = livebox_service_mouse_event(common->pkgname);
+
+       /* Cluster infomration is not determined yet */
+       common->nr_of_sizes = 0x01;
+
+       common->timestamp = util_timestamp();
+       common->is_user = 1;
+       common->delete_type = LB_DELETE_PERMANENTLY;
+       common->pd.lock = NULL;
+       common->pd.lock_fd = -1;
+       common->lb.lock = NULL;
+       common->lb.lock_fd = -1;
+
+       common->state = CREATE;
+       common->visible = LB_SHOW;
+
+       s_info.livebox_common_list = dlist_append(s_info.livebox_common_list, common);
+       return common;
 }
 
-EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data)
+int lb_destroy_common_handle(struct livebox_common *common)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
-               return LB_STATUS_ERROR_INVALID;
-       }
+       dlist_remove_data(s_info.livebox_common_list, common);
 
-       if (handler->state != CREATE) {
-               ErrPrint("Handler is already deleted\n");
-               return LB_STATUS_ERROR_INVALID;
-       }
+       common->state = DESTROYED;
+       free(common->cluster);
+       free(common->category);
+       free(common->id);
+       free(common->pkgname);
+       free(common->filename);
+       free(common->lb.auto_launch);
+       free(common->alt.icon);
+       free(common->alt.name);
 
-       handler->state = DELETE;
-       handler->delete_type = type;
+       if (common->lb.fb) {
+               fb_destroy(common->lb.fb);
+               common->lb.fb = NULL;
+       }
 
-       if (!handler->id) {
-               /*!
-                * \note
-                * The id is not determined yet.
-                * It means a user didn't receive created event yet.
-                * Then just stop to delete procedure from here.
-                * Because the "created" event handler will release this.
-                * By the way, if the user adds any callback for getting return status of this,
-                * call it at here.
-                */
-               if (cb) {
-                       cb(handler, 0, data);
-               }
-               return LB_STATUS_SUCCESS;
+       if (common->pd.fb) {
+               fb_destroy(common->pd.fb);
+               common->pd.fb = NULL;
+       }
+
+       return 0;
+}
+
+int lb_common_ref(struct livebox_common *common, struct livebox *handle)
+{
+       common->livebox_list = dlist_append(common->livebox_list, handle);
+       common->refcnt++;
+
+       return common->refcnt;
+}
+
+int lb_common_unref(struct livebox_common *common, struct livebox *handle)
+{
+       int refcnt;
+       dlist_remove_data(common->livebox_list, handle);
+       refcnt = --common->refcnt;
+
+       return refcnt;
+}
+
+static void refresh_for_paused_updating_cb(struct livebox *handle, int ret, void *data)
+{
+       if (handle->paused_updating == 0) {
+               DbgPrint("Paused updates are cleared\n");
+               return;
+       }
+
+       DbgPrint("Pending updates are found\n");
+       lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
+}
+
+static int lb_set_visibility(struct livebox *handler, enum livebox_visible_state state)
+{
+       struct packet *packet;
+       int need_to_add_job = 0;
+       int ret;
+
+       if (handler->common->visible != LB_SHOW && state == LB_SHOW) {
+               if (handler->paused_updating) {
+                       need_to_add_job = 1;
+               }
+       } else if (handler->common->visible == LB_SHOW && state != LB_SHOW) {
+               struct dlist *l;
+               struct livebox *item;
+
+               dlist_foreach(handler->common->livebox_list, l, item) {
+                       if (item->visible == LB_SHOW) {
+                               DbgPrint("%s visibility is not changed\n", handler->common->pkgname);
+                               return LB_STATUS_SUCCESS;
+                       }
+               }
+       } else if (handler->common->visible == LB_SHOW && state == LB_SHOW && handler->paused_updating) {
+               if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
+                       ErrPrint("Unable to add a new job for refreshing box\n");
+               }
+
+               return LB_STATUS_SUCCESS;
+       } else {
+               /*!
+                * \brief
+                * No need to send this to the master
+                */
+               return LB_STATUS_SUCCESS;
+       }
+
+       packet = packet_create_noack("change,visibility", "ssi", handler->common->pkgname, handler->common->id, (int)state);
+       if (!packet) {
+               ErrPrint("Failed to create a packet\n");
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       ret = master_rpc_request_only(handler, packet);
+       if (ret == LB_STATUS_SUCCESS) {
+               DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state);
+               handler->common->visible = state;
+
+               if (need_to_add_job) {
+                       if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
+                               ErrPrint("Unable to add a new job for refreshing box\n");
+                       }
+               }
+       }
+
+       return ret;
+}
+
+EAPI struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data)
+{
+       char *lbid;
+       struct livebox *handler;
+       int w = 0;
+       int h = 0;
+
+       if (!pkgname || !cluster || !category) {
+               ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
+                                                               pkgname, cluster, category);
+               return NULL;
+       }
+
+       lbid = lb_pkgname(pkgname);
+       if (!lbid) {
+               ErrPrint("Invalid package: %s\n", pkgname);
+               return NULL;
+       }
+
+       if (livebox_service_is_enabled(lbid) == 0) {
+               DbgPrint("Livebox [%s](%s) is disabled package\n", lbid, pkgname);
+               free(lbid);
+               return NULL;
+       }
+
+       if (type != LB_SIZE_TYPE_UNKNOWN) {
+               (void)livebox_service_get_size(type, &w, &h);
+       }
+
+       handler = calloc(1, sizeof(*handler));
+       if (!handler) {
+               ErrPrint("Error: %s\n", strerror(errno));
+               free(lbid);
+               return NULL;
        }
 
        if (!cb) {
-               cb = default_delete_cb;
+               cb = default_create_cb;
        }
 
-       return lb_send_delete(handler, type, cb, data);
+       handler->common = find_sharable_common_handle(lbid, content, w, h, cluster, category);
+       if (!handler->common) {
+               handler->common = lb_create_common_handle(handler, lbid, cluster, category);
+               free(lbid);
+               if (!handler->common) {
+                       ErrPrint("Failed to find common handle\n");
+                       free(handler);
+                       return NULL;
+               }
+
+               if (!content || !strlen(content)) {
+                       char *pc;
+                       /*!
+                        * \note
+                        * I know the content should not be modified. use it temporarly without "const"
+                        */
+                       pc = livebox_service_content(handler->common->pkgname);
+                       lb_set_content(handler->common, pc);
+                       free(pc);
+               } else {
+                       lb_set_content(handler->common, content);
+               }
+
+               lb_set_period(handler->common, period);
+               lb_set_size(handler->common, w, h);
+               lb_common_ref(handler->common, handler);
+
+               if (create_real_instance(handler, cb, data) < 0) {
+                       if (lb_common_unref(handler->common, handler) == 0) {
+                               /*!
+                                * Delete common
+                                */
+                               lb_destroy_common_handle(handler->common);
+                               handler->common = NULL;
+                       }
+                       free(handler);
+                       return NULL;
+               }
+       } else {
+               free(lbid);
+
+               lb_common_ref(handler->common, handler);
+
+               if (handler->common->request.created) {
+                       /*!
+                        * If a box is in creating, wait its result too
+                        */
+                       handler->cbs.created.cb = cb;
+                       handler->cbs.created.data = data;
+               } else {
+                       /*!
+                        * or fire the fake created_event
+                        */
+                       if (create_fake_instance(handler, cb, data) < 0) {
+                               if (lb_common_unref(handler->common, handler) == 0) {
+                                       /*!
+                                        * Delete common
+                                        */
+                                       lb_destroy_common_handle(handler->common);
+                               }
+                               free(handler);
+                               return NULL;
+                       }
+               }
+       }
+
+       handler->visible = LB_SHOW;
+       handler->state = CREATE;
+       handler = lb_ref(handler);
+
+       if (handler->common->visible != LB_SHOW) {
+               lb_set_visibility(handler, LB_SHOW);
+       }
+
+       return handler;
 }
 
-EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
+EAPI double livebox_period(struct livebox *handler)
+{
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return 0.0f;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return 0.0f;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Hnalder is not valid\n");
+               return 0.0f;
+       }
+
+       return handler->common->lb.period;
+}
+
+EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
+{
+       struct packet *packet;
+       int ret;
+
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Handler is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (handler->common->request.period_changed) {
+               ErrPrint("Previous request for changing period is not finished\n");
+               return LB_STATUS_ERROR_BUSY;
+       }
+
+       if (!handler->common->is_user) {
+               ErrPrint("CA Livebox is not able to change the period\n");
+               return LB_STATUS_ERROR_PERMISSION;
+       }
+
+       if (handler->common->lb.period == period) {
+               DbgPrint("No changes\n");
+               return LB_STATUS_ERROR_ALREADY;
+       }
+
+       packet = packet_create("set_period", "ssd", handler->common->pkgname, handler->common->id, period);
+       if (!packet) {
+               ErrPrint("Failed to build a packet %s\n", handler->common->pkgname);
+               return LB_STATUS_ERROR_FAULT;
+       }
+
+       if (!cb) {
+               cb = default_period_changed_cb;
+       }
+
+       ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
+       if (ret == LB_STATUS_SUCCESS) {
+               handler->cbs.period_changed.cb = cb;
+               handler->cbs.period_changed.data = data;
+               handler->common->request.period_changed = 1;
+       }
+
+       return ret;
+}
+
+static void lb_update_visibility(struct livebox_common *old_common)
 {
+       struct dlist *l;
+       struct livebox *item;
+
+       item = NULL;
+       dlist_foreach(old_common->livebox_list, l, item) {
+               if (item->visible == LB_SHOW) {
+                       break;
+               }
+
+               item = NULL;
+       }
+
+       if (!item) {
+               l = dlist_nth(old_common->livebox_list, 0);
+               item = dlist_data(l);
+
+               if (item) {
+                       lb_set_visibility(item, LB_HIDE_WITH_PAUSE);
+               } else {
+                       ErrPrint("Unable to get the valid handle from common handler\n");
+               }
+       }
+}
+
+/*!
+ * \note
+ * The second parameter should be the "return value",
+ * But in this case, we will use it for "type of deleting instance".
+ */
+static void job_del_cb(struct livebox *handle, int type, void *data)
+{
+       struct cb_info *cbinfo = data;
+       ret_cb_t cb;
+
+       if (handle->visible == LB_SHOW) {
+               lb_update_visibility(handle->common);
+       }
+
+       cb = cbinfo->cb;
+       data = cbinfo->data;
+       destroy_cb_info(cbinfo);
+
+       if (handle->common->refcnt == 1) {
+               handle->common->delete_type = type;
+               handle->common->state = DELETE;
+
+               if (!handle->common->id) {
+                       /*!
+                        * \note
+                        * The id is not determined yet.
+                        * It means a user didn't receive created event yet.
+                        * Then just stop to delete procedure from here.
+                        * Because the "created" event handle will release this.
+                        * By the way, if the user adds any callback for getting return status of this,
+                        * call it at here.
+                        */
+                       if (cb) {
+                               cb(handle, LB_STATUS_SUCCESS, data);
+                       }
+               }
+
+               DbgPrint("Send delete request\n");
+               lb_send_delete(handle, type, cb, data);
+       } else {
+               if (cb) {
+                       cb(handle, LB_STATUS_SUCCESS, data);
+               }
+
+               DbgPrint("Before unref: %d\n", handle->common->refcnt);
+               lb_unref(handle, 1);
+       }
+}
+
+EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data)
+{
+       struct cb_info *cbinfo;
+
        if (!handler) {
                ErrPrint("Handler is NIL\n");
                return LB_STATUS_ERROR_INVALID;
@@ -1130,29 +1638,25 @@ EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
        }
 
        handler->state = DELETE;
-       handler->delete_type = LB_DELETE_PERMANENTLY;
 
-       if (!handler->id) {
-               /*!
-                * \note
-                * The id is not determined yet.
-                * It means a user didn't receive created event yet.
-                * Then just stop to delete procedure from here.
-                * Because the "created" event handler will release this.
-                * By the way, if the user adds any callback for getting return status of this,
-                * call it at here.
-                */
-               if (cb) {
-                       cb(handler, 0, data);
-               }
-               return LB_STATUS_SUCCESS;
+       cbinfo = create_cb_info(cb, data);
+       if (!cbinfo) {
+               ErrPrint("Failed to create a cbinfo\n");
+               return LB_STATUS_ERROR_MEMORY;
        }
 
-       if (!cb) {
-               cb = default_delete_cb;
+       if (job_add(handler, job_del_cb, type, cbinfo) != LB_STATUS_SUCCESS) {
+               ErrPrint("Failed to add a new job\n");
+               destroy_cb_info(cbinfo);
+               return LB_STATUS_ERROR_FAULT;
        }
 
-       return lb_send_delete(handler, LB_DELETE_PERMANENTLY, cb, data);
+       return LB_STATUS_SUCCESS;
+}
+
+EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
+{
+       return livebox_del_NEW(handler, LB_DELETE_PERMANENTLY, cb, data);
 }
 
 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
@@ -1171,6 +1675,7 @@ EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char
 
        info->handler = cb;
        info->user_data = data;
+       info->is_deleted = 0;
 
        s_info.fault_list = dlist_append(s_info.fault_list, info);
        return LB_STATUS_SUCCESS;
@@ -1185,9 +1690,14 @@ EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const
                if (info->handler == cb) {
                        void *data;
 
-                       s_info.fault_list = dlist_remove(s_info.fault_list, l);
                        data = info->user_data;
-                       free(info);
+
+                       if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
+                               info->is_deleted = 1;
+                       } else {
+                               s_info.fault_list = dlist_remove(s_info.fault_list, l);
+                               free(info);
+                       }
 
                        return data;
                }
@@ -1213,6 +1723,7 @@ EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_even
 
        info->handler = cb;
        info->user_data = data;
+       info->is_deleted = 0;
 
        s_info.event_list = dlist_append(s_info.event_list, info);
        return LB_STATUS_SUCCESS;
@@ -1227,9 +1738,14 @@ EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_
                if (info->handler == cb) {
                        void *data;
 
-                       s_info.event_list = dlist_remove(s_info.event_list, l);
                        data = info->user_data;
-                       free(info);
+
+                       if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
+                               info->is_deleted = 1;
+                       } else {
+                               s_info.event_list = dlist_remove(s_info.event_list, l);
+                               free(info);
+                       }
 
                        return data;
                }
@@ -1243,29 +1759,35 @@ EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret
        struct packet *packet;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is Invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is Invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
+               ErrPrint("Handler is Invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->update_mode_cb) {
+       if (handler->common->request.update_mode) {
                ErrPrint("Previous update_mode cb is not finished yet\n");
                return LB_STATUS_ERROR_BUSY;
        }
 
-       if (handler->is_active_update == active_update) {
+       if (handler->common->is_active_update == active_update) {
                return LB_STATUS_ERROR_ALREADY;
        }
 
-       if (!handler->is_user) {
+       if (!handler->common->is_user) {
                return LB_STATUS_ERROR_PERMISSION;
        }
 
-       packet = packet_create("update_mode", "ssi", handler->pkgname, handler->id, active_update);
+       packet = packet_create("update_mode", "ssi", handler->common->pkgname, handler->common->id, active_update);
        if (!packet) {
                return LB_STATUS_ERROR_FAULT;
        }
@@ -1276,8 +1798,9 @@ EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret
 
        ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL);
        if (ret == LB_STATUS_SUCCESS) {
-               handler->update_mode_cb = cb;
-               handler->update_mode_cbdata = data;
+               handler->cbs.update_mode.cb = cb;
+               handler->cbs.update_mode.data = data;
+               handler->common->request.update_mode = 1;
        }
 
        return ret;
@@ -1285,69 +1808,209 @@ EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret
 
 EAPI int livebox_is_active_update(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is Invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is Invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return handler->is_active_update;
+       if (!handler->common->id) {
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return handler->common->is_active_update;
+}
+
+static void resize_job_cb(struct livebox *handler, int ret, void *data)
+{
+       struct cb_info *info = data;
+
+       if (info->cb) {
+               info->cb(handler, ret, info->data);
+       }
+
+       free(info);
+
+       /*!
+        * \note
+        * Forcely update the box
+        */
+       lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
 }
 
 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
 {
-       struct packet *packet;
+       struct livebox_common *common;
        int w;
        int h;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       /*!
+        * \TODO
+        * If this handle is host instance or link instance,
+        * Create a new instance or find another linkable instance.
+        */
+
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->size_changed_cb) {
+       /*!
+        * \note
+        * resize operation should be separated by each handler.
+        * If a handler is resizing, the other handler can request resize too.
+        * So we should not use the common->request.size_changed flag.
+        */
+       if (handler->cbs.size_changed.cb) {
                ErrPrint("Previous resize request is not finished yet\n");
                return LB_STATUS_ERROR_BUSY;
        }
 
-       if (!handler->is_user) {
-               ErrPrint("CA Livebox is not able to be resized\n");
-               return LB_STATUS_ERROR_PERMISSION;
-       }
-
        if (livebox_service_get_size(type, &w, &h) != 0) {
                ErrPrint("Invalid size type\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->lb.width == w && handler->lb.height == h) {
+       if (handler->common->lb.width == w && handler->common->lb.height == h) {
                DbgPrint("No changes\n");
                return LB_STATUS_ERROR_ALREADY;
        }
 
-       packet = packet_create("resize", "ssii", handler->pkgname, handler->id, w, h);
-       if (!packet) {
-               ErrPrint("Failed to build param\n");
-               return LB_STATUS_ERROR_FAULT;
+       if (!handler->common->is_user) {
+               ErrPrint("CA Livebox is not able to be resized\n");
+               return LB_STATUS_ERROR_PERMISSION;
        }
 
-       if (!cb) {
-               cb = default_lb_size_changed_cb;
-       }
+       if (handler->common->refcnt <= 1) {
+               struct packet *packet;
 
-       ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
-       if (ret == LB_STATUS_SUCCESS) {
-               handler->size_changed_cb = cb;
-               handler->size_cbdata = data;
+               /* Only 1 instance */
+               packet = packet_create("resize", "ssii", handler->common->pkgname, handler->common->id, w, h);
+               if (!packet) {
+                       ErrPrint("Failed to build param\n");
+                       return LB_STATUS_ERROR_FAULT;
+               }
+
+               if (!cb) {
+                       cb = default_lb_size_changed_cb;
+               }
+
+               ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
+               if (ret == LB_STATUS_SUCCESS) {
+                       handler->cbs.size_changed.cb = cb;
+                       handler->cbs.size_changed.data = data;
+                       handler->common->request.size_changed = 1;
+               }
+       } else {
+               common = find_sharable_common_handle(handler->common->pkgname, handler->common->content, w, h, handler->common->cluster, handler->common->category);
+               if (!common) {
+                       struct livebox_common *old_common;
+                       /*!
+                        * \note
+                        * If the common handler is in resizing,
+                        * if user tries to resize a hander, then simply create new one even if the requested size is same with this.
+
+                       if (handler->common->request.size_changed) {
+                       }
+
+                        */
+
+                       old_common = handler->common;
+
+                       common = lb_create_common_handle(handler, old_common->pkgname, old_common->cluster, old_common->category);
+                       if (!common) {
+                               ErrPrint("Failed to create common handle\n");
+                               return LB_STATUS_ERROR_FAULT;
+                       }
+
+                       lb_set_size(common, w, h);
+                       lb_set_content(common, old_common->content);
+                       lb_set_period(common, old_common->lb.period);
+
+                       /*!
+                        * \note
+                        * Disconnecting from old one.
+                        */
+                       if (lb_common_unref(old_common, handler) == 0) {
+                               /*!
+                                * \note
+                                * Impossible
+                                */
+                               ErrPrint("Common has no associated handler\n");
+                       }
+
+                       lb_common_ref(common, handler);
+
+                       /*!
+                        * Connect to a new one
+                        */
+                       handler->common = common;
+
+                       /*!
+                        * \TODO
+                        * Need to care, if it fails to create a common handle,
+                        * the resize operation will be failed.
+                        * in that case, we should reuse the old common handle
+                        */
+                       ret = create_real_instance(handler, cb, data);
+                       if (ret < 0) {
+                               lb_common_unref(common, handler);
+                               lb_destroy_common_handle(common);
+
+                               lb_common_ref(old_common, handler);
+                               handler->common = old_common;
+                       } else {
+                               /*!
+                                * In this case, we should update visibility of old_common's liveboxes
+                                */
+                               if (handler->visible == LB_SHOW) {
+                                       lb_update_visibility(old_common);
+                               }
+                       }
+               } else {
+                       struct cb_info *cbinfo;
+
+                       cbinfo = create_cb_info(cb, data);
+                       if (!cbinfo) {
+                               ErrPrint("Failed to create a cbinfo\n");
+                               ret = LB_STATUS_ERROR_MEMORY;
+                       } else {
+                               ret = job_add(handler, resize_job_cb, LB_STATUS_SUCCESS, cbinfo);
+                               if (ret == LB_STATUS_SUCCESS) {
+                                       struct livebox_common *old_common;
+
+                                       old_common = handler->common;
+
+                                       if (lb_common_unref(handler->common, handler) == 0) {
+                                               ErrPrint("Old common has no associated handler\n");
+                                       }
+
+                                       lb_common_ref(common, handler);
+                                       handler->common = common;
+
+                                       if (handler->visible == LB_SHOW) {
+                                               lb_update_visibility(old_common);
+                                       }
+                               } else {
+                                       destroy_cb_info(cbinfo);
+                               }
+                       }
+               }
        }
 
        return ret;
@@ -1359,47 +2022,66 @@ EAPI int livebox_click(struct livebox *handler, double x, double y)
        double timestamp;
        int ret;
 
-       timestamp = util_timestamp();
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->lb.auto_launch) {
-               DbgPrint("AUTO_LAUNCH [%s]\n", handler->lb.auto_launch);
-               if (aul_launch_app(handler->lb.auto_launch, NULL) < 0) {
-                       ErrPrint("Failed to launch app %s\n", handler->lb.auto_launch);
+       if (handler->common->lb.auto_launch) {
+/*
+               service_h service;
+
+               DbgPrint("AUTO_LAUNCH [%s]\n", handler->common->lb.auto_launch);
+
+               ret = service_create(&service);
+               if (ret == SERVICE_ERROR_NONE) {
+                       service_set_package(service, handler->common->lb.auto_launch);
+                       service_send_launch_request(service, NULL, NULL);
+                       service_destroy(service);
+               } else {
+                       ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
+               }
+*/
+               ret = aul_launch_app(handler->common->lb.auto_launch, NULL);
+               if (ret <= 0) {
+                       ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
                }
        }
 
-       packet = packet_create_noack("clicked", "sssddd", handler->pkgname, handler->id, "clicked", timestamp, x, y);
+       timestamp = util_timestamp();
+       DbgPrint("CLICKED: %lf\n", timestamp);
+
+       packet = packet_create_noack("clicked", "sssddd", handler->common->pkgname, handler->common->id, "clicked", timestamp, x, y);
        if (!packet) {
                ErrPrint("Failed to build param\n");
                return LB_STATUS_ERROR_FAULT;
        }
 
-       DbgPrint("CLICKED: %lf\n", timestamp);
        ret = master_rpc_request_only(handler, packet);
 
-       if (!handler->lb.mouse_event && (handler->lb.type == _LB_TYPE_BUFFER || handler->lb.type == _LB_TYPE_SCRIPT)) {
+       if (!handler->common->lb.mouse_event && (handler->common->lb.type == _LB_TYPE_BUFFER || handler->common->lb.type == _LB_TYPE_SCRIPT)) {
                int ret; /* Shadow variable */
-               ret = send_mouse_event(handler, "lb_mouse_down", x * handler->lb.width, y * handler->lb.height);
+               ret = send_mouse_event(handler, "lb_mouse_down", x * handler->common->lb.width, y * handler->common->lb.height);
                if (ret < 0) {
                        ErrPrint("Failed to send Down: %d\n", ret);
                }
 
-               ret = send_mouse_event(handler, "lb_mouse_move", x * handler->lb.width, y * handler->lb.height);
+               ret = send_mouse_event(handler, "lb_mouse_move", x * handler->common->lb.width, y * handler->common->lb.height);
                if (ret < 0) {
                        ErrPrint("Failed to send Move: %d\n", ret);
                }
 
-               ret = send_mouse_event(handler, "lb_mouse_up", x * handler->lb.width, y * handler->lb.height);
+               ret = send_mouse_event(handler, "lb_mouse_up", x * handler->common->lb.width, y * handler->common->lb.height);
                if (ret < 0) {
                        ErrPrint("Failed to send Up: %d\n", ret);
                }
@@ -1410,32 +2092,42 @@ EAPI int livebox_click(struct livebox *handler, double x, double y)
 
 EAPI int livebox_has_pd(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return !!handler->pd.data.fb;
+       return !!handler->common->pd.fb;
 }
 
 EAPI int livebox_pd_is_created(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
+       if (!handler->common->pd.fb || !handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return handler->is_pd_created;
+       return handler->common->is_pd_created;
 }
 
 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
@@ -1448,27 +2140,36 @@ EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, doub
        struct packet *packet;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->pd.fb || !handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->is_pd_created == 1) {
+       /*!
+        * \note
+        * Only one handler can have a PD
+        */
+       if (handler->common->is_pd_created == 1) {
                DbgPrint("PD already created\n");
                return LB_STATUS_SUCCESS;
        }
 
-       if (handler->pd_created_cb) {
+       if (handler->common->request.pd_created) {
                ErrPrint("Previous request is not completed yet\n");
                return LB_STATUS_ERROR_BUSY;
        }
 
-       packet = packet_create("create_pd", "ssdd", handler->pkgname, handler->id, x, y);
+       packet = packet_create("create_pd", "ssdd", handler->common->pkgname, handler->common->id, x, y);
        if (!packet) {
                ErrPrint("Failed to build param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -1481,8 +2182,9 @@ EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, doub
        DbgPrint("PERF_DBOX\n");
        ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
        if (ret == LB_STATUS_SUCCESS) {
-               handler->pd_created_cb = cb;
-               handler->pd_created_cbdata = data;
+               handler->cbs.pd_created.cb = cb;
+               handler->cbs.pd_created.data = data;
+               handler->common->request.pd_created = 1;
        }
 
        return ret;
@@ -1492,22 +2194,27 @@ EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
 {
        struct packet *packet;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
+       if (!handler->common->pd.fb || !handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (!handler->is_pd_created) {
+       if (!handler->common->is_pd_created) {
                ErrPrint("PD is not created\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       packet = packet_create_noack("pd_move", "ssdd", handler->pkgname, handler->id, x, y);
+       packet = packet_create_noack("pd_move", "ssdd", handler->common->pkgname, handler->common->id, x, y);
        if (!packet) {
                ErrPrint("Failed to build param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -1553,22 +2260,33 @@ EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
        struct cb_info *cbinfo;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
+       if (!handler->common->pd.fb || !handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (!handler->is_pd_created && !handler->pd_created_cb) {
+       /*!
+        * \FIXME
+        * Replace the callback check code.
+        * Use the flag instead of callback.
+        * the flag should be in the ADT "common"
+        */
+       if (!handler->common->is_pd_created && !handler->common->request.pd_created) {
                ErrPrint("PD is not created\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       packet = packet_create("destroy_pd", "ss", handler->pkgname, handler->id);
+       packet = packet_create("destroy_pd", "ss", handler->common->pkgname, handler->common->id);
        if (!packet) {
                ErrPrint("Failed to build a param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -1600,35 +2318,40 @@ EAPI int livebox_access_event(struct livebox *handler, enum access_event_type ty
        char *ptr = cmd;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->access_event_cb) {
+       if (handler->common->request.access_event) {
                ErrPrint("Previous access event is not yet done\n");
                return LB_STATUS_ERROR_BUSY;
        }
 
        if (type & ACCESS_EVENT_PD_MASK) {
-               if (!handler->is_pd_created) {
+               if (!handler->common->is_pd_created) {
                        ErrPrint("PD is not created\n");
                        return LB_STATUS_ERROR_INVALID;
                }
                *ptr++ = 'p';
                *ptr++ = 'd';
-               w = handler->pd.width;
-               h = handler->pd.height;
+               w = handler->common->pd.width;
+               h = handler->common->pd.height;
        } else if (type & ACCESS_EVENT_LB_MASK) {
                *ptr++ = 'l';
                *ptr++ = 'b';
-               w = handler->lb.width;
-               h = handler->lb.height;
+               w = handler->common->lb.width;
+               h = handler->common->lb.height;
        } else {
                ErrPrint("Invalid event type\n");
                return LB_STATUS_ERROR_INVALID;
@@ -1675,8 +2398,9 @@ EAPI int livebox_access_event(struct livebox *handler, enum access_event_type ty
 
        ret = send_access_event(handler, cmd, x * w, y * h);
        if (ret == LB_STATUS_SUCCESS) {
-               handler->access_event_cb = cb;
-               handler->access_event_cbdata = data;
+               handler->cbs.access_event.cb = cb;
+               handler->cbs.access_event.data = data;
+               handler->common->request.access_event = 1;
        }
 
        return ret;
@@ -1694,12 +2418,17 @@ EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type ty
        char cmd[32] = { '\0', };
        char *ptr = cmd;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
@@ -1712,18 +2441,18 @@ EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type ty
        if (type & CONTENT_EVENT_PD_MASK) {
                int flag = 1;
 
-               if (!handler->is_pd_created) {
+               if (!handler->common->is_pd_created) {
                        ErrPrint("PD is not created\n");
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (!handler->pd.data.fb) {
+               if (!handler->common->pd.fb) {
                        ErrPrint("Handler is not valid\n");
                        return LB_STATUS_ERROR_INVALID;
                }
 
                if (type & CONTENT_EVENT_MOUSE_MOVE) {
-                       if (fabs(x - handler->pd.x) < MINIMUM_EVENT && fabs(y - handler->pd.y) < MINIMUM_EVENT) {
+                       if (fabs(x - handler->common->pd.x) < MINIMUM_EVENT && fabs(y - handler->common->pd.y) < MINIMUM_EVENT) {
                                return LB_STATUS_ERROR_BUSY;
                        }
                } else if (type & CONTENT_EVENT_MOUSE_SET) {
@@ -1731,27 +2460,27 @@ EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type ty
                }
 
                if (flag) {
-                       w = handler->pd.width;
-                       h = handler->pd.height;
-                       handler->pd.x = x;
-                       handler->pd.y = y;
+                       w = handler->common->pd.width;
+                       h = handler->common->pd.height;
+                       handler->common->pd.x = x;
+                       handler->common->pd.y = y;
                }
                *ptr++ = 'p';
                *ptr++ = 'd';
        } else if (type & CONTENT_EVENT_LB_MASK) {
                int flag = 1;
 
-               if (!handler->lb.mouse_event) {
+               if (!handler->common->lb.mouse_event) {
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (!handler->lb.data.fb) {
+               if (!handler->common->lb.fb) {
                        ErrPrint("Handler is not valid\n");
                        return LB_STATUS_ERROR_INVALID;
                }
 
                if (type & CONTENT_EVENT_MOUSE_MOVE) {
-                       if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT) {
+                       if (fabs(x - handler->common->lb.x) < MINIMUM_EVENT && fabs(y - handler->common->lb.y) < MINIMUM_EVENT) {
                                return LB_STATUS_ERROR_BUSY;
                        }
                } else if (type & CONTENT_EVENT_MOUSE_SET) {
@@ -1759,10 +2488,10 @@ EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type ty
                }
 
                if (flag) {
-                       w = handler->lb.width;
-                       h = handler->lb.height;
-                       handler->lb.x = x;
-                       handler->lb.y = y;
+                       w = handler->common->lb.width;
+                       h = handler->common->lb.height;
+                       handler->common->lb.x = x;
+                       handler->common->lb.y = y;
                }
                *ptr++ = 'l';
                *ptr++ = 'b';
@@ -1810,12 +2539,17 @@ EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type
        char *ptr = cmd;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
@@ -1825,13 +2559,18 @@ EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type
                return LB_STATUS_ERROR_INVALID;
        }
 
+       if (handler->common->request.key_event) {
+               ErrPrint("Previous key event is not completed yet\n");
+               return LB_STATUS_ERROR_BUSY;
+       }
+
        if (type & CONTENT_EVENT_PD_MASK) {
-               if (!handler->is_pd_created) {
+               if (!handler->common->is_pd_created) {
                        ErrPrint("PD is not created\n");
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (!handler->pd.data.fb) {
+               if (!handler->common->pd.fb) {
                        ErrPrint("Handler is not valid\n");
                        return LB_STATUS_ERROR_INVALID;
                }
@@ -1851,11 +2590,11 @@ EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type
                *ptr++ = 'p';
                *ptr++ = 'd';
        } else if (type & CONTENT_EVENT_LB_MASK) {
-               if (!handler->lb.mouse_event) {
+               if (!handler->common->lb.mouse_event) {
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (!handler->lb.data.fb) {
+               if (!handler->common->lb.fb) {
                        ErrPrint("Handler is not valid\n");
                        return LB_STATUS_ERROR_INVALID;
                }
@@ -1911,8 +2650,9 @@ EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type
 
        ret = send_key_event(handler, cmd, keycode);
        if (ret == LB_STATUS_SUCCESS) {
-               handler->key_event_cb = cb;
-               handler->key_event_cbdata = data;
+               handler->cbs.key_event.cb = cb;
+               handler->cbs.key_event.data = data;
+               handler->common->request.key_event = 1;
        }
 
        return ret;
@@ -1920,22 +2660,27 @@ EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type
 
 EAPI const char *livebox_filename(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return NULL;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return NULL;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return NULL;
        }
 
-       if (handler->filename) {
-               return handler->filename;
+       if (handler->common->filename) {
+               return handler->common->filename;
        }
 
        /* Oooops */
-       return util_uri_to_path(handler->id);
+       return util_uri_to_path(handler->common->id);
 }
 
 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
@@ -1943,12 +2688,17 @@ EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
        int _w;
        int _h;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
@@ -1960,12 +2710,12 @@ EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
                h = &_h;
        }
 
-       if (!handler->is_pd_created) {
-               *w = handler->pd.default_width;
-               *h = handler->pd.default_height;
+       if (!handler->common->is_pd_created) {
+               *w = handler->common->pd.default_width;
+               *h = handler->common->pd.default_height;
        } else {
-               *w = handler->pd.width;
-               *h = handler->pd.height;
+               *w = handler->common->pd.width;
+               *h = handler->common->pd.height;
        }
 
        return LB_STATUS_SUCCESS;
@@ -1976,23 +2726,28 @@ EAPI int livebox_size(struct livebox *handler)
        int w;
        int h;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       w = handler->lb.width;
-       h = handler->lb.height;
+       w = handler->common->lb.width;
+       h = handler->common->lb.height;
 
-       switch (handler->lb.type) {
+       switch (handler->common->lb.type) {
        case _LB_TYPE_BUFFER:
        case _LB_TYPE_SCRIPT:
-               if (!fb_is_created(handler->lb.data.fb)) {
+               if (!fb_is_created(handler->common->lb.fb)) {
                        w = 0;
                        h = 0;
                }
@@ -2014,27 +2769,37 @@ EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const c
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (!cluster || !category || handler->state != CREATE || !handler->id) {
+       if (!cluster || !category || handler->state != CREATE) {
+               ErrPrint("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Invalid argument\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->group_changed_cb) {
+       if (handler->common->request.group_changed) {
                ErrPrint("Previous group changing request is not finished yet\n");
                return LB_STATUS_ERROR_BUSY;
        }
 
-       if (!handler->is_user) {
+       if (!handler->common->is_user) {
                ErrPrint("CA Livebox is not able to change the group\n");
                return LB_STATUS_ERROR_PERMISSION;
        }
 
-       if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
+       if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) {
                DbgPrint("No changes\n");
                return LB_STATUS_ERROR_ALREADY;
        }
 
-       packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
+       packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category);
        if (!packet) {
                ErrPrint("Failed to build a param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -2046,8 +2811,9 @@ EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const c
 
        ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
        if (ret == LB_STATUS_SUCCESS) {
-               handler->group_changed_cb = cb;
-               handler->group_cbdata = data; 
+               handler->cbs.group_changed.cb = cb;
+               handler->cbs.group_changed.data = data; 
+               handler->common->request.group_changed = 1;
        }
 
        return ret;
@@ -2060,13 +2826,23 @@ EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (!cluster || !category || handler->state != CREATE || !handler->id) {
+       if (!cluster || !category || handler->state != CREATE) {
+               ErrPrint("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid argument\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Invalid argument\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       *cluster = handler->cluster;
-       *category = handler->category;
+       *cluster = handler->common->cluster;
+       *category = handler->common->category;
        return LB_STATUS_SUCCESS;
 }
 
@@ -2080,13 +2856,23 @@ EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *siz
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (!cnt || handler->state != CREATE || !handler->id) {
+       if (!cnt || handler->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
        for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
-               if (handler->lb.size_list & (0x01 << i)) {
+               if (handler->common->lb.size_list & (0x01 << i)) {
                        if (j == *cnt) {
                                break;
                        }
@@ -2111,22 +2897,32 @@ EAPI const char *livebox_pkgname(struct livebox *handler)
                return NULL;
        }
 
-       return handler->pkgname;
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return NULL;
+       }
+
+       return handler->common->pkgname;
 }
 
 EAPI double livebox_priority(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
-               return 0.0f;
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return -1.0f;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return -1.0f;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid (%p)\n", handler);
                return -1.0f;
        }
 
-       return handler->lb.priority;
+       return handler->common->lb.priority;
 }
 
 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
@@ -2183,24 +2979,29 @@ EAPI int livebox_delete_category(const char *cluster, const char *category, ret_
 
 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_TYPE_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_TYPE_INVALID;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_TYPE_INVALID;
        }
 
-       switch (handler->lb.type) {
+       switch (handler->common->lb.type) {
        case _LB_TYPE_FILE:
                return LB_TYPE_IMAGE;
        case _LB_TYPE_BUFFER:
        case _LB_TYPE_SCRIPT:
                {
                        const char *id;
-                       id = fb_id(handler->lb.data.fb);
+                       id = fb_id(handler->common->lb.fb);
                        if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
                                return LB_TYPE_PIXMAP;
                        }
@@ -2217,24 +3018,29 @@ EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
 
 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return PD_TYPE_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return PD_TYPE_INVALID;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return PD_TYPE_INVALID;
        }
 
-       switch (handler->pd.type) {
+       switch (handler->common->pd.type) {
        case _PD_TYPE_TEXT:
                return PD_TYPE_TEXT;
        case _PD_TYPE_BUFFER:
        case _PD_TYPE_SCRIPT:
                {
                        const char *id;
-                       id = fb_id(handler->pd.data.fb);
+                       id = fb_id(handler->common->pd.fb);
                        if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
                                return PD_TYPE_PIXMAP;
                        }
@@ -2259,7 +3065,7 @@ EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_scr
                return LB_STATUS_ERROR_INVALID;
        }
 
-       memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
+       memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops));
        return LB_STATUS_SUCCESS;
 }
 
@@ -2275,77 +3081,60 @@ EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script
                return LB_STATUS_ERROR_INVALID;
        }
 
-       memcpy(&handler->lb.data.ops, ops, sizeof(*ops));
+       memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops));
        return LB_STATUS_SUCCESS;
 }
 
 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
 {
-       struct packet *packet;
-       struct cb_info *cbinfo;
-       const char *id;
-       int ret;
-
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
-               ErrPrint("Invalid handle\n");
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
-               ErrPrint("Handler is not valid type\n");
+       if (!handler->common->id) {
+               ErrPrint("Invalid handle\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       id = fb_id(handler->lb.data.fb);
-       if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
+       if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
+               ErrPrint("Handler is not valid type\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
-       if (!packet) {
-               ErrPrint("Failed to build a param\n");
-               return LB_STATUS_ERROR_FAULT;
-       }
-
-       cbinfo = create_cb_info(cb, data);
-       if (!cbinfo) {
-               packet_destroy(packet);
-               return LB_STATUS_ERROR_FAULT;
-       }
-
-       ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo);
-       if (ret < 0) {
-               destroy_cb_info(cbinfo);
-       }
-
-       return ret;
+       return lb_acquire_lb_pixmap(handler, cb, data);
 }
 
 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
 {
        struct packet *packet;
 
-       if (!handler || pixmap == 0) {
-               ErrPrint("Handler is NIL [%d]\n", pixmap);
+       if (!handler || pixmap == 0 || handler->state != CREATE) {
+               ErrPrint("Handler is invalid [%d]\n", pixmap);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Invalid handle\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
+       if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
                ErrPrint("Handler is not valid type\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
+       packet = packet_create_noack("lb_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
        if (!packet) {
                ErrPrint("Failed to build a param\n");
                return LB_STATUS_ERROR_INVALID;
@@ -2356,49 +3145,27 @@ EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
 
 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
 {
-       struct packet *packet;
-       struct cb_info *cbinfo;
-       const char *id;
-       int ret;
-
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
-               ErrPrint("Invalid handle\n");
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
-               ErrPrint("Handler is not valid type\n");
+       if (!handler->common->id) {
+               ErrPrint("Invalid handle\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       id = fb_id(handler->pd.data.fb);
-       if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
+       if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
+               ErrPrint("Handler is not valid type\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
-       if (!packet) {
-               ErrPrint("Failed to build a param\n");
-               return LB_STATUS_ERROR_FAULT;
-       }
-
-       cbinfo = create_cb_info(cb, data);
-       if (!cbinfo) {
-               packet_destroy(packet);
-               return LB_STATUS_ERROR_FAULT;
-       }
-
-       ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo);
-       if (ret < 0) {
-               destroy_cb_info(cbinfo);
-       }
-
-       return ret;
+       return lb_acquire_pd_pixmap(handler, cb, data);
 }
 
 EAPI int livebox_pd_pixmap(const struct livebox *handler)
@@ -2406,23 +3173,28 @@ EAPI int livebox_pd_pixmap(const struct livebox *handler)
        const char *id;
        int pixmap = 0;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return 0;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return 0;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Invalid handler\n");
                return 0;
        }
 
-       if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
+       if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
                ErrPrint("Invalid handler\n");
                return 0;
        }
 
-       id = fb_id(handler->pd.data.fb);
-       if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
+       id = fb_id(handler->common->pd.fb);
+       if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
                ErrPrint("PIXMAP Id is not valid\n");
                return 0;
        }
@@ -2435,23 +3207,28 @@ EAPI int livebox_lb_pixmap(const struct livebox *handler)
        const char *id;
        int pixmap = 0;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return 0;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return 0;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
                ErrPrint("Invalid handler\n");
                return 0;
        }
 
-       if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
+       if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
                ErrPrint("Invalid handler\n");
                return 0;
        }
 
-       id = fb_id(handler->lb.data.fb);
-       if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
+       id = fb_id(handler->common->lb.fb);
+       if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
                ErrPrint("PIXMAP Id is not valid\n");
                return 0;
        }
@@ -2463,22 +3240,27 @@ EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
 {
        struct packet *packet;
 
-       if (!handler || pixmap == 0) {
-               ErrPrint("Handler is NIL [%d]\n", pixmap);
+       if (!handler || pixmap == 0 || handler->state != CREATE) {
+               ErrPrint("Handler is invalid [%d]\n", pixmap);
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Invalid handle\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
+       if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
                ErrPrint("Handler is not valid type\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
+       packet = packet_create_noack("pd_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
        if (!packet) {
                ErrPrint("Failed to build a param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -2489,22 +3271,27 @@ EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
 
 EAPI void *livebox_acquire_fb(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return NULL;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return NULL;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Invalid handle\n");
                return NULL;
        }
 
-       if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
+       if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
                ErrPrint("Handler is not valid type\n");
                return NULL;
        }
 
-       return fb_acquire_buffer(handler->lb.data.fb);
+       return fb_acquire_buffer(handler->common->lb.fb);
 }
 
 EAPI int livebox_release_fb(void *buffer)
@@ -2519,22 +3306,27 @@ EAPI int livebox_fb_refcnt(void *buffer)
 
 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return NULL;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return NULL;
+       }
+
+       if (!handler->common->id) {
                ErrPrint("Invalid handler\n");
                return NULL;
        }
 
-       if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
+       if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
                ErrPrint("Handler is not valid type\n");
                return NULL;
        }
 
-       return fb_acquire_buffer(handler->pd.data.fb);
+       return fb_acquire_buffer(handler->common->pd.fb);
 }
 
 EAPI int livebox_release_pdfb(void *buffer)
@@ -2549,47 +3341,62 @@ EAPI int livebox_pdfb_refcnt(void *buffer)
 
 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
-               ErrPrint("Handler is not valid\n");
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Invalid handler\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return fb_size(handler->pd.data.fb);
+       return fb_size(handler->common->pd.fb);
 }
 
 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
-               ErrPrint("Handler is not valid\n");
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Invalid handler\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return fb_size(handler->lb.data.fb);
+       return fb_size(handler->common->lb.fb);
 }
 
 EAPI int livebox_is_user(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE) {
+       if (!handler->common || handler->common->state != CREATE) {
                ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return handler->is_user;
+       if (!handler->common->id) {
+               ErrPrint("Invalid handler\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return handler->common->is_user;
 }
 
 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
@@ -2597,27 +3404,32 @@ EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void
        struct packet *packet;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
-               ErrPrint("Handler is not valid\n");
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Invalid handler\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->pinup_cb) {
+       if (handler->common->request.pinup) {
                ErrPrint("Previous pinup request is not finished\n");
                return LB_STATUS_ERROR_BUSY;
        }
 
-       if (handler->is_pinned_up == flag) {
+       if (handler->common->is_pinned_up == flag) {
                DbgPrint("No changes\n");
                return LB_STATUS_ERROR_ALREADY;
        }
 
-       packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
+       packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
        if (!packet) {
                ErrPrint("Failed to build a param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -2629,8 +3441,9 @@ EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void
 
        ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
        if (ret == LB_STATUS_SUCCESS) {
-               handler->pinup_cb = cb;
-               handler->pinup_cbdata = data;
+               handler->cbs.pinup.cb = cb;
+               handler->cbs.pinup.data = data;
+               handler->common->request.pinup = 1;
        }
 
        return ret;
@@ -2638,30 +3451,42 @@ EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void
 
 EAPI int livebox_is_pinned_up(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
+               ErrPrint("Invalid handler\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return handler->is_pinned_up;
+       return handler->common->is_pinned_up;
 }
 
 EAPI int livebox_has_pinup(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Invalid handler\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       return handler->lb.pinup_supported;
+       return handler->common->lb.pinup_supported;
 }
 
 EAPI int livebox_set_data(struct livebox *handler, void *data)
@@ -2672,6 +3497,7 @@ EAPI int livebox_set_data(struct livebox *handler, void *data)
        }
 
        if (handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
@@ -2687,6 +3513,7 @@ EAPI void *livebox_get_data(struct livebox *handler)
        }
 
        if (handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return NULL;
        }
 
@@ -2708,30 +3535,32 @@ EAPI int livebox_is_exists(const char *pkgname)
 
 EAPI const char *livebox_content(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return NULL;
        }
 
-       if (handler->state != CREATE) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
                return NULL;
        }
 
-       return handler->content;
+       return handler->common->content;
 }
 
 EAPI const char *livebox_category_title(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return NULL;
        }
 
-       if (handler->state != CREATE) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
                return NULL;
        }
 
-       return handler->title;
+       return handler->common->title;
 }
 
 EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data)
@@ -2740,12 +3569,17 @@ EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission,
        struct cb_info *cbinfo;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || (handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || !handler->id) {
+       if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
                ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
@@ -2759,7 +3593,7 @@ EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission,
        }
 
        packet = packet_create("text_signal", "ssssdddd",
-                               handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
+                               handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
        if (!packet) {
                ErrPrint("Failed to build a param\n");
                return LB_STATUS_ERROR_FAULT;
@@ -2822,16 +3656,22 @@ EAPI int livebox_refresh(struct livebox *handler, int force)
 {
        struct packet *packet;
 
-       if (!handler) {
-               ErrPrint("Hnalder is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
+               ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       packet = packet_create_noack("update", "ssi", handler->pkgname, handler->id, force);
+       packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
        if (!packet) {
                ErrPrint("Failed to create a packet\n");
                return LB_STATUS_ERROR_FAULT;
@@ -2860,19 +3700,25 @@ EAPI int livebox_refresh_group(const char *cluster, const char *category, int fo
 
 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
 {
-       struct packet *packet;
+       int old_state;
        int ret;
 
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Handler is not valid\n");
                return LB_STATUS_ERROR_INVALID;
        }
 
-       if (!handler->is_user) {
+       if (!handler->common->is_user) {
                /* System cluster livebox cannot be changed its visible states */
                if (state == LB_HIDE_WITH_PAUSE) {
                        ErrPrint("CA Livebox is not able to change the visibility\n");
@@ -2880,19 +3726,19 @@ EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_st
                }
        }
 
+       DbgPrint("[%s] Change visiblity to 0x%x\n", handler->common->pkgname, state);
+
        if (handler->visible == state) {
+               DbgPrint("%s has no changes\n", handler->common->pkgname);
                return LB_STATUS_ERROR_ALREADY;
        }
 
-       packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
-       if (!packet) {
-               ErrPrint("Failed to create a packet\n");
-               return LB_STATUS_ERROR_FAULT;
-       }
+       old_state = handler->visible;
+       handler->visible = state;
 
-       ret = master_rpc_request_only(handler, packet);
-       if (ret == 0) {
-               handler->visible = state;
+       ret = lb_set_visibility(handler, state);
+       if (ret < 0) {
+               handler->visible = old_state;
        }
 
        return ret;
@@ -2900,19 +3746,25 @@ EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_st
 
 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
 {
-       if (!handler) {
-               ErrPrint("Handler is NIL\n");
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is invalid\n");
+               return LB_VISIBLE_ERROR;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
                return LB_VISIBLE_ERROR;
        }
 
-       if (handler->state != CREATE || !handler->id) {
+       if (!handler->common->id) {
+               ErrPrint("Handler is not valid\n");
                return LB_VISIBLE_ERROR;
        }
 
        return handler->visible;
 }
 
-int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
+int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
 {
        void *pc = NULL;
        void *ps = NULL;
@@ -2934,41 +3786,41 @@ int lb_set_group(struct livebox *handler, const char *cluster, const char *categ
                }
        }
 
-       if (handler->cluster) {
-               free(handler->cluster);
+       if (common->cluster) {
+               free(common->cluster);
        }
 
-       if (handler->category) {
-               free(handler->category);
+       if (common->category) {
+               free(common->category);
        }
 
-       handler->cluster = pc;
-       handler->category = ps;
+       common->cluster = pc;
+       common->category = ps;
 
        return LB_STATUS_SUCCESS;
 }
 
-void lb_set_size(struct livebox *handler, int w, int h)
+void lb_set_size(struct livebox_common *common, int w, int h)
 {
-       handler->lb.width = w;
-       handler->lb.height = h;
+       common->lb.width = w;
+       common->lb.height = h;
 }
 
-void lb_set_update_mode(struct livebox *handle, int active_mode)
+void lb_set_update_mode(struct livebox_common *common, int active_mode)
 {
-       handle->is_active_update = active_mode;
+       common->is_active_update = active_mode;
 }
 
-void lb_set_pdsize(struct livebox *handler, int w, int h)
+void lb_set_pdsize(struct livebox_common *common, int w, int h)
 {
-       handler->pd.width = w;
-       handler->pd.height = h;
+       common->pd.width = w;
+       common->pd.height = h;
 }
 
-void lb_set_default_pdsize(struct livebox *handler, int w, int h)
+void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
 {
-       handler->pd.default_width = w;
-       handler->pd.default_height = h;
+       common->pd.default_width = w;
+       common->pd.default_height = h;
 }
 
 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
@@ -2977,11 +3829,20 @@ void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname,
        struct dlist *n;
        struct fault_info *info;
 
+       s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
+
        dlist_foreach_safe(s_info.fault_list, l, n, info) {
-               if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
+               if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
+                       info->is_deleted = 1;
+               }
+
+               if (info->is_deleted) {
                        s_info.fault_list = dlist_remove(s_info.fault_list, l);
+                       free(info);
                }
        }
+
+       s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
 }
 
 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
@@ -2990,46 +3851,66 @@ void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type ev
        struct dlist *n;
        struct event_info *info;
 
+       if (event == LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
+               if (handler->visible != LB_SHOW) {
+                       DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
+                       handler->paused_updating++;
+                       return;
+               } else {
+                       handler->paused_updating = 0;
+               }
+       }
+
+       s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
+
        dlist_foreach_safe(s_info.event_list, l, n, info) {
-               if (info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
+               if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
+                       DbgPrint("Event handler returns EXIT_FAILURE\n");
+                       info->is_deleted = 1;
+               }
+
+               if (info->is_deleted) {
                        s_info.event_list = dlist_remove(s_info.event_list, l);
+                       free(info);
                }
        }
+
+       s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
 }
 
-struct livebox *lb_find_livebox(const char *pkgname, const char *id)
+struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
 {
        struct dlist *l;
-       struct livebox *handler;
+       struct livebox_common *common;
 
-       dlist_foreach(s_info.livebox_list, l, handler) {
-               if (!handler->id) {
+       dlist_foreach(s_info.livebox_common_list, l, common) {
+               if (!common->id) {
                        continue;
                }
 
-               if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id)) {
-                       return handler;
+               if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
+                       return common;
                }
        }
 
        return NULL;
 }
 
-struct livebox *lb_find_livebox_by_timestamp(double timestamp)
+struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
 {
        struct dlist *l;
-       struct livebox *handler;
+       struct livebox_common *common;
 
-       dlist_foreach(s_info.livebox_list, l, handler) {
-               if (handler->timestamp == timestamp) {
-                       return handler;
+       dlist_foreach(s_info.livebox_common_list, l, common) {
+               if (common->timestamp == timestamp) {
+                       return common;
                }
        }
 
        return NULL;
 }
 
-struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
+struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
 {
        struct livebox *handler;
 
@@ -3039,35 +3920,21 @@ struct livebox *lb_new_livebox(const char *pkgname, const char *id, double times
                return NULL;
        }
 
-       handler->pkgname = strdup(pkgname);
-       if (!handler->pkgname) {
-               ErrPrint("%s\n", strerror(errno));
-               free(handler);
-               return NULL;
-       }
-
-       handler->id = strdup(id);
-       if (!handler->id) {
-               ErrPrint("%s\n", strerror(errno));
-               free(handler->pkgname);
+       handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
+       if (!handler->common) {
+               ErrPrint("Heap: %s\n", strerror(errno));
                free(handler);
                return NULL;
        }
 
-       handler->timestamp = timestamp;
-       handler->lb.type = _LB_TYPE_FILE;
-       handler->pd.type = _PD_TYPE_SCRIPT;
-       handler->state = CREATE;
+       lb_common_ref(handler->common, handler);
+       lb_set_id(handler->common, id);
+       handler->common->timestamp = timestamp;
+       handler->common->state = CREATE;
        handler->visible = LB_SHOW;
-       handler->delete_type = LB_DELETE_PERMANENTLY;
-       handler->pd.lock = NULL;
-       handler->pd.lock_fd = -1;
-       handler->lb.lock = NULL;
-       handler->lb.lock_fd = -1;
-
        s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
-       lb_ref(handler);
-       return handler;
+
+       return lb_ref(handler);
 }
 
 int lb_delete_all(void)
@@ -3078,101 +3945,109 @@ int lb_delete_all(void)
 
        dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
                lb_invoke_event_handler(handler, LB_EVENT_DELETED);
-               lb_unref(handler);
+               lb_unref(handler, 1);
        }
 
        return LB_STATUS_SUCCESS;
 }
 
-int lb_set_content(struct livebox *handler, const char *content)
+int lb_set_content(struct livebox_common *common, const char *content)
 {
-       if (handler->content) {
-               free(handler->content);
-               handler->content = NULL;
-       }
+       char *pc = NULL;
 
        if (content) {
-               handler->content = strdup(content);
-               if (!handler->content) {
-                       ErrPrint("Heap: %s (content: %s)\n", strerror(errno), content);
+               pc = strdup(content);
+               if (!pc) {
+                       ErrPrint("heap: %s [%s]\n", strerror(errno), content);
                        return LB_STATUS_ERROR_MEMORY;
                }
        }
 
+       free(common->content);
+       common->content = pc;
        return LB_STATUS_SUCCESS;
 }
 
-int lb_set_title(struct livebox *handler, const char *title)
+int lb_set_title(struct livebox_common *common, const char *title)
 {
-       if (handler->title) {
-               free(handler->title);
-               handler->title = NULL;
-       }
+       char *pt = NULL;
 
        if (title) {
-               handler->title = strdup(title);
-               if (!handler->title) {
-                       ErrPrint("Heap: %s (title: %s)\n", strerror(errno), title);
+               pt = strdup(title);
+               if (!pt) {
+                       ErrPrint("heap: %s [%s]\n", strerror(errno), title);
                        return LB_STATUS_ERROR_MEMORY;
                }
        }
 
+       free(common->title);
+       common->title = pt;
        return LB_STATUS_SUCCESS;
 }
 
-void lb_set_size_list(struct livebox *handler, int size_list)
+void lb_set_size_list(struct livebox_common *common, int size_list)
 {
-       handler->lb.size_list = size_list;
+       common->lb.size_list = size_list;
 }
 
-void lb_set_auto_launch(struct livebox *handler, const char *auto_launch)
+void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
 {
-       if (!strlen(auto_launch)) {
+       char *pa = NULL;
+
+       if (!auto_launch || !strlen(auto_launch)) {
                return;
        }
 
-       handler->lb.auto_launch = strdup(auto_launch);
-       if (!handler->lb.auto_launch) {
-               ErrPrint("Heap: %s\n", strerror(errno));
+       pa = strdup(auto_launch);
+       if (!pa) {
+               ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
+               return;
        }
+
+       free(common->lb.auto_launch);
+       common->lb.auto_launch = pa;
 }
 
-void lb_set_priority(struct livebox *handler, double priority)
+void lb_set_priority(struct livebox_common *common, double priority)
 {
-       handler->lb.priority = priority;
+       common->lb.priority = priority;
 }
 
-void lb_set_id(struct livebox *handler, const char *id)
+void lb_set_id(struct livebox_common *common, const char *id)
 {
-       if (handler->id) {
-               free(handler->id);
-       }
+       char *pi = NULL;
 
-       handler->id = strdup(id);
-       if (!handler->id) {
-               ErrPrint("Error: %s\n", strerror(errno));
+       if (id) {
+               pi = strdup(id);
+               if (!pi) {
+                       ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
+                       return;
+               }
        }
+
+       free(common->id);
+       common->id = pi;
 }
 
-void lb_set_filename(struct livebox *handler, const char *filename)
+void lb_set_filename(struct livebox_common *common, const char *filename)
 {
-       if (handler->filename) {
-               if (handler->lb.type == _LB_TYPE_FILE || handler->lb.type == _LB_TYPE_TEXT) {
-                       if (handler->filename[0] && unlink(handler->filename) < 0) {
-                               ErrPrint("unlink: %s (%s)\n", strerror(errno), handler->filename);
+       if (common->filename) {
+               if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
+                       if (common->filename[0] && unlink(common->filename) < 0) {
+                               ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
                        }
                }
 
-               free(handler->filename);
+               free(common->filename);
        }
 
-       handler->filename = strdup(filename);
-       if (!handler->filename) {
+       common->filename = strdup(filename);
+       if (!common->filename) {
                ErrPrint("Heap: %s\n", strerror(errno));
        }
 }
 
-void lb_set_alt_info(struct livebox *handler, const char *icon, const char *name)
+void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
 {
        char *_icon = NULL;
        char *_name = NULL;
@@ -3191,33 +4066,27 @@ void lb_set_alt_info(struct livebox *handler, const char *icon, const char *name
                }
        }
 
-       if (handler->icon) {
-               free(handler->icon);
-       }
-
-       handler->icon = _icon;
+       free(common->alt.icon);
+       common->alt.icon = _icon;
 
-       if (handler->name) {
-               free(handler->name);
-       }
-
-       handler->name = _name;
+       free(common->alt.name);
+       common->alt.name = _name;
 }
 
-int lb_set_lb_fb(struct livebox *handler, const char *filename)
+int lb_set_lb_fb(struct livebox_common *common, const char *filename)
 {
        struct fb_info *fb;
 
-       if (!handler) {
+       if (!common) {
                return LB_STATUS_ERROR_INVALID;
        }
 
-       fb = handler->lb.data.fb;
+       fb = common->lb.fb;
        if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
                return LB_STATUS_SUCCESS;
        }
 
-       handler->lb.data.fb = NULL;
+       common->lb.fb = NULL;
 
        if (!filename || filename[0] == '\0') {
                if (fb) {
@@ -3226,8 +4095,8 @@ int lb_set_lb_fb(struct livebox *handler, const char *filename)
                return LB_STATUS_SUCCESS;
        }
 
-       handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
-       if (!handler->lb.data.fb) {
+       common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
+       if (!common->lb.fb) {
                ErrPrint("Faield to create a FB\n");
                if (fb) {
                        fb_destroy(fb);
@@ -3242,20 +4111,20 @@ int lb_set_lb_fb(struct livebox *handler, const char *filename)
        return LB_STATUS_SUCCESS;
 }
 
-int lb_set_pd_fb(struct livebox *handler, const char *filename)
+int lb_set_pd_fb(struct livebox_common *common, const char *filename)
 {
        struct fb_info *fb;
 
-       if (!handler) {
+       if (!common || common->state != CREATE) {
                return LB_STATUS_ERROR_INVALID;
        }
 
-       fb = handler->pd.data.fb;
+       fb = common->pd.fb;
        if (fb && !strcmp(fb_id(fb), filename)) {
                /* BUFFER is not changed, just update the content */
                return LB_STATUS_ERROR_EXIST;
        }
-       handler->pd.data.fb = NULL;
+       common->pd.fb = NULL;
 
        if (!filename || filename[0] == '\0') {
                if (fb) {
@@ -3264,8 +4133,8 @@ int lb_set_pd_fb(struct livebox *handler, const char *filename)
                return LB_STATUS_SUCCESS;
        }
 
-       handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
-       if (!handler->pd.data.fb) {
+       common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
+       if (!common->pd.fb) {
                ErrPrint("Failed to create a FB\n");
                if (fb) {
                        fb_destroy(fb);
@@ -3279,49 +4148,49 @@ int lb_set_pd_fb(struct livebox *handler, const char *filename)
        return LB_STATUS_SUCCESS;
 }
 
-struct fb_info *lb_get_lb_fb(struct livebox *handler)
+struct fb_info *lb_get_lb_fb(struct livebox_common *common)
 {
-       return handler->lb.data.fb;
+       return common->lb.fb;
 }
 
-struct fb_info *lb_get_pd_fb(struct livebox *handler)
+struct fb_info *lb_get_pd_fb(struct livebox_common *common)
 {
-       return handler->pd.data.fb;
+       return common->pd.fb;
 }
 
-void lb_set_user(struct livebox *handler, int user)
+void lb_set_user(struct livebox_common *common, int user)
 {
-       handler->is_user = user;
+       common->is_user = user;
 }
 
-void lb_set_pinup(struct livebox *handler, int pinup_supported)
+void lb_set_pinup(struct livebox_common *common, int pinup_supported)
 {
-       handler->lb.pinup_supported = pinup_supported;
+       common->lb.pinup_supported = pinup_supported;
 }
 
-void lb_set_text_lb(struct livebox *handler)
+void lb_set_text_lb(struct livebox_common *common)
 {
-       handler->lb.type = _LB_TYPE_TEXT;
+       common->lb.type = _LB_TYPE_TEXT;
 }
 
-void lb_set_text_pd(struct livebox *handler)
+void lb_set_text_pd(struct livebox_common *common)
 {
-       handler->pd.type = _PD_TYPE_TEXT;
+       common->pd.type = _PD_TYPE_TEXT;
 }
 
-int lb_text_lb(struct livebox *handler)
+int lb_text_lb(struct livebox_common *common)
 {
-       return handler->lb.type == _LB_TYPE_TEXT;
+       return common->lb.type == _LB_TYPE_TEXT;
 }
 
-int lb_text_pd(struct livebox *handler)
+int lb_text_pd(struct livebox_common *common)
 {
-       return handler->pd.type == _PD_TYPE_TEXT;
+       return common->pd.type == _PD_TYPE_TEXT;
 }
 
-void lb_set_period(struct livebox *handler, double period)
+void lb_set_period(struct livebox_common *common, double period)
 {
-       handler->lb.period = period;
+       common->lb.period = period;
 }
 
 struct livebox *lb_ref(struct livebox *handler)
@@ -3334,7 +4203,7 @@ struct livebox *lb_ref(struct livebox *handler)
        return handler;
 }
 
-struct livebox *lb_unref(struct livebox *handler)
+struct livebox *lb_unref(struct livebox *handler, int destroy_common)
 {
        if (!handler) {
                return NULL;
@@ -3345,98 +4214,84 @@ struct livebox *lb_unref(struct livebox *handler)
                return handler;
        }
 
-       if (handler->created_cb) {
-               handler->created_cb(handler, LB_STATUS_ERROR_FAULT, handler->created_cbdata);
-               handler->created_cb = NULL;
-               handler->created_cbdata = NULL;
+       if (handler->cbs.created.cb) {
+               handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
+               handler->cbs.created.cb = NULL;
+               handler->cbs.created.data = NULL;
        }
 
-       if (handler->deleted_cb) {
-               handler->deleted_cb(handler, LB_STATUS_ERROR_FAULT, handler->deleted_cbdata);
-               handler->deleted_cb = NULL;
-               handler->deleted_cbdata = NULL;
+       if (handler->cbs.deleted.cb) {
+               handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
+               handler->cbs.deleted.cb = NULL;
+               handler->cbs.deleted.data = NULL;
        }
 
-       if (handler->pinup_cb) {
-               handler->pinup_cb(handler, LB_STATUS_ERROR_FAULT, handler->pinup_cbdata);
-               handler->pinup_cb = NULL;
-               handler->pinup_cbdata = NULL;
+       if (handler->cbs.pinup.cb) {
+               handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
+               handler->cbs.pinup.cb = NULL;
+               handler->cbs.pinup.data = NULL;
        }
 
-       if (handler->group_changed_cb) {
-               handler->group_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->group_cbdata);
-               handler->group_changed_cb = NULL;
-               handler->group_cbdata = NULL;
+       if (handler->cbs.group_changed.cb) {
+               handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
+               handler->cbs.group_changed.cb = NULL;
+               handler->cbs.group_changed.data = NULL;
        }
 
-       if (handler->period_changed_cb) {
-               handler->period_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->period_cbdata);
-               handler->period_changed_cb = NULL;
-               handler->period_cbdata = NULL;
+       if (handler->cbs.period_changed.cb) {
+               handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
+               handler->cbs.period_changed.cb = NULL;
+               handler->cbs.period_changed.data = NULL;
        }
 
-       if (handler->size_changed_cb) {
-               handler->size_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->size_cbdata);
-               handler->size_changed_cb = NULL;
-               handler->size_cbdata = NULL;
+       if (handler->cbs.size_changed.cb) {
+               handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
+               handler->cbs.size_changed.cb = NULL;
+               handler->cbs.size_changed.data = NULL;
        }
 
-       if (handler->pd_created_cb) {
-               handler->pd_created_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_created_cbdata);
-               handler->pd_created_cb = NULL;
-               handler->pd_created_cbdata = NULL;
+       if (handler->cbs.pd_created.cb) {
+               handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
+               handler->cbs.pd_created.cb = NULL;
+               handler->cbs.pd_created.data = NULL;
        }
 
-       if (handler->pd_destroyed_cb) {
-               handler->pd_destroyed_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_destroyed_cbdata);
-               handler->pd_destroyed_cb = NULL;
-               handler->pd_destroyed_cbdata = NULL;
+       if (handler->cbs.pd_destroyed.cb) {
+               handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
+               handler->cbs.pd_destroyed.cb = NULL;
+               handler->cbs.pd_destroyed.data = NULL;
        }
 
-       if (handler->update_mode_cb) {
-               handler->update_mode_cb(handler, LB_STATUS_ERROR_FAULT, handler->update_mode_cbdata);
-               handler->update_mode_cb = NULL;
-               handler->update_mode_cbdata = NULL;
+       if (handler->cbs.update_mode.cb) {
+               handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
+               handler->cbs.update_mode.cb = NULL;
+               handler->cbs.update_mode.data = NULL;
        }
 
-       if (handler->access_event_cb) {
-               handler->access_event_cb(handler, LB_ACCESS_STATUS_ERROR, handler->access_event_cbdata);
-               handler->access_event_cb = NULL;
-               handler->access_event_cbdata = NULL;
+       if (handler->cbs.access_event.cb) {
+               handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
+               handler->cbs.access_event.cb = NULL;
+               handler->cbs.access_event.data = NULL;
        }
 
-       if (handler->key_event_cb) {
-               handler->key_event_cb(handler, LB_KEY_STATUS_ERROR, handler->key_event_cbdata);
-               handler->key_event_cb = NULL;
-               handler->key_event_cbdata = NULL;
+       if (handler->cbs.key_event.cb) {
+               handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
+               handler->cbs.key_event.cb = NULL;
+               handler->cbs.key_event.data = NULL;
        }
 
-       if (handler->filename) {
-               (void)util_unlink(handler->filename);
+       if (handler->common->filename) {
+               (void)util_unlink(handler->common->filename);
        }
 
        dlist_remove_data(s_info.livebox_list, handler);
 
        handler->state = DESTROYED;
-       free(handler->cluster);
-       free(handler->category);
-       free(handler->id);
-       free(handler->pkgname);
-       free(handler->filename);
-       free(handler->lb.auto_launch);
-       free(handler->icon);
-       free(handler->name);
-
-       if (handler->lb.data.fb) {
-               fb_destroy(handler->lb.data.fb);
-               handler->lb.data.fb = NULL;
-       }
-
-       if (handler->pd.data.fb) {
-               fb_destroy(handler->pd.data.fb);
-               handler->pd.data.fb = NULL;
+       if (lb_common_unref(handler->common, handler) == 0) {
+               if (destroy_common) {
+                       lb_destroy_common_handle(handler->common);
+               }
        }
-
        free(handler);
        return NULL;
 }
@@ -3447,17 +4302,19 @@ int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
        struct cb_info *cbinfo;
        int ret;
 
-       if (!cb && !!data) {
-               ErrPrint("Invalid argument\n");
-               return LB_STATUS_ERROR_INVALID;
-       }
-
-       if (handler->deleted_cb) {
+       if (handler->common->request.deleted) {
                ErrPrint("Already in-progress\n");
+               if (cb) {
+                       cb(handler, LB_STATUS_SUCCESS, data);
+               }
                return LB_STATUS_ERROR_BUSY;
        }
 
-       packet = packet_create("delete", "ssi", handler->pkgname, handler->id, type);
+       if (!cb) {
+               cb = default_delete_cb;
+       }
+
+       packet = packet_create("delete", "ssi", handler->common->pkgname, handler->common->id, type);
        if (!packet) {
                ErrPrint("Failed to build a param\n");
                if (cb) {
@@ -3467,19 +4324,29 @@ int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
                return LB_STATUS_ERROR_FAULT;
        }
 
-       if (!cb) {
-               cb = default_delete_cb;
-       }
-
        cbinfo = create_cb_info(cb, data);
        if (!cbinfo) {
                packet_destroy(packet);
+               ErrPrint("Failed to create cbinfo\n");
+               if (cb) {
+                       cb(handler, LB_STATUS_ERROR_FAULT, data);
+               }
+
                return LB_STATUS_ERROR_FAULT;
        }
 
        ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
        if (ret < 0) {
+               /*!
+                * Packet is destroyed by master_rpc_async_request.
+                */
                destroy_cb_info(cbinfo);
+
+               if (cb) {
+                       cb(handler, LB_STATUS_ERROR_FAULT, data);
+               }
+       } else {
+               handler->common->request.deleted = 1;
        }
 
        return ret;
@@ -3511,63 +4378,88 @@ EAPI int livebox_client_resumed(void)
        return master_rpc_request_only(NULL, packet);
 }
 
-EAPI void livebox_set_manual_sync(int flag)
+EAPI int livebox_sync_lb_fb(struct livebox *handler)
 {
-       conf_set_manual_sync(flag);
-}
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
 
-EAPI int livebox_manual_sync(void)
-{
-       return conf_manual_sync();
-}
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
 
-EAPI void livebox_set_frame_drop_for_resizing(int flag)
-{
-       conf_set_frame_drop_for_resizing(flag);
-}
+       if (!handler->common->id) {
+               return LB_STATUS_ERROR_INVALID;
+       }
 
-EAPI int livebox_frame_drop_for_resizing(void)
-{
-       return conf_frame_drop_for_resizing();
+       return lb_sync_lb_fb(handler->common);
 }
 
-EAPI int livebox_sync_lb_fb(struct livebox *handler)
+int lb_sync_lb_fb(struct livebox_common *common)
 {
        int ret;
 
-       if (fb_type(lb_get_lb_fb(handler)) == BUFFER_TYPE_FILE && handler->lb.lock_fd >= 0) {
-               (void)do_fb_lock(handler->lb.lock_fd);
-               ret = fb_sync(lb_get_lb_fb(handler));
-               (void)do_fb_unlock(handler->lb.lock_fd);
+       if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
+               (void)do_fb_lock(common->lb.lock_fd);
+               ret = fb_sync(lb_get_lb_fb(common));
+               (void)do_fb_unlock(common->lb.lock_fd);
        } else {
-               ret = fb_sync(lb_get_lb_fb(handler));
+               ret = fb_sync(lb_get_lb_fb(common));
        }
 
        return ret;
 }
 
-EAPI int livebox_sync_pd_fb(struct livebox *handler)
+int lb_sync_pd_fb(struct livebox_common *common)
 {
        int ret;
 
-       if (fb_type(lb_get_pd_fb(handler)) == BUFFER_TYPE_FILE && handler->pd.lock_fd >= 0) {
-               (void)do_fb_lock(handler->pd.lock_fd);
-               ret = fb_sync(lb_get_pd_fb(handler));
-               (void)do_fb_unlock(handler->pd.lock_fd);
+       if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
+               (void)do_fb_lock(common->pd.lock_fd);
+               ret = fb_sync(lb_get_pd_fb(common));
+               (void)do_fb_unlock(common->pd.lock_fd);
        } else {
-               ret = fb_sync(lb_get_pd_fb(handler));
+               ret = fb_sync(lb_get_pd_fb(common));
        }
 
        return ret;
 }
 
+EAPI int livebox_sync_pd_fb(struct livebox *handler)
+{
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       return lb_sync_pd_fb(handler->common);
+}
+
 EAPI const char *livebox_alt_icon(struct livebox *handler)
 {
        if (!handler || handler->state != CREATE) {
                ErrPrint("Handler is not valid[%p]\n", handler);
                return NULL;
        }
-       return handler->icon;
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return NULL;
+       }
+
+       return handler->common->alt.icon;
 }
 
 EAPI const char *livebox_alt_name(struct livebox *handler)
@@ -3577,7 +4469,12 @@ EAPI const char *livebox_alt_name(struct livebox *handler)
                return NULL;
        }
 
-       return handler->name;
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return NULL;
+       }
+
+       return handler->common->alt.name;
 }
 
 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
@@ -3585,28 +4482,43 @@ EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
        int ret = LB_STATUS_SUCCESS;
        int fd;
 
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Handler is not valid[%p]\n", handler);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Handler is not valid\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Handler is not valid[%p]\n", handler);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
        if (is_pd) {
-               if (!handler->pd.lock || handler->pd.lock_fd < 0) {
-                       DbgPrint("Lock: %s (%d)\n", handler->pd.lock, handler->pd.lock_fd);
+               if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
+                       DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (fb_type(lb_get_pd_fb(handler)) == BUFFER_TYPE_FILE) {
+               if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
                        return LB_STATUS_SUCCESS;
                }
 
-               fd = handler->pd.lock_fd;
+               fd = handler->common->pd.lock_fd;
        } else {
-               if (!handler->lb.lock || handler->lb.lock_fd < 0) {
-                       DbgPrint("Lock: %s (%d)\n", handler->lb.lock, handler->lb.lock_fd);
+               if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
+                       DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (fb_type(lb_get_lb_fb(handler)) == BUFFER_TYPE_FILE) {
+               if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
                        return LB_STATUS_SUCCESS;
                }
 
-               fd = handler->lb.lock_fd;
+               fd = handler->common->lb.lock_fd;
        }
 
        ret = do_fb_lock(fd);
@@ -3619,28 +4531,43 @@ EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
        int ret = LB_STATUS_SUCCESS;
        int fd;
 
+       if (!handler || handler->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common || handler->common->state != CREATE) {
+               ErrPrint("Invalid handle\n");
+               return LB_STATUS_ERROR_INVALID;
+       }
+
+       if (!handler->common->id) {
+               ErrPrint("Handler is not valid[%p]\n", handler);
+               return LB_STATUS_ERROR_INVALID;
+       }
+
        if (is_pd) {
-               if (!handler->pd.lock || handler->pd.lock_fd < 0) {
-                       DbgPrint("Unlock: %s (%d)\n", handler->pd.lock, handler->pd.lock_fd);
+               if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
+                       DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (fb_type(lb_get_pd_fb(handler)) == BUFFER_TYPE_FILE) {
+               if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
                        return LB_STATUS_SUCCESS;
                }
 
-               fd = handler->pd.lock_fd;
+               fd = handler->common->pd.lock_fd;
        } else {
-               if (!handler->lb.lock || handler->lb.lock_fd < 0) {
-                       DbgPrint("Unlock: %s (%d)\n", handler->lb.lock, handler->lb.lock_fd);
+               if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
+                       DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
                        return LB_STATUS_ERROR_INVALID;
                }
 
-               if (fb_type(lb_get_lb_fb(handler)) == BUFFER_TYPE_FILE) {
+               if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
                        return LB_STATUS_SUCCESS;
                }
 
-               fd = handler->lb.lock_fd;
+               fd = handler->common->lb.lock_fd;
        }
 
        ret = do_fb_unlock(fd);
@@ -3648,4 +4575,48 @@ EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
        return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
 }
 
+EAPI int livebox_set_option(enum livebox_option_type option, int state)
+{
+       int ret = LB_STATUS_SUCCESS;
+
+       switch (option) {
+       case LB_OPTION_MANUAL_SYNC:
+               conf_set_manual_sync(state);
+               break;
+       case LB_OPTION_FRAME_DROP_FOR_RESIZE:
+               conf_set_frame_drop_for_resizing(state);
+               break;
+       case LB_OPTION_SHARED_CONTENT:
+               conf_set_shared_content(state);
+               break;
+       default:
+               ret = LB_STATUS_ERROR_INVALID;
+               break;
+       }
+
+       return ret;
+}
+
+EAPI int livebox_option(enum livebox_option_type option)
+{
+       int ret;
+
+       switch (option) {
+       case LB_OPTION_MANUAL_SYNC:
+               ret = conf_manual_sync();
+               break;
+       case LB_OPTION_FRAME_DROP_FOR_RESIZE:
+               ret = conf_frame_drop_for_resizing();
+               break;
+       case LB_OPTION_SHARED_CONTENT:
+               ret = conf_shared_content();
+               break;
+       default:
+               ret = LB_STATUS_ERROR_INVALID;
+               break;
+       }
+
+       return ret;
+}
+
 /* End of a file */
index 3af85ed..ec3b4cb 100644 (file)
@@ -95,7 +95,7 @@ static inline struct command *create_command(struct livebox *handler, struct pac
 static inline void destroy_command(struct command *command)
 {
        packet_unref(command->packet);
-       lb_unref(command->handler);
+       lb_unref(command->handler, 1);
        free(command);
 }
 
@@ -260,7 +260,7 @@ int master_rpc_clear_fault_package(const char *pkgname)
                        continue;
                }
 
-               if (!strcmp(command->handler->pkgname, pkgname)) {
+               if (!strcmp(command->handler->common->pkgname, pkgname)) {
                        s_info.cmd_list = dlist_remove(s_info.cmd_list, l);
                        if (command->ret_cb) {
                                command->ret_cb(command->handler, NULL, command->data);