From: Sung-jae Park Date: Tue, 14 Jan 2014 23:58:44 +0000 (+0900) Subject: Revise code (sync with the latest commercial one) X-Git-Tag: accepted/tizen/generic/20140226.073644~8 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9e378008ec3f98e96b36af3eb25dced8cc53e2b2;p=platform%2Fframework%2Fweb%2Flivebox-viewer.git Revise code (sync with the latest commercial one) 1. Optimize the text parser (desc parser) ugly "realloc" is removed from the parser. there is only ONE memory allocation for parsing the text data. 2. Shared view concept is introduced. If client tries to add several instances using one package, viewer will creates fake handles using common real handle. Even if user creates 100000* dboxes, there is only A real handle. All other handles just duplicates its contents. This will save the power consumption, decrease the memory pressure, optimize the IPC overhead. 3. Refactoring the livebox handle structure. for supporiting the "2." Change-Id: Id8607cc247fd61fde8a251858bf2d23dd2a1119d --- diff --git a/include/conf.h b/include/conf.h index f134310..83f2ff4 100644 --- a/include/conf.h +++ b/include/conf.h @@ -34,5 +34,9 @@ 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); +extern double conf_event_filter(void); +extern void conf_set_event_filter(double filter); /* End of a file */ diff --git a/include/debug.h b/include/debug.h index f9df62d..2983a06 100644 --- a/include/debug.h +++ b/include/debug.h @@ -36,4 +36,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..2e71f2e 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.2 Release: 1 Group: HomeTF/Livebox License: Flora diff --git a/src/client.c b/src/client.c index 3a3266d..232d785 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; @@ -68,6 +69,7 @@ static struct packet *master_fault_package(pid_t pid, int handle, const struct p return NULL; } + DbgPrint("[%s]\n", pkgname); master_rpc_clear_fault_package(pkgname); lb_invoke_fault_handler(LB_FAULT_DEACTIVATED, pkgname, id, function); return NULL; @@ -75,11 +77,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 +91,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); + DbgPrint("HOLD: [%s] seize(%d)\n", id, seize); + seize = seize ? LB_EVENT_HOLD_SCROLL : LB_EVENT_RELEASE_SCROLL; + dlist_foreach(common->livebox_list, l, livebox) { + lb_invoke_event_handler(livebox, seize); + } out: return NULL; @@ -106,6 +113,9 @@ 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 dlist *n; + struct livebox_common *common; char *new_content; int ret; int status; @@ -117,38 +127,42 @@ 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; } - if (status == 0) { + if (status == LB_STATUS_SUCCESS) { 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_safe(common->livebox_list, l, n, handler) { + if (handler->cbs.pinup.cb) { + ret_cb_t cb; + void *cbdata; - /* Make sure that user can call pinup API in its result callback */ - cb = handler->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 == LB_STATUS_SUCCESS) { + lb_invoke_event_handler(handler, LB_EVENT_PINUP_CHANGED); + } } out: @@ -161,6 +175,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 +185,9 @@ static struct packet *master_deleted(pid_t pid, int handle, const struct packet goto out; } - handler = lb_find_livebox_by_timestamp(timestamp); - if (!handler) { + DbgPrint("[%s]\n", pkgname); + common = lb_find_common_handle_by_timestamp(timestamp); + if (!common) { /*! * \note * This can be happens only if the user delete a livebox @@ -179,8 +197,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 +208,72 @@ 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); + } } - } - - /*! - * \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); + /* Just try to delete it, if a user didn't remove it from the live box list */ + lb_unref(handler, 1); + } out: return NULL; @@ -257,6 +282,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 +297,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 +319,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 +343,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 +355,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 +389,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 +400,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 +427,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 +440,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 +476,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 +489,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 +517,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 +530,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 +563,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 +574,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 +610,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 +626,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 +643,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(handler)) { - (void)parse_desc(handler, livebox_filename(handler), 0); + if (lb_text_lb(common)) { + const char *common_filename; + + common_filename = common->filename ? common->filename : util_uri_to_path(common->id); + + (void)parse_desc(common, common_filename, 0); /*! * \note * DESC parser will call the "text event callback". * Don't need to call global event callback in this case. */ goto out; - } else if (lb_get_lb_fb(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 +687,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 +702,12 @@ 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; + struct dlist *n; int width; int height; int ret; @@ -640,68 +719,80 @@ static struct packet *master_pd_created(pid_t pid, int handle, const struct pack goto out; } - handler = lb_find_livebox(pkgname, id); - if (!handler) { + DbgPrint("[%s]\n", pkgname); + 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)) { - 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); - if (ret < 0) { - ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); - } + if (!common->request.pd_created) { + ErrPrint("PD create request is canceled\n"); + goto out; } - handler->is_pd_created = (status == 0); + common->is_pd_created = (status == LB_STATUS_SUCCESS); + common->request.pd_created = 0; - switch (handler->pd.type) { - case _PD_TYPE_SCRIPT: - case _PD_TYPE_BUFFER: - switch (fb_type(lb_get_pd_fb(handler))) { - case BUFFER_TYPE_FILE: - case BUFFER_TYPE_SHM: - lb_create_lock_file(handler, 1); - break; - case BUFFER_TYPE_PIXMAP: - case BUFFER_TYPE_ERROR: - default: - break; + if (common->is_pd_created) { + lb_set_pdsize(common, width, height); + if (lb_text_pd(common)) { + DbgPrint("Text TYPE does not need to handle this\n"); + } else { + (void)lb_set_pd_fb(common, buf_id); + + switch (common->pd.type) { + case _PD_TYPE_SCRIPT: + case _PD_TYPE_BUFFER: + switch (fb_type(lb_get_pd_fb(common))) { + case BUFFER_TYPE_FILE: + case BUFFER_TYPE_SHM: + lb_create_lock_file(common, 1); + break; + case BUFFER_TYPE_PIXMAP: + case BUFFER_TYPE_ERROR: + default: + break; + } + break; + case _PD_TYPE_TEXT: + default: + break; + } + + ret = lb_sync_pd_fb(common); + if (ret < 0) { + ErrPrint("Failed to do sync FB (%s - %s)\n", pkgname, util_basename(util_uri_to_path(id))); + } } - break; - case _PD_TYPE_TEXT: - default: - break; } - if (handler->pd_created_cb) { - ret_cb_t cb; - void *cbdata; + DbgPrint("PERF_DBOX\n"); + dlist_foreach_safe(common->livebox_list, l, n, handler) { + if (handler->cbs.pd_created.cb) { + ret_cb_t cb; + void *cbdata; - cb = handler->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 if (status == LB_STATUS_SUCCESS) { + lb_invoke_event_handler(handler, LB_EVENT_PD_CREATED); + } } out: @@ -711,6 +802,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 +815,59 @@ static struct packet *master_pd_destroyed(pid_t pid, int handle, const struct pa goto out; } - handler = lb_find_livebox(pkgname, id); - if (!handler) { + DbgPrint("[%s]\n", pkgname); + 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; + if (common->is_pd_created == 0) { + ErrPrint("PD is not created, event is ignored\n"); + goto out; + } - if (handler->pd_destroyed_cb) { - ret_cb_t cb; - void *cbdata; + common->is_pd_created = 0; + common->request.pd_destroyed = 0; - cb = handler->pd_destroyed_cb; - cbdata = handler->pd_destroyed_cbdata; + dlist_foreach(common->livebox_list, l, handler) { + if (handler->cbs.pd_destroyed.cb) { + ret_cb_t cb; + void *cbdata; - handler->pd_destroyed_cb = NULL; - handler->pd_destroyed_cbdata = NULL; + cb = handler->cbs.pd_destroyed.cb; + cbdata = handler->cbs.pd_destroyed.data; - /*! - * 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); + 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 == LB_STATUS_SUCCESS) { + 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 +892,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 +906,14 @@ static struct packet *master_pd_updated(pid_t pid, int handle, const struct pack goto out; } - handler = lb_find_livebox(pkgname, id); - if (!handler) { + DbgPrint("[%s]\n", pkgname); + 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 +924,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 +959,9 @@ 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; + struct dlist *n; const char *pkgname; const char *id; int active_mode; @@ -867,34 +979,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_safe(common->livebox_list, l, n, 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 if (status == LB_STATUS_SUCCESS) { + lb_invoke_event_handler(handler, LB_EVENT_UPDATE_MODE_CHANGED); + } } out: @@ -904,6 +1019,7 @@ out: static struct packet *master_size_changed(pid_t pid, int handle, const struct packet *packet) { struct livebox *handler; + struct livebox_common *common; const char *pkgname; const char *id; const char *fbfile; @@ -924,17 +1040,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 @@ -943,64 +1060,60 @@ static struct packet *master_size_changed(pid_t pid, int handle, const struct pa * So the PD has no private resized event handler. * 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); + if (status == LB_STATUS_SUCCESS) { + struct dlist *l; + + lb_set_pdsize(common, w, h); + dlist_foreach(common->livebox_list, l, handler) { + lb_invoke_event_handler(handler, LB_EVENT_PD_SIZE_CHANGED); + } } else { ErrPrint("This is not possible. PD Size is changed but the return value is not ZERO (%d)\n", status); } } else { - if (status == 0) { - lb_set_size(handler, w, h); + struct dlist *l; + struct dlist *n; + + if (status == LB_STATUS_SUCCESS) { + lb_set_size(common, w, h); /*! * \NOTE * If there is a created LB FB, * Update it too. */ - if (lb_get_lb_fb(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_safe(common->livebox_list, l, n, 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 == LB_STATUS_SUCCESS) { 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 +1124,9 @@ 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; + struct dlist *n; const char *pkgname; const char *id; int ret; @@ -1023,34 +1139,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); + if (status == LB_STATUS_SUCCESS) { + 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_safe(common->livebox_list, l, n, handler) { + if (handler->cbs.period_changed.cb) { + ret_cb_t cb; + void *cbdata; + + cb = handler->cbs.period_changed.cb; + cbdata = handler->cbs.period_changed.data; - handler->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 == LB_STATUS_SUCCESS) { + lb_invoke_event_handler(handler, LB_EVENT_PERIOD_CHANGED); + } } out: @@ -1060,6 +1180,9 @@ 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; + struct dlist *n; const char *pkgname; const char *id; int ret; @@ -1073,13 +1196,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, @@ -1089,23 +1212,27 @@ static struct packet *master_group_changed(pid_t pid, int handle, const struct p goto out; } - if (status == 0) { - (void)lb_set_group(handler, cluster, category); + if (status == LB_STATUS_SUCCESS) { + (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_safe(common->livebox_list, l, n, handler) { + if (handler->cbs.group_changed.cb) { + ret_cb_t cb; + void *cbdata; + + cb = handler->cbs.group_changed.cb; + cbdata = handler->cbs.group_changed.data; - handler->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 == LB_STATUS_SUCCESS) { + lb_invoke_event_handler(handler, LB_EVENT_GROUP_CHANGED); + } } out: @@ -1115,6 +1242,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 +1298,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 +1327,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 +1341,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 +1357,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 +1365,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 +1376,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 +1398,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 +1413,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..1c1f898 100644 --- a/src/conf.c +++ b/src/conf.c @@ -3,9 +3,15 @@ static struct info { int manual_sync; int frame_drop_for_resizing; + int shared_content; + + double event_filter; } s_info = { .manual_sync = 0, .frame_drop_for_resizing = 1, + .shared_content = 0, + + .event_filter = 0.01f, }; void conf_set_manual_sync(int flag) @@ -28,4 +34,24 @@ int conf_frame_drop_for_resizing(void) return s_info.frame_drop_for_resizing; } +void conf_set_shared_content(int flag) +{ + s_info.shared_content = flag; +} + +int conf_shared_content(void) +{ + return s_info.shared_content; +} + +double conf_event_filter(void) +{ + return s_info.event_filter; +} + +void conf_set_event_filter(double filter) +{ + s_info.event_filter = filter; +} + /* End of a file */ diff --git a/src/desc_parser.c b/src/desc_parser.c 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..16674b7 100644 --- a/src/livebox.c +++ b/src/livebox.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -43,26 +44,39 @@ #include "conf.h" #define EAPI __attribute__((visibility("default"))) -#define MINIMUM_EVENT s_info.event_filter #if defined(FLOG) 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, .fault_list = NULL, .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 +85,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 +218,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,10 +315,15 @@ 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; - return; + handler->cbs.update_mode.cb(handler, ret, handler->cbs.update_mode.data); + handler->cbs.update_mode.cb = NULL; + handler->cbs.update_mode.data = NULL; + handler->common->request.update_mode = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static void resize_cb(struct livebox *handler, const struct packet *result, void *data) @@ -332,9 +356,15 @@ 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; + handler->common->request.size_changed = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data) @@ -381,9 +411,15 @@ 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; + handler->common->request.group_changed = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data) @@ -406,9 +442,15 @@ 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; + handler->common->request.period_changed = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data) @@ -431,8 +473,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 +485,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 +508,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 +526,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 +549,15 @@ 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; + handler->common->request.pd_created = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static void activated_cb(struct livebox *handler, const struct packet *result, void *data) @@ -554,12 +602,16 @@ static void pd_destroy_cb(struct livebox *handler, const struct packet *result, ret = LB_STATUS_ERROR_INVALID; } - if (ret == 0) { - handler->pd_destroyed_cb = cb; - handler->pd_destroyed_cbdata = cbdata; - } else if (cb) { - handler->is_pd_created = 0; - cb(handler, ret, cbdata); + if (ret == LB_STATUS_SUCCESS) { + handler->cbs.pd_destroyed.cb = cb; + handler->cbs.pd_destroyed.data = cbdata; + } else { + handler->common->is_pd_created = 0; + handler->common->request.pd_destroyed = 0; + + if (cb) { + cb(handler, ret, cbdata); + } } } @@ -607,6 +659,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,9 +710,16 @@ 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 if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + if (cb) { + cb(handler, pixmap, cbdata); + } + + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); } else { if (cb) { cb(handler, pixmap, cbdata); @@ -636,6 +727,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,9 +784,15 @@ 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 if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + if (cb) { + cb(handler, pixmap, cbdata); + } + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); } else { if (cb) { DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap); @@ -686,9 +819,15 @@ 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; + handler->common->request.pinup = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static void key_ret_cb(struct livebox *handler, const struct packet *result, void *data) @@ -711,10 +850,15 @@ 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; - return; + handler->cbs.key_event.cb(handler, ret, handler->cbs.key_event.data); + handler->cbs.key_event.cb = NULL; + handler->cbs.key_event.data = NULL; + handler->common->request.key_event = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static void access_ret_cb(struct livebox *handler, const struct packet *result, void *data) @@ -738,10 +882,15 @@ 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; - return; + handler->cbs.access_event.cb(handler, ret, handler->cbs.access_event.data); + handler->cbs.access_event.cb = NULL; + handler->cbs.access_event.data = NULL; + handler->common->request.access_event = 0; + + if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) { + lb_invoke_event_handler(handler, LB_EVENT_DELETED); + lb_unref(handler, 1); + } } static int send_access_event(struct livebox *handler, const char *event, int x, int y) @@ -751,7 +900,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 +915,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 +930,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; @@ -821,7 +970,7 @@ EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double eve * So set them using arguments. */ s_info.prevent_overwrite = prevent_overwrite; - MINIMUM_EVENT = event_filter; + conf_set_event_filter(event_filter); initialize_livebox(disp, use_thread); return LB_STATUS_SUCCESS; @@ -843,7 +992,10 @@ EAPI int livebox_init(void *disp) env = getenv("PROVIDER_EVENT_FILTER"); if (env) { - sscanf(env, "%lf", &MINIMUM_EVENT); + double event_filter; + if (sscanf(env, "%lf", &event_filter) == 1) { + conf_set_event_filter(event_filter); + } } initialize_livebox(disp, 0); @@ -883,6 +1035,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,178 +1121,476 @@ 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; +} + +struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category) +{ + struct livebox_common *common; + + common = calloc(1, sizeof(*common)); + if (!common) { + ErrPrint("Heap: %s\n", strerror(errno)); + return NULL; + } + + common->pkgname = strdup(pkgname); + if (!common->pkgname) { + free(common); + return NULL; + } + + common->cluster = strdup(cluster); + if (!common->cluster) { + ErrPrint("Error: %s\n", strerror(errno)); + free(common->pkgname); + free(common); + return NULL; + } + + common->category = strdup(category); + if (!common->category) { + ErrPrint("Error: %s\n", strerror(errno)); + free(common->cluster); + free(common->pkgname); + free(common); + return NULL; + } + + /* Data provider will set this */ + common->lb.type = _LB_TYPE_FILE; + common->pd.type = _PD_TYPE_SCRIPT; + + /* Used for handling the mouse event on a box */ + common->lb.mouse_event = 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; +} + +int lb_destroy_common_handle(struct livebox_common *common) +{ + dlist_remove_data(s_info.livebox_common_list, common); + + 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); + + if (common->lb.fb) { + fb_destroy(common->lb.fb); + common->lb.fb = NULL; + } + + if (common->pd.fb) { + fb_destroy(common->pd.fb); + common->pd.fb = NULL; + } + + return 0; +} + +int lb_common_ref(struct livebox_common *common, struct livebox *handle) +{ + common->livebox_list = dlist_append(common->livebox_list, handle); + common->refcnt++; + + return common->refcnt; +} + +int lb_common_unref(struct livebox_common *common, struct livebox *handle) +{ + int refcnt; + dlist_remove_data(common->livebox_list, handle); + refcnt = --common->refcnt; + + return refcnt; +} + +static void refresh_for_paused_updating_cb(struct livebox *handle, int ret, void *data) +{ + if (handle->paused_updating == 0) { + DbgPrint("Paused updates are cleared\n"); + return; + } + + DbgPrint("Pending updates are found\n"); + lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED); +} - if (handler->lb.period == period) { +static int lb_set_visibility(struct livebox *handler, enum livebox_visible_state state) +{ + struct packet *packet; + int need_to_add_job = 0; + int ret; + + if (handler->common->visible != LB_SHOW && state == LB_SHOW) { + need_to_add_job = !!handler->paused_updating; + } else if (handler->common->visible == LB_SHOW && state != LB_SHOW) { + struct dlist *l; + struct livebox *item; + + dlist_foreach(handler->common->livebox_list, l, item) { + if (item->visible == LB_SHOW) { + DbgPrint("%s visibility is not changed\n", handler->common->pkgname); + return LB_STATUS_SUCCESS; + } + } + } else if (handler->common->visible == LB_SHOW && state == LB_SHOW && handler->paused_updating) { + if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) { + ErrPrint("Unable to add a new job for refreshing box\n"); + } + + return LB_STATUS_SUCCESS; + } else { + /*! + * \brief + * No need to send this to the master + */ + return LB_STATUS_SUCCESS; + } + + packet = packet_create_noack("change,visibility", "ssi", handler->common->pkgname, handler->common->id, (int)state); + if (!packet) { + ErrPrint("Failed to create a packet\n"); + return LB_STATUS_ERROR_FAULT; + } + + ret = master_rpc_request_only(handler, packet); + if (ret == LB_STATUS_SUCCESS) { + DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state); + handler->common->visible = state; + + if (need_to_add_job) { + if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) { + ErrPrint("Unable to add a new job for refreshing box\n"); + } + } + } + + return ret; +} + +EAPI struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data) +{ + char *lbid; + struct livebox *handler; + int w = 0; + int h = 0; + + if (!pkgname || !cluster || !category) { + ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n", + pkgname, cluster, category); + return NULL; + } + + lbid = lb_pkgname(pkgname); + if (!lbid) { + ErrPrint("Invalid package: %s\n", pkgname); + return NULL; + } + + if (livebox_service_is_enabled(lbid) == 0) { + DbgPrint("Livebox [%s](%s) is disabled package\n", lbid, pkgname); + free(lbid); + return NULL; + } + + if (type != LB_SIZE_TYPE_UNKNOWN) { + (void)livebox_service_get_size(type, &w, &h); + } + + handler = calloc(1, sizeof(*handler)); + if (!handler) { + ErrPrint("Error: %s\n", strerror(errno)); + free(lbid); + return NULL; + } + + if (!cb) { + cb = default_create_cb; + } + + handler->common = find_sharable_common_handle(lbid, content, w, h, cluster, category); + if (!handler->common) { + handler->common = lb_create_common_handle(handler, lbid, cluster, category); + free(lbid); + if (!handler->common) { + ErrPrint("Failed to find common handle\n"); + free(handler); + return NULL; + } + + if (!content || !strlen(content)) { + char *pc; + /*! + * \note + * I know the content should not be modified. use it temporarly without "const" + */ + pc = livebox_service_content(handler->common->pkgname); + lb_set_content(handler->common, pc); + free(pc); + } else { + lb_set_content(handler->common, content); + } + + lb_set_period(handler->common, period); + lb_set_size(handler->common, w, h); + lb_common_ref(handler->common, handler); + + if (create_real_instance(handler, cb, data) < 0) { + if (lb_common_unref(handler->common, handler) == 0) { + /*! + * Delete common + */ + lb_destroy_common_handle(handler->common); + handler->common = NULL; + } + free(handler); + return NULL; + } + } else { + free(lbid); + + lb_common_ref(handler->common, handler); + + if (handler->common->request.created) { + /*! + * If a box is in creating, wait its result too + */ + handler->cbs.created.cb = cb; + handler->cbs.created.data = data; + } else { + /*! + * or fire the fake created_event + */ + if (create_fake_instance(handler, cb, data) < 0) { + if (lb_common_unref(handler->common, handler) == 0) { + /*! + * Delete common + */ + lb_destroy_common_handle(handler->common); + } + free(handler); + return NULL; + } + } + } + + handler->visible = LB_SHOW; + handler->state = CREATE; + handler = lb_ref(handler); + + if (handler->common->visible != LB_SHOW) { + lb_set_visibility(handler, LB_SHOW); + } + + return handler; +} + +EAPI double livebox_period(struct livebox *handler) +{ + if (!handler || handler->state != CREATE) { + ErrPrint("Handler is not valid\n"); + return 0.0f; + } + + if (!handler->common || handler->common->state != CREATE) { + ErrPrint("Invalid handle\n"); + return 0.0f; + } + + if (!handler->common->id) { + ErrPrint("Hnalder is not valid\n"); + return 0.0f; + } + + return handler->common->lb.period; +} + +EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data) +{ + struct packet *packet; + int ret; + + if (!handler || handler->state != CREATE) { + ErrPrint("Handler is not valid\n"); + return LB_STATUS_ERROR_INVALID; + } + + if (!handler->common || handler->common->state != CREATE) { + ErrPrint("Invalid handle\n"); + return LB_STATUS_ERROR_INVALID; + } + + if (!handler->common->id) { + ErrPrint("Handler is not valid\n"); + return LB_STATUS_ERROR_INVALID; + } + + if (handler->common->request.period_changed) { + ErrPrint("Previous request for changing period is not finished\n"); + return LB_STATUS_ERROR_BUSY; + } + + if (!handler->common->is_user) { + ErrPrint("CA Livebox is not able to change the period\n"); + return LB_STATUS_ERROR_PERMISSION; + } + + if (handler->common->lb.period == period) { DbgPrint("No changes\n"); return LB_STATUS_ERROR_ALREADY; } - packet = packet_create("set_period", "ssd", handler->pkgname, handler->id, period); + packet = packet_create("set_period", "ssd", handler->common->pkgname, handler->common->id, period); if (!packet) { - ErrPrint("Failed to build a packet %s\n", handler->pkgname); + ErrPrint("Failed to build a packet %s\n", handler->common->pkgname); return LB_STATUS_ERROR_FAULT; } @@ -1072,53 +1600,104 @@ EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, 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; + handler->cbs.period_changed.cb = cb; + handler->cbs.period_changed.data = data; + handler->common->request.period_changed = 1; } return ret; } -EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data) +static void lb_update_visibility(struct livebox_common *old_common) { - if (!handler) { - ErrPrint("Handler is NIL\n"); - return LB_STATUS_ERROR_INVALID; + 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 (handler->state != CREATE) { - ErrPrint("Handler is already deleted\n"); - return LB_STATUS_ERROR_INVALID; + if (!item) { + l = dlist_nth(old_common->livebox_list, 0); + item = dlist_data(l); + + if (item) { + lb_set_visibility(item, LB_HIDE_WITH_PAUSE); + } else { + ErrPrint("Unable to get the valid handle from common handler\n"); + } + } else { + lb_set_visibility(item, LB_SHOW); } +} - handler->state = DELETE; - handler->delete_type = type; +/*! + * \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 (!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 (handle->visible == LB_SHOW) { + lb_update_visibility(handle->common); + } + + cb = cbinfo->cb; + data = cbinfo->data; + destroy_cb_info(cbinfo); + + if (handle->common->state != CREATE) { + DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt); if (cb) { - cb(handler, 0, data); + cb(handle, LB_STATUS_SUCCESS, data); } - return LB_STATUS_SUCCESS; - } - if (!cb) { - cb = default_delete_cb; + return; } - return lb_send_delete(handler, type, cb, data); + 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(struct livebox *handler, ret_cb_t cb, void *data) +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 +1709,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 +1746,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 +1761,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 +1794,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 +1809,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 +1830,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 +1869,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 +1879,210 @@ 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->state != CREATE || !handler->id) { + 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->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); /* To update visibility: Show --> Paused */ + lb_update_visibility(common); /* To update visibility: Paused --> Show */ + } + } else { + destroy_cb_info(cbinfo); + } + } + } } return ret; @@ -1359,47 +2094,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 +2164,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->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; } - 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) @@ -1443,32 +2207,70 @@ EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data) return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data); } +static void turn_off_pd_destroyed_flag_cb(struct livebox *handler, int ret, void *data) +{ + if (handler->common->request.pd_destroyed) { + ret_cb_t cb; + void *data; + + DbgPrint("pd_destroyed request is canceled\n"); + handler->common->request.pd_destroyed = 0; + cb = handler->cbs.pd_destroyed.cb; + data = handler->cbs.pd_destroyed.data; + handler->cbs.pd_destroyed.cb = NULL; + handler->cbs.pd_destroyed.data = NULL; + + if (cb) { + cb(handler, ret, data); + } + } +} + EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data) { struct packet *packet; int ret; - if (!handler) { - 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) { - DbgPrint("PD already created\n"); + /*! + * \note + * Only one handler can have a PD + */ + if (handler->common->is_pd_created) { + DbgPrint("PD is already created\n"); return LB_STATUS_SUCCESS; } - if (handler->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); + /*! + * \note + * Turn off the pd_destroyed request flag + */ + if (handler->common->request.pd_destroyed) { + if (job_add(handler, turn_off_pd_destroyed_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) { + ErrPrint("Failed to add pd_destroyed job\n"); + } + } + + packet = packet_create("create_pd", "ssdd", handler->common->pkgname, handler->common->id, x, y); if (!packet) { ErrPrint("Failed to build param\n"); return LB_STATUS_ERROR_FAULT; @@ -1481,8 +2283,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 +2295,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; @@ -1547,28 +2355,75 @@ EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data) return ret; } +static void turn_off_pd_created_flag_cb(struct livebox *handler, int ret, void *data) +{ + if (handler->common->request.pd_created) { + ret_cb_t cb; + void *data; + + DbgPrint("pd_created request is canceled\n"); + handler->common->request.pd_created = 0; + cb = handler->cbs.pd_created.cb; + data = handler->cbs.pd_created.data; + handler->cbs.pd_created.cb = NULL; + handler->cbs.pd_created.data = NULL; + + if (cb) { + cb(handler, ret, data); + } + } +} + EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data) { struct packet *packet; struct cb_info *cbinfo; int ret; - if (!handler) { - 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); + if (handler->common->request.pd_destroyed) { + ErrPrint("PD destroy request is already sent\n"); + return LB_STATUS_ERROR_ALREADY; + } + + /*! + * \note + * Disable the pd_created request flag + */ + if (handler->common->request.pd_created) { + if (job_add(handler, turn_off_pd_created_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) { + ErrPrint("Failed to add a new job\n"); + } + } + + DbgPrint("[%s]\n", handler->common->pkgname); + + packet = packet_create("destroy_pd", "ss", handler->common->pkgname, handler->common->id); if (!packet) { ErrPrint("Failed to build a param\n"); return LB_STATUS_ERROR_FAULT; @@ -1587,6 +2442,8 @@ EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data) ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo); if (ret < 0) { destroy_cb_info(cbinfo); + } else { + handler->common->request.pd_destroyed = 1; } return ret; @@ -1600,35 +2457,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 +2537,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 +2557,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 +2580,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) < conf_event_filter() && fabs(y - handler->common->pd.y) < conf_event_filter()) { return LB_STATUS_ERROR_BUSY; } } else if (type & CONTENT_EVENT_MOUSE_SET) { @@ -1731,27 +2599,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) < conf_event_filter() && fabs(y - handler->common->lb.y) < conf_event_filter()) { return LB_STATUS_ERROR_BUSY; } } else if (type & CONTENT_EVENT_MOUSE_SET) { @@ -1759,10 +2627,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 +2678,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 +2698,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 +2729,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 +2789,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 +2799,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->state != CREATE || !handler->id) { + if (!handler->common || handler->common->state != CREATE) { + ErrPrint("Handler is invalid\n"); + return NULL; + } + + if (!handler->common->id) { ErrPrint("Handler is not valid\n"); return NULL; } - if (handler->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 +2827,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->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; } @@ -1960,12 +2849,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 +2865,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->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; } - 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 +2908,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->group_changed_cb) { + if (!handler->common->id) { + ErrPrint("Invalid argument\n"); + return LB_STATUS_ERROR_INVALID; + } + + if (handler->common->request.group_changed) { ErrPrint("Previous group changing request is not finished yet\n"); return LB_STATUS_ERROR_BUSY; } - if (!handler->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 +2950,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 +2965,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; } - *cluster = handler->cluster; - *category = handler->category; + if (!handler->common->id) { + ErrPrint("Invalid argument\n"); + return LB_STATUS_ERROR_INVALID; + } + + *cluster = handler->common->cluster; + *category = handler->common->category; return LB_STATUS_SUCCESS; } @@ -2080,13 +2995,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 +3036,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->common || handler->common->state != CREATE) { + ErrPrint("Handler is invalid\n"); + return -1.0f; } - if (handler->state != CREATE || !handler->id) { + 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 +3118,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->common || handler->common->state != CREATE) { + ErrPrint("Handler is invalid\n"); return LB_TYPE_INVALID; } - if (handler->state != CREATE || !handler->id) { + 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 +3157,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->common || handler->common->state != CREATE) { + ErrPrint("Handler is invalid\n"); return PD_TYPE_INVALID; } - if (handler->state != CREATE || !handler->id) { + 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 +3204,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 +3220,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 +3284,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 +3312,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 +3346,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 +3379,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->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->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 +3410,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->common || handler->common->state != CREATE) { + ErrPrint("Handler is invalid\n"); return NULL; } - if (handler->state != CREATE || !handler->id) { + 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 +3445,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->common || handler->common->state != CREATE) { + ErrPrint("Handler is invalid\n"); return NULL; } - if (handler->state != CREATE || !handler->id) { + 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 +3480,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; } - return fb_size(handler->pd.data.fb); + if (!handler->common->id) { + ErrPrint("Invalid handler\n"); + return LB_STATUS_ERROR_INVALID; + } + + return fb_size(handler->common->pd.fb); } EAPI int livebox_lbfb_bufsz(struct livebox *handler) { - if (!handler) { - 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 +3543,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->common || handler->common->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->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 +3580,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 +3590,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->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->lb.pinup_supported; + return handler->common->lb.pinup_supported; } EAPI int livebox_set_data(struct livebox *handler, void *data) @@ -2672,6 +3636,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 +3652,7 @@ EAPI void *livebox_get_data(struct livebox *handler) } if (handler->state != CREATE) { + ErrPrint("Handler is invalid\n"); return NULL; } @@ -2708,30 +3674,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 +3708,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 +3732,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 +3795,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 +3839,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->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; } - 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 +3865,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 +3885,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 +3925,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 +3968,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 +3990,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 +4059,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 +4084,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 +4205,27 @@ void lb_set_alt_info(struct livebox *handler, const char *icon, const char *name } } - if (handler->icon) { - free(handler->icon); - } - - handler->icon = _icon; - - if (handler->name) { - free(handler->name); - } + free(common->alt.icon); + common->alt.icon = _icon; - 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 +4234,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 +4250,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 +4272,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 +4287,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 +4342,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,99 +4353,91 @@ 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) { + /*! + * \note + * Lock file should be deleted after all callbacks are processed. + */ + lb_destroy_lock_file(handler->common, 0); + lb_destroy_common_handle(handler->common); + } } - free(handler); + DbgPrint("Handler is released\n"); return NULL; } @@ -3447,17 +4447,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 +4469,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 +4523,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 +4614,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 +4627,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 +4676,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 +4720,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);