From: Sung-jae Park Date: Sat, 11 Jan 2014 03:14:17 +0000 (+0900) Subject: [Experimental] Implement the "shared view" concept X-Git-Tag: submit/tizen_mobile/20150527.071719~1^2~30^2~14^2~29^2~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2ae812fbed1a4938102f0fcc518c68b66d84431e;p=platform%2Fcore%2Fappfw%2Fwidget-viewer.git [Experimental] Implement the "shared view" concept 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 --- diff --git a/TC/testcase/utc_livebox_viewer.c b/TC/testcase/utc_livebox_viewer.c index 0e46f01..83ec85d 100644 --- a/TC/testcase/utc_livebox_viewer.c +++ b/TC/testcase/utc_livebox_viewer.c @@ -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"); } diff --git a/include/conf.h b/include/conf.h index f134310..487aea1 100644 --- a/include/conf.h +++ b/include/conf.h @@ -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 */ diff --git a/include/debug.h b/include/debug.h index ed0b9b8..d06862c 100644 --- a/include/debug.h +++ b/include/debug.h @@ -24,4 +24,5 @@ extern FILE *__file_log_fp; #define ErrPrint(format, arg...) do { fprintf(__file_log_fp, "[ERR] [%s/%s:%d] " format, util_basename(__FILE__), __func__, __LINE__, ##arg); fflush(__file_log_fp); } while (0) #endif + /* End of a file */ diff --git a/include/desc_parser.h b/include/desc_parser.h index 0ba13ef..a7e0092 100644 --- a/include/desc_parser.h +++ b/include/desc_parser.h @@ -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 */ diff --git a/include/livebox.h b/include/livebox.h index d97c217..bead828 100644 --- a/include/livebox.h +++ b/include/livebox.h @@ -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); + +/*! * \} */ diff --git a/include/livebox_internal.h b/include/livebox_internal.h index fb9da64..a6f92f9 100644 --- a/include/livebox_internal.h +++ b/include/livebox_internal.h @@ -14,41 +14,50 @@ * 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 */ diff --git a/packaging/liblivebox-viewer.spec b/packaging/liblivebox-viewer.spec index 86e61c4..6c3a0ea 100644 --- a/packaging/liblivebox-viewer.spec +++ b/packaging/liblivebox-viewer.spec @@ -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 diff --git a/src/client.c b/src/client.c index 3a3266d..3604787 100644 --- a/src/client.c +++ b/src/client.c @@ -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, ×tamp, &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, diff --git a/src/conf.c b/src/conf.c index 9a9063b..95446aa 100644 --- a/src/conf.c +++ b/src/conf.c @@ -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 */ diff --git a/src/desc_parser.c b/src/desc_parser.c index d0fa14c..73ec31f 100644 --- a/src/desc_parser.c +++ b/src/desc_parser.c @@ -19,7 +19,12 @@ #include /* malloc */ #include /* strdup */ #include +#include +#include +#include +#include +#include #include #include #include @@ -31,36 +36,68 @@ #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 */ diff --git a/src/fb.c b/src/fb.c index 69c5dde..1dda034 100644 --- 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; } diff --git a/src/livebox.c b/src/livebox.c index c9d3635..d8c6bc2 100644 --- a/src/livebox.c +++ b/src/livebox.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -49,13 +50,25 @@ 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 */ diff --git a/src/master_rpc.c b/src/master_rpc.c index 3af85ed..ec3b4cb 100644 --- a/src/master_rpc.c +++ b/src/master_rpc.c @@ -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);