2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
27 #include <com-core_packet.h>
28 #include <livebox-service.h>
29 #include <livebox-errno.h>
34 #include "slave_life.h"
35 #include "slave_rpc.h"
36 #include "client_life.h"
38 #include "client_rpc.h"
40 #include "script_handler.h"
41 #include "buffer_handler.h"
47 enum buffer_type env_buf_type;
49 .env_buf_type = BUFFER_TYPE_FILE,
52 struct set_pinup_cbdata {
53 struct inst_info *inst;
57 struct resize_cbdata {
58 struct inst_info *inst;
63 struct update_mode_cbdata {
64 struct inst_info *inst;
68 struct change_group_cbdata {
69 struct inst_info *inst;
74 struct period_cbdata {
75 struct inst_info *inst;
80 int (*event_cb)(struct inst_info *inst, void *data);
91 struct pkg_info *info;
93 enum instance_state state; /*!< Represents current state */
94 enum instance_state requested_state; /*!< Only ACTIVATED | DESTROYED is acceptable */
95 enum instance_destroy_type destroy_type;
107 int scroll_locked; /*!< Scroller which is in viewer is locked. */
108 int active_update; /*!< Viewer will reload the buffer by itself, so the provider doesn't need to send the updated event */
113 enum livebox_visible_state visible;
121 struct script_info *script;
122 struct buffer_info *buffer;
135 struct script_info *script;
136 struct buffer_info *buffer;
139 struct client_node *owner;
140 int is_opened_for_reactivate;
141 int need_to_send_close_event;
142 char *pended_update_desc;
143 int pended_update_cnt;
146 struct client_node *client; /*!< Owner - creator */
147 Eina_List *client_list; /*!< Viewer list */
150 Ecore_Timer *update_timer; /*!< Only used for secured livebox */
153 INST_EVENT_PROCESS_IDLE = 0x00,
154 INST_EVENT_PROCESS_DELETE = 0x01
156 Eina_List *delete_event_list;
158 Eina_List *data_list;
161 #define CLIENT_SEND_EVENT(instance, packet) ((instance)->client ? client_rpc_async_request((instance)->client, (packet)) : client_broadcast((instance), (packet)))
163 static Eina_Bool update_timer_cb(void *data);
165 static inline void timer_thaw(struct inst_info *inst)
172 ecore_timer_thaw(inst->update_timer);
173 period = ecore_timer_interval_get(inst->update_timer);
174 pending = ecore_timer_pending_get(inst->update_timer);
175 delay = util_time_delay_for_compensation(period) - pending;
176 ecore_timer_delay(inst->update_timer, delay);
178 if (inst->sleep_at == 0.0f) {
182 sleep_time = util_timestamp() - inst->sleep_at;
183 if (sleep_time > pending) {
184 (void)update_timer_cb(inst);
187 inst->sleep_at = 0.0f;
190 static inline void timer_freeze(struct inst_info *inst)
192 ecore_timer_freeze(inst->update_timer);
194 if (ecore_timer_interval_get(inst->update_timer) <= 1.0f) {
198 #if defined(_USE_ECORE_TIME_GET)
199 inst->sleep_at = ecore_time_get();
202 if (gettimeofday(&tv, NULL) < 0) {
203 ErrPrint("gettimeofday: %s\n", strerror(errno));
207 inst->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
212 static int viewer_deactivated_cb(struct client_node *client, void *data)
214 struct inst_info *inst = data;
216 DbgPrint("%d is deleted from the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
217 if (!eina_list_data_find(inst->client_list, client)) {
218 ErrPrint("Not found\n");
219 return LB_STATUS_ERROR_NOT_EXIST;
222 inst->client_list = eina_list_remove(inst->client_list, client);
223 if (!inst->client_list && !inst->client) {
224 DbgPrint("Has no clients\n");
225 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
228 instance_unref(inst);
229 return -1; /*!< Remove this callback from the cb list */
232 static int pause_livebox(struct inst_info *inst)
234 struct packet *packet;
236 packet = packet_create_noack("lb_pause", "ss", package_name(inst->info), inst->id);
238 ErrPrint("Failed to create a new packet\n");
239 return LB_STATUS_ERROR_FAULT;
242 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
245 /*! \TODO Wake up the freeze'd timer */
246 static int resume_livebox(struct inst_info *inst)
248 struct packet *packet;
250 packet = packet_create_noack("lb_resume", "ss", package_name(inst->info), inst->id);
252 ErrPrint("Failed to create a new packet\n");
253 return LB_STATUS_ERROR_FAULT;
256 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
259 static inline int instance_recover_visible_state(struct inst_info *inst)
263 switch (inst->visible) {
266 instance_thaw_updator(inst);
270 case LB_HIDE_WITH_PAUSE:
271 ret = pause_livebox(inst);
273 instance_freeze_updator(inst);
276 ret = LB_STATUS_ERROR_INVALID;
280 DbgPrint("Visible state is recovered to %d\n", ret);
284 static inline void instance_send_update_mode_event(struct inst_info *inst, int active_mode, int status)
286 struct packet *packet;
290 ErrPrint("Instance info is not ready to use\n");
294 pkgname = package_name(inst->info);
296 packet = packet_create_noack("update_mode", "ssii", pkgname, inst->id, status, active_mode);
298 CLIENT_SEND_EVENT(inst, packet);
300 ErrPrint("Failed to send update mode event\n");
304 static inline void instance_send_resized_event(struct inst_info *inst, int is_pd, int w, int h, int status)
306 struct packet *packet;
307 enum lb_type lb_type;
312 ErrPrint("Instance info is not ready to use\n");
316 pkgname = package_name(inst->info);
318 lb_type = package_lb_type(inst->info);
319 if (lb_type == LB_TYPE_SCRIPT) {
320 id = script_handler_buffer_id(inst->lb.canvas.script);
321 } else if (lb_type == LB_TYPE_BUFFER) {
322 id = buffer_handler_id(inst->lb.canvas.buffer);
327 packet = packet_create_noack("size_changed", "sssiiii", pkgname, inst->id, id, is_pd, w, h, status);
329 CLIENT_SEND_EVENT(inst, packet);
331 ErrPrint("Failed to send size changed event\n");
335 static void update_mode_cb(struct slave_node *slave, const struct packet *packet, void *data)
337 struct update_mode_cbdata *cbdata = data;
341 ErrPrint("Invalid packet\n");
342 ret = LB_STATUS_ERROR_FAULT;
346 if (packet_get(packet, "i", &ret) != 1) {
347 ErrPrint("Invalid parameters\n");
348 ret = LB_STATUS_ERROR_INVALID;
352 if (ret == (int)LB_STATUS_SUCCESS) {
353 cbdata->inst->active_update = cbdata->active_update;
357 instance_send_update_mode_event(cbdata->inst, cbdata->active_update, ret);
358 instance_unref(cbdata->inst);
362 HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_node *client)
364 struct packet *packet;
365 enum lb_type lb_type;
366 enum pd_type pd_type;
371 client = inst->client;
373 return LB_STATUS_SUCCESS;
377 lb_type = package_lb_type(inst->info);
378 pd_type = package_pd_type(inst->info);
380 if (lb_type == LB_TYPE_SCRIPT) {
381 lb_file = script_handler_buffer_id(inst->lb.canvas.script);
382 } else if (lb_type == LB_TYPE_BUFFER) {
383 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
388 if (pd_type == PD_TYPE_SCRIPT) {
389 pd_file = script_handler_buffer_id(inst->pd.canvas.script);
390 } else if (pd_type == PD_TYPE_BUFFER) {
391 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
396 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
398 package_name(inst->info), inst->id, inst->content,
399 inst->lb.width, inst->lb.height,
400 inst->pd.width, inst->pd.height,
401 inst->cluster, inst->category,
403 package_auto_launch(inst->info),
405 package_size_list(inst->info),
407 package_pinup(inst->info),
409 inst->lb.period, inst->title,
412 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
413 return LB_STATUS_ERROR_FAULT;
416 return client_rpc_async_request(client, packet);
419 static int update_client_list(struct client_node *client, void *data)
421 struct inst_info *inst = data;
423 if (!instance_has_client(inst, client)) {
424 instance_add_client(inst, client);
427 return LB_STATUS_SUCCESS;
430 static int instance_broadcast_created_event(struct inst_info *inst)
432 struct packet *packet;
433 enum lb_type lb_type;
434 enum pd_type pd_type;
438 lb_type = package_lb_type(inst->info);
439 pd_type = package_pd_type(inst->info);
441 if (lb_type == LB_TYPE_SCRIPT) {
442 lb_file = script_handler_buffer_id(inst->lb.canvas.script);
443 } else if (lb_type == LB_TYPE_BUFFER) {
444 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
449 if (pd_type == PD_TYPE_SCRIPT) {
450 pd_file = script_handler_buffer_id(inst->pd.canvas.script);
451 } else if (pd_type == PD_TYPE_BUFFER) {
452 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
458 client_browse_list(inst->cluster, inst->category, update_client_list, inst);
461 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
463 package_name(inst->info), inst->id, inst->content,
464 inst->lb.width, inst->lb.height,
465 inst->pd.width, inst->pd.height,
466 inst->cluster, inst->category,
468 package_auto_launch(inst->info),
470 package_size_list(inst->info),
472 package_pinup(inst->info),
474 inst->lb.period, inst->title,
477 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
478 return LB_STATUS_ERROR_FAULT;
481 return CLIENT_SEND_EVENT(inst, packet);
484 HAPI int instance_unicast_deleted_event(struct inst_info *inst, struct client_node *client, int reason)
486 struct packet *packet;
489 client = inst->client;
491 return LB_STATUS_ERROR_INVALID;
495 packet = packet_create_noack("deleted", "ssdi", package_name(inst->info), inst->id, inst->timestamp, reason);
497 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
498 return LB_STATUS_ERROR_FAULT;
501 return client_rpc_async_request(client, packet);
504 static int instance_broadcast_deleted_event(struct inst_info *inst, int reason)
506 struct packet *packet;
507 struct client_node *client;
512 packet = packet_create_noack("deleted", "ssdi", package_name(inst->info), inst->id, inst->timestamp, reason);
514 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
515 return LB_STATUS_ERROR_FAULT;
518 ret = CLIENT_SEND_EVENT(inst, packet);
520 EINA_LIST_FOREACH_SAFE(inst->client_list, l, n, client) {
521 instance_del_client(inst, client);
527 static int client_deactivated_cb(struct client_node *client, void *data)
529 struct inst_info *inst = data;
530 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
531 return LB_STATUS_SUCCESS;
534 static int send_pd_destroyed_to_client(struct inst_info *inst, int status)
536 struct packet *packet;
538 if (!inst->pd.need_to_send_close_event && status != LB_STATUS_ERROR_FAULT) {
539 ErrPrint("PD is not created\n");
540 return LB_STATUS_ERROR_INVALID;
543 packet = packet_create_noack("pd_destroyed", "ssi", package_name(inst->info), inst->id, status);
545 ErrPrint("Failed to create a packet\n");
546 return LB_STATUS_ERROR_FAULT;
549 inst->pd.need_to_send_close_event = 0;
551 return CLIENT_SEND_EVENT(inst, packet);
554 static inline void invoke_delete_callbacks(struct inst_info *inst)
558 struct event_item *item;
560 inst->in_event_process |= INST_EVENT_PROCESS_DELETE;
561 EINA_LIST_FOREACH_SAFE(inst->delete_event_list, l, n, item) {
562 if (item->deleted || item->event_cb(inst, item->data) < 0 || item->deleted) {
563 inst->delete_event_list = eina_list_remove(inst->delete_event_list, item);
567 inst->in_event_process &= ~INST_EVENT_PROCESS_DELETE;
570 HAPI int instance_event_callback_add(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data), void *data)
572 struct event_item *item;
575 return LB_STATUS_ERROR_INVALID;
579 case INSTANCE_EVENT_DESTROY:
580 item = malloc(sizeof(*item));
582 ErrPrint("Heap: %s\n", strerror(errno));
583 return LB_STATUS_ERROR_MEMORY;
586 item->event_cb = event_cb;
590 inst->delete_event_list = eina_list_append(inst->delete_event_list, item);
593 return LB_STATUS_ERROR_INVALID;
596 return LB_STATUS_SUCCESS;
599 HAPI int instance_event_callback_del(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data), void *data)
603 struct event_item *item;
606 case INSTANCE_EVENT_DESTROY:
607 EINA_LIST_FOREACH_SAFE(inst->delete_event_list, l, n, item) {
608 if (item->event_cb == event_cb && item->data == data) {
609 if (inst->in_event_process & INST_EVENT_PROCESS_DELETE) {
612 inst->delete_event_list = eina_list_remove(inst->delete_event_list, item);
615 return LB_STATUS_SUCCESS;
623 return LB_STATUS_ERROR_NOT_EXIST;
626 static inline void destroy_instance(struct inst_info *inst)
628 struct pkg_info *pkg;
629 enum lb_type lb_type;
630 enum pd_type pd_type;
631 struct slave_node *slave;
632 struct event_item *item;
633 struct tag_item *tag_item;
635 (void)send_pd_destroyed_to_client(inst, LB_STATUS_SUCCESS);
637 invoke_delete_callbacks(inst);
641 lb_type = package_lb_type(pkg);
642 pd_type = package_pd_type(pkg);
643 slave = package_slave(inst->info);
645 DbgPrint("Instance is destroyed (%p), slave(%p)\n", inst, slave);
647 if (lb_type == LB_TYPE_SCRIPT) {
648 (void)script_handler_unload(inst->lb.canvas.script, 0);
649 if (script_handler_destroy(inst->lb.canvas.script) == (int)LB_STATUS_SUCCESS) {
650 inst->lb.canvas.script = NULL;
652 } else if (lb_type == LB_TYPE_BUFFER) {
653 (void)buffer_handler_unload(inst->lb.canvas.buffer);
654 if (buffer_handler_destroy(inst->lb.canvas.buffer) == (int)LB_STATUS_SUCCESS) {
655 inst->lb.canvas.buffer = NULL;
659 if (pd_type == PD_TYPE_SCRIPT) {
660 (void)script_handler_unload(inst->pd.canvas.script, 1);
661 if (script_handler_destroy(inst->pd.canvas.script) == (int)LB_STATUS_SUCCESS) {
662 inst->pd.canvas.script = NULL;
664 } else if (pd_type == PD_TYPE_BUFFER) {
665 (void)buffer_handler_unload(inst->pd.canvas.buffer);
666 if (buffer_handler_destroy(inst->pd.canvas.buffer) == (int)LB_STATUS_SUCCESS) {
667 inst->pd.canvas.buffer = NULL;
672 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
673 client_unref(inst->client);
676 if (inst->update_timer) {
677 ecore_timer_del(inst->update_timer);
680 EINA_LIST_FREE(inst->data_list, tag_item) {
681 DbgPrint("Tagged item[%s] %p\n", tag_item->tag, tag_item->data);
682 DbgFree(tag_item->tag);
686 EINA_LIST_FREE(inst->delete_event_list, item) {
691 DbgFree(inst->category);
692 DbgFree(inst->cluster);
693 DbgFree(inst->content);
694 DbgFree(inst->title);
695 util_unlink(util_uri_to_path(inst->id));
697 package_del_instance(inst->info, inst);
700 slave = slave_unload_instance(slave);
703 static Eina_Bool update_timer_cb(void *data)
705 struct inst_info *inst = (struct inst_info *)data;
707 slave_rpc_request_update(package_name(inst->info), inst->id, inst->cluster, inst->category, NULL, 0);
708 return ECORE_CALLBACK_RENEW;
711 static inline int fork_package(struct inst_info *inst, const char *pkgname)
713 struct pkg_info *info;
716 info = package_find(pkgname);
718 ErrPrint("%s is not found\n", pkgname);
719 return LB_STATUS_ERROR_NOT_EXIST;
722 len = strlen(SCHEMA_FILE "%s%s_%d_%lf.png") + strlen(IMAGE_PATH) + strlen(package_name(info)) + 50;
723 inst->id = malloc(len);
725 ErrPrint("Heap: %s\n", strerror(errno));
726 return LB_STATUS_ERROR_MEMORY;
729 snprintf(inst->id, len, SCHEMA_FILE "%s%s_%d_%lf.png", IMAGE_PATH, package_name(info), client_pid(inst->client), inst->timestamp);
731 instance_set_pd_size(inst, package_pd_width(info), package_pd_height(info));
733 inst->lb.period = package_period(info);
737 if (package_secured(info)) {
738 if (inst->lb.period > 0.0f) {
739 inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
740 if (!inst->update_timer) {
741 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
743 timer_freeze(inst); /* Freeze the update timer as default */
746 inst->update_timer = NULL;
750 return LB_STATUS_SUCCESS;
753 HAPI struct inst_info *instance_create(struct client_node *client, double timestamp, const char *pkgname, const char *content, const char *cluster, const char *category, double period, int width, int height)
755 struct inst_info *inst;
757 inst = calloc(1, sizeof(*inst));
759 ErrPrint("Heap: %s\n", strerror(errno));
763 inst->timestamp = timestamp;
764 inst->lb.width = width;
765 inst->lb.height = height;
767 inst->content = strdup(content);
768 if (!inst->content) {
769 ErrPrint("Heap: %s\n", strerror(errno));
774 inst->cluster = strdup(cluster);
775 if (!inst->cluster) {
776 ErrPrint("Heap: %s\n", strerror(errno));
777 DbgFree(inst->content);
782 inst->category = strdup(category);
783 if (!inst->category) {
784 ErrPrint("Heap: %s\n", strerror(errno));
785 DbgFree(inst->cluster);
786 DbgFree(inst->content);
791 inst->title = strdup(DEFAULT_TITLE); /*!< Use the DEFAULT Title "" */
793 ErrPrint("Heap: %s\n", strerror(errno));
794 DbgFree(inst->category);
795 DbgFree(inst->cluster);
796 DbgFree(inst->content);
802 inst->client = client_ref(client);
803 if (client_event_callback_add(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst) < 0) {
804 ErrPrint("Failed to add client event callback: %s\n", inst->id);
808 if (fork_package(inst, pkgname) < 0) {
809 (void)client_unref(inst->client);
810 DbgFree(inst->title);
811 DbgFree(inst->category);
812 DbgFree(inst->cluster);
813 DbgFree(inst->content);
818 inst->state = INST_INIT;
819 inst->requested_state = INST_INIT;
822 if (package_add_instance(inst->info, inst) < 0) {
823 instance_destroy(inst, INSTANCE_DESTROY_FAULT);
827 slave_load_instance(package_slave(inst->info));
829 if (instance_activate(inst) < 0) {
830 instance_state_reset(inst);
831 instance_destroy(inst, INSTANCE_DESTROY_FAULT);
838 HAPI struct inst_info *instance_ref(struct inst_info *inst)
848 HAPI struct inst_info *instance_unref(struct inst_info *inst)
854 if (inst->refcnt == 0) {
855 ErrPrint("Instance refcnt is not valid\n");
860 if (inst->refcnt == 0) {
861 destroy_instance(inst);
868 static void deactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
870 struct inst_info *inst = data;
875 * In this callback, we cannot trust the "client" information.
876 * It could be cleared before reach to here.
882 * The instance_reload will care this.
883 * And it will be called from the slave activate callback.
888 if (packet_get(packet, "i", &ret) != 1) {
889 ErrPrint("Invalid argument\n");
893 DbgPrint("[%s] %d (0x%X)\n", inst->id, ret, inst->state);
895 if (inst->state == INST_DESTROYED) {
899 * Do nothing at here anymore.
908 * Successfully unloaded
910 switch (inst->requested_state) {
912 instance_state_reset(inst);
913 instance_reactivate(inst);
916 instance_broadcast_deleted_event(inst, ret);
917 instance_state_reset(inst);
918 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
920 /*!< Unable to reach here */
925 case LB_STATUS_ERROR_INVALID:
928 * Slave has no instance of this package.
930 case LB_STATUS_ERROR_NOT_EXIST:
933 * This instance's previous state is only can be the INST_ACTIVATED.
934 * So we should care the slave_unload_instance from here.
935 * And we should send notification to clients, about this is deleted.
939 * Slave has no instance of this.
940 * In this case, ignore the requested_state
941 * Because, this instance is already met a problem.
946 * Failed to unload this instance.
947 * This is not possible, slave will always return LB_STATUS_ERROR_NOT_EXIST, LB_STATUS_ERROR_INVALID, or 0.
948 * but care this exceptional case.
950 instance_broadcast_deleted_event(inst, ret);
951 instance_state_reset(inst);
952 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
957 inst->changing_state = 0;
958 instance_unref(inst);
961 static void reactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
963 struct inst_info *inst = data;
964 enum lb_type lb_type;
965 enum pd_type pd_type;
974 * instance_reload function will care this.
975 * and it will be called from the slave_activate callback
980 if (packet_get(packet, "issi", &ret, &content, &title, &is_pinned_up) != 4) {
981 ErrPrint("Invalid parameter\n");
985 if (strlen(content)) {
988 tmp = strdup(content);
990 ErrPrint("Heap: %s\n", strerror(errno));
994 DbgFree(inst->content);
1001 tmp = strdup(title);
1003 ErrPrint("Heap: %s\n", strerror(errno));
1007 DbgFree(inst->title);
1011 if (inst->state == INST_DESTROYED) {
1014 * Already destroyed.
1015 * Do nothing at here anymore.
1021 case 0: /*!< normally created */
1022 inst->state = INST_ACTIVATED;
1023 switch (inst->requested_state) {
1024 case INST_DESTROYED:
1025 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1027 case INST_ACTIVATED:
1028 inst->is_pinned_up = is_pinned_up;
1029 lb_type = package_lb_type(inst->info);
1030 pd_type = package_pd_type(inst->info);
1034 * Optimization point.
1035 * In case of the BUFFER type,
1036 * the slave will request the buffer to render its contents.
1037 * so the buffer will be automatcially recreated when it gots the
1038 * buffer request packet.
1039 * so load a buffer from here is not neccessary.
1040 * I should to revise it and concrete the concept.
1041 * Just leave it only for now.
1044 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script) {
1045 script_handler_load(inst->lb.canvas.script, 0);
1046 } else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer) {
1047 buffer_handler_load(inst->lb.canvas.buffer);
1050 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script && inst->pd.is_opened_for_reactivate) {
1054 * We should to send a request to open a PD to slave.
1055 * if we didn't send it, the slave will not recognize the state of a PD.
1056 * We have to keep the view of PD seamless even if the livebox is reactivated.
1057 * To do that, send open request from here.
1059 ret = instance_slave_open_pd(inst, NULL);
1060 instance_slave_get_pd_pos(inst, &x, &y);
1064 * In this case, master already loads the PD script.
1065 * So just send the pd,show event to the slave again.
1067 ret = instance_signal_emit(inst, "pd,show", instance_id(inst), 0.0, 0.0, 0.0, 0.0, x, y, 0);
1068 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer && inst->pd.is_opened_for_reactivate) {
1071 buffer_handler_load(inst->pd.canvas.buffer);
1072 instance_slave_get_pd_pos(inst, &x, &y);
1076 * We should to send a request to open a PD to slave.
1077 * if we didn't send it, the slave will not recognize the state of a PD.
1078 * We have to keep the view of PD seamless even if the livebox is reactivated.
1079 * To do that, send open request from here.
1081 ret = instance_slave_open_pd(inst, NULL);
1085 * In this case, just send the pd,show event for keeping the compatibility
1087 ret = instance_signal_emit(inst, "pd,show", instance_id(inst), 0.0, 0.0, 0.0, 0.0, x, y, 0);
1092 * After create an instance again,
1093 * Send resize request to the livebox.
1094 * instance_resize(inst, inst->lb.width, inst->lb.height);
1096 * renew request will resize the livebox while creating it again
1101 * This function will check the visiblity of a livebox and
1102 * make decision whether it thaw the update timer or not.
1104 instance_recover_visible_state(inst);
1110 instance_broadcast_deleted_event(inst, ret);
1111 instance_state_reset(inst);
1112 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1117 inst->changing_state = 0;
1118 instance_unref(inst);
1121 static void activate_cb(struct slave_node *slave, const struct packet *packet, void *data)
1123 struct inst_info *inst = data;
1135 * instance_reload will care this
1136 * it will be called from the slave_activate callback
1141 if (packet_get(packet, "iiidssi", &ret, &w, &h, &priority, &content, &title, &is_pinned_up) != 7) {
1142 ErrPrint("Invalid parameter\n");
1146 DbgPrint("[%s] returns %d (state: 0x%X)\n", inst->id, ret, inst->state);
1148 if (inst->state == INST_DESTROYED) {
1151 * Already destroyed.
1152 * Do nothing at here anymore.
1158 case 1: /*!< need to create */
1159 if (util_free_space(IMAGE_PATH) > MINIMUM_SPACE) {
1160 struct inst_info *new_inst;
1161 new_inst = instance_create(inst->client, util_timestamp(), package_name(inst->info),
1162 inst->content, inst->cluster, inst->category,
1163 inst->lb.period, 0, 0);
1165 ErrPrint("Failed to create a new instance\n");
1168 ErrPrint("Not enough space\n");
1170 case 0: /*!< normally created */
1173 * Anyway this instance is loaded to the slave,
1174 * just increase the loaded instance counter
1175 * And then reset jobs.
1177 instance_set_lb_size(inst, w, h);
1178 instance_set_lb_info(inst, priority, content, title);
1180 inst->state = INST_ACTIVATED;
1182 switch (inst->requested_state) {
1183 case INST_DESTROYED:
1184 instance_unicast_deleted_event(inst, NULL, ret);
1185 instance_state_reset(inst);
1186 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1188 case INST_ACTIVATED:
1192 * LB should be created at the create time
1194 inst->is_pinned_up = is_pinned_up;
1195 if (package_lb_type(inst->info) == LB_TYPE_SCRIPT) {
1196 if (inst->lb.width == 0 && inst->lb.height == 0) {
1197 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1200 inst->lb.canvas.script = script_handler_create(inst,
1201 package_lb_path(inst->info),
1202 package_lb_group(inst->info),
1203 inst->lb.width, inst->lb.height);
1205 if (!inst->lb.canvas.script) {
1206 ErrPrint("Failed to create LB\n");
1208 script_handler_load(inst->lb.canvas.script, 0);
1210 } else if (package_lb_type(inst->info) == LB_TYPE_BUFFER) {
1211 instance_create_lb_buffer(inst, DEFAULT_PIXELS);
1214 if (package_pd_type(inst->info) == PD_TYPE_SCRIPT) {
1215 if (inst->pd.width == 0 && inst->pd.height == 0) {
1216 instance_set_pd_size(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1219 inst->pd.canvas.script = script_handler_create(inst,
1220 package_pd_path(inst->info),
1221 package_pd_group(inst->info),
1222 inst->pd.width, inst->pd.height);
1224 if (!inst->pd.canvas.script) {
1225 ErrPrint("Failed to create PD\n");
1227 } else if (package_pd_type(inst->info) == PD_TYPE_BUFFER) {
1228 instance_create_pd_buffer(inst, DEFAULT_PIXELS);
1231 instance_broadcast_created_event(inst);
1233 instance_thaw_updator(inst);
1238 instance_unicast_deleted_event(inst, NULL, ret);
1239 instance_state_reset(inst);
1240 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1245 inst->changing_state = 0;
1246 instance_unref(inst);
1249 HAPI int instance_create_pd_buffer(struct inst_info *inst, int pixels)
1251 if (inst->pd.width == 0 && inst->pd.height == 0) {
1252 instance_set_pd_size(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1255 if (!inst->pd.canvas.buffer) {
1256 inst->pd.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->pd.width, inst->pd.height, pixels);
1257 if (!inst->pd.canvas.buffer) {
1258 ErrPrint("Failed to create PD Buffer\n");
1262 return !!inst->pd.canvas.buffer;
1265 HAPI int instance_create_lb_buffer(struct inst_info *inst, int pixels)
1267 if (inst->lb.width == 0 && inst->lb.height == 0) {
1268 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1271 if (!inst->lb.canvas.buffer) {
1274 * Slave doesn't call the acquire_buffer.
1275 * In this case, create the buffer from here.
1277 inst->lb.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->lb.width, inst->lb.height, pixels);
1278 if (!inst->lb.canvas.buffer) {
1279 ErrPrint("Failed to create LB\n");
1283 return !!inst->lb.canvas.buffer;
1286 HAPI int instance_destroy(struct inst_info *inst, enum instance_destroy_type type)
1288 struct packet *packet;
1291 ErrPrint("Invalid instance handle\n");
1292 return LB_STATUS_ERROR_INVALID;
1295 switch (inst->state) {
1296 case INST_REQUEST_TO_ACTIVATE:
1297 case INST_REQUEST_TO_DESTROY:
1298 case INST_REQUEST_TO_REACTIVATE:
1299 inst->requested_state = INST_DESTROYED;
1300 return LB_STATUS_SUCCESS;
1302 inst->state = INST_DESTROYED;
1303 inst->requested_state = INST_DESTROYED;
1304 (void)instance_unref(inst);
1305 return LB_STATUS_SUCCESS;
1306 case INST_DESTROYED:
1307 inst->requested_state = INST_DESTROYED;
1308 return LB_STATUS_SUCCESS;
1313 packet = packet_create("delete", "ssi", package_name(inst->info), inst->id, type);
1315 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1316 return LB_STATUS_ERROR_FAULT;
1319 inst->destroy_type = type;
1320 inst->requested_state = INST_DESTROYED;
1321 inst->state = INST_REQUEST_TO_DESTROY;
1322 inst->changing_state = 1;
1323 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, deactivate_cb, instance_ref(inst), 0);
1326 HAPI int instance_reload(struct inst_info *inst, enum instance_destroy_type type)
1328 struct packet *packet;
1332 ErrPrint("Invalid instance handle\n");
1333 return LB_STATUS_ERROR_INVALID;
1336 DbgPrint("Reload instance (%s)\n", instance_id(inst));
1338 switch (inst->state) {
1339 case INST_REQUEST_TO_ACTIVATE:
1340 case INST_REQUEST_TO_REACTIVATE:
1341 return LB_STATUS_SUCCESS;
1343 ret = instance_activate(inst);
1345 ErrPrint("Failed to activate instance: %d (%s)\n", ret, instance_id(inst));
1347 return LB_STATUS_SUCCESS;
1348 case INST_DESTROYED:
1349 case INST_REQUEST_TO_DESTROY:
1350 DbgPrint("Instance is destroying now\n");
1351 return LB_STATUS_SUCCESS;
1356 packet = packet_create("delete", "ssi", package_name(inst->info), inst->id, type);
1358 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1359 return LB_STATUS_ERROR_FAULT;
1362 inst->destroy_type = type;
1363 inst->requested_state = INST_ACTIVATED;
1364 inst->state = INST_REQUEST_TO_DESTROY;
1365 inst->changing_state = 1;
1366 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, deactivate_cb, instance_ref(inst), 0);
1369 /* Client Deactivated Callback */
1370 static int pd_buffer_close_cb(struct client_node *client, void *inst)
1374 ret = instance_slave_close_pd(inst, client, LB_CLOSE_PD_NORMAL);
1376 DbgPrint("Forcely close the PD ret: %d\n", ret);
1379 instance_unref(inst);
1381 return -1; /* Delete this callback */
1384 /* Client Deactivated Callback */
1385 static int pd_script_close_cb(struct client_node *client, void *inst)
1389 ret = script_handler_unload(instance_pd_script(inst), 1);
1391 DbgPrint("Unload script: %d\n", ret);
1394 ret = instance_slave_close_pd(inst, client, LB_CLOSE_PD_NORMAL);
1396 DbgPrint("Forcely close the PD ret: %d\n", ret);
1399 instance_unref(inst);
1401 return -1; /* Delete this callback */
1404 static inline void release_resource_for_closing_pd(struct pkg_info *info, struct inst_info *inst, struct client_node *client)
1407 client = inst->pd.owner;
1415 * Clean up the resources
1417 if (package_pd_type(info) == PD_TYPE_BUFFER) {
1418 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) == 0) {
1421 * Only if this function succeed to remove the pd_buffer_close_cb,
1422 * Decrease the reference count of this instance
1424 instance_unref(inst);
1426 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
1427 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) == 0) {
1430 * Only if this function succeed to remove the script_close_cb,
1431 * Decrease the reference count of this instance
1433 instance_unref(inst);
1436 ErrPrint("Unknown PD type\n");
1441 HAPI int instance_state_reset(struct inst_info *inst)
1443 enum lb_type lb_type;
1444 enum pd_type pd_type;
1447 ErrPrint("Invalid instance handle\n");
1448 return LB_STATUS_ERROR_INVALID;
1451 if (inst->state == INST_DESTROYED) {
1455 lb_type = package_lb_type(inst->info);
1456 pd_type = package_pd_type(inst->info);
1458 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script) {
1459 script_handler_unload(inst->lb.canvas.script, 0);
1460 } else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer) {
1461 buffer_handler_unload(inst->lb.canvas.buffer);
1464 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script) {
1465 inst->pd.is_opened_for_reactivate = script_handler_is_loaded(inst->pd.canvas.script);
1466 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1467 script_handler_unload(inst->pd.canvas.script, 1);
1468 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer) {
1469 inst->pd.is_opened_for_reactivate = buffer_handler_is_loaded(inst->pd.canvas.buffer);
1470 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1471 buffer_handler_unload(inst->pd.canvas.buffer);
1475 inst->state = INST_INIT;
1476 inst->requested_state = INST_INIT;
1477 return LB_STATUS_SUCCESS;
1480 HAPI int instance_reactivate(struct inst_info *inst)
1482 struct packet *packet;
1486 ErrPrint("Invalid instance handle\n");
1487 return LB_STATUS_ERROR_INVALID;
1490 if (package_is_fault(inst->info)) {
1491 ErrPrint("Fault package [%s]\n", package_name(inst->info));
1492 return LB_STATUS_ERROR_FAULT;
1495 switch (inst->state) {
1496 case INST_REQUEST_TO_DESTROY:
1497 case INST_REQUEST_TO_ACTIVATE:
1498 case INST_REQUEST_TO_REACTIVATE:
1499 inst->requested_state = INST_ACTIVATED;
1500 return LB_STATUS_SUCCESS;
1501 case INST_DESTROYED:
1502 case INST_ACTIVATED:
1503 return LB_STATUS_SUCCESS;
1509 packet = packet_create("renew", "sssiidssiisii",
1510 package_name(inst->info),
1513 package_timeout(inst->info),
1514 !!package_lb_path(inst->info),
1518 inst->lb.width, inst->lb.height,
1519 package_abi(inst->info),
1520 inst->scroll_locked,
1521 inst->active_update);
1523 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1524 return LB_STATUS_ERROR_FAULT;
1527 ret = slave_activate(package_slave(inst->info));
1528 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
1531 * If the master failed to launch the slave,
1532 * Do not send any requests to the slave.
1534 ErrPrint("Failed to launch the slave\n");
1535 packet_destroy(packet);
1539 inst->requested_state = INST_ACTIVATED;
1540 inst->state = INST_REQUEST_TO_REACTIVATE;
1541 inst->changing_state = 1;
1543 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, reactivate_cb, instance_ref(inst), 1);
1546 HAPI int instance_activate(struct inst_info *inst)
1548 struct packet *packet;
1552 ErrPrint("Invalid instance handle\n");
1553 return LB_STATUS_ERROR_INVALID;
1556 if (package_is_fault(inst->info)) {
1557 ErrPrint("Fault package [%s]\n", package_name(inst->info));
1558 return LB_STATUS_ERROR_FAULT;
1561 switch (inst->state) {
1562 case INST_REQUEST_TO_REACTIVATE:
1563 case INST_REQUEST_TO_ACTIVATE:
1564 case INST_REQUEST_TO_DESTROY:
1565 inst->requested_state = INST_ACTIVATED;
1566 return LB_STATUS_SUCCESS;
1567 case INST_ACTIVATED:
1568 case INST_DESTROYED:
1569 return LB_STATUS_SUCCESS;
1575 packet = packet_create("new", "sssiidssisii",
1576 package_name(inst->info),
1579 package_timeout(inst->info),
1580 !!package_lb_path(inst->info),
1585 package_abi(inst->info),
1589 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1590 return LB_STATUS_ERROR_FAULT;
1593 ret = slave_activate(package_slave(inst->info));
1594 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
1597 * If the master failed to launch the slave,
1598 * Do not send any requests to the slave.
1600 ErrPrint("Failed to launch the slave\n");
1601 packet_destroy(packet);
1605 inst->state = INST_REQUEST_TO_ACTIVATE;
1606 inst->requested_state = INST_ACTIVATED;
1607 inst->changing_state = 1;
1611 * Try to activate a slave if it is not activated
1613 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, activate_cb, instance_ref(inst), 1);
1616 HAPI int instance_lb_update_begin(struct inst_info *inst, double priority, const char *content, const char *title)
1618 struct packet *packet;
1621 if (!inst->active_update) {
1622 ErrPrint("Invalid request [%s]\n", inst->id);
1623 return LB_STATUS_ERROR_INVALID;
1626 switch (package_lb_type(inst->info)) {
1627 case LB_TYPE_BUFFER:
1628 if (!inst->lb.canvas.buffer) {
1629 ErrPrint("Buffer is null [%s]\n", inst->id);
1630 return LB_STATUS_ERROR_INVALID;
1632 fbfile = buffer_handler_id(inst->lb.canvas.buffer);
1634 case LB_TYPE_SCRIPT:
1635 if (!inst->lb.canvas.script) {
1636 ErrPrint("Script is null [%s]\n", inst->id);
1637 return LB_STATUS_ERROR_INVALID;
1639 fbfile = script_handler_buffer_id(inst->lb.canvas.script);
1642 ErrPrint("Invalid request[%s]\n", inst->id);
1643 return LB_STATUS_ERROR_INVALID;
1646 packet = packet_create_noack("lb_update_begin", "ssdsss", package_name(inst->info), inst->id, priority, content, title, fbfile);
1648 ErrPrint("Unable to create a packet\n");
1649 return LB_STATUS_ERROR_FAULT;
1652 return CLIENT_SEND_EVENT(inst, packet);
1655 HAPI int instance_lb_update_end(struct inst_info *inst)
1657 struct packet *packet;
1659 if (!inst->active_update) {
1660 ErrPrint("Invalid request [%s]\n", inst->id);
1661 return LB_STATUS_ERROR_INVALID;
1664 switch (package_lb_type(inst->info)) {
1665 case LB_TYPE_BUFFER:
1666 if (!inst->lb.canvas.buffer) {
1667 ErrPrint("Buffer is null [%s]\n", inst->id);
1668 return LB_STATUS_ERROR_INVALID;
1671 case LB_TYPE_SCRIPT:
1672 if (!inst->lb.canvas.script) {
1673 ErrPrint("Script is null [%s]\n", inst->id);
1674 return LB_STATUS_ERROR_INVALID;
1678 ErrPrint("Invalid request[%s]\n", inst->id);
1679 return LB_STATUS_ERROR_INVALID;
1682 packet = packet_create_noack("lb_update_end", "ss", package_name(inst->info), inst->id);
1684 ErrPrint("Unable to create a packet\n");
1685 return LB_STATUS_ERROR_FAULT;
1688 return CLIENT_SEND_EVENT(inst, packet);
1691 HAPI int instance_pd_update_begin(struct inst_info *inst)
1693 struct packet *packet;
1696 if (!inst->active_update) {
1697 ErrPrint("Invalid request [%s]\n", inst->id);
1698 return LB_STATUS_ERROR_INVALID;
1701 switch (package_pd_type(inst->info)) {
1702 case PD_TYPE_BUFFER:
1703 if (!inst->pd.canvas.buffer) {
1704 ErrPrint("Buffer is null [%s]\n", inst->id);
1705 return LB_STATUS_ERROR_INVALID;
1707 fbfile = buffer_handler_id(inst->pd.canvas.buffer);
1709 case PD_TYPE_SCRIPT:
1710 if (!inst->pd.canvas.script) {
1711 ErrPrint("Script is null [%s]\n", inst->id);
1712 return LB_STATUS_ERROR_INVALID;
1714 fbfile = script_handler_buffer_id(inst->pd.canvas.script);
1717 ErrPrint("Invalid request[%s]\n", inst->id);
1718 return LB_STATUS_ERROR_INVALID;
1721 packet = packet_create_noack("pd_update_begin", "sss", package_name(inst->info), inst->id, fbfile);
1723 ErrPrint("Unable to create a packet\n");
1724 return LB_STATUS_ERROR_FAULT;
1727 return CLIENT_SEND_EVENT(inst, packet);
1730 HAPI int instance_pd_update_end(struct inst_info *inst)
1732 struct packet *packet;
1734 if (!inst->active_update) {
1735 ErrPrint("Invalid request [%s]\n", inst->id);
1736 return LB_STATUS_ERROR_INVALID;
1739 switch (package_pd_type(inst->info)) {
1740 case PD_TYPE_BUFFER:
1741 if (!inst->pd.canvas.buffer) {
1742 ErrPrint("Buffer is null [%s]\n", inst->id);
1743 return LB_STATUS_ERROR_INVALID;
1746 case PD_TYPE_SCRIPT:
1747 if (!inst->pd.canvas.script) {
1748 ErrPrint("Script is null [%s]\n", inst->id);
1749 return LB_STATUS_ERROR_INVALID;
1753 ErrPrint("Invalid request[%s]\n", inst->id);
1754 return LB_STATUS_ERROR_INVALID;
1757 packet = packet_create_noack("pd_update_end", "ss", package_name(inst->info), inst->id);
1759 ErrPrint("Unable to create a packet\n");
1760 return LB_STATUS_ERROR_FAULT;
1763 return CLIENT_SEND_EVENT(inst, packet);
1766 HAPI void instance_lb_updated_by_instance(struct inst_info *inst, const char *safe_file)
1768 struct packet *packet;
1770 enum lb_type lb_type;
1772 const char *content;
1776 if (inst->client && inst->visible != LB_SHOW) {
1777 if (inst->visible == LB_HIDE) {
1778 DbgPrint("Ignore update event %s(HIDE)\n", inst->id);
1781 DbgPrint("Livebox(%s) is PAUSED. But content is updated.\n", inst->id);
1784 lb_type = package_lb_type(inst->info);
1785 if (lb_type == LB_TYPE_SCRIPT) {
1786 id = script_handler_buffer_id(inst->lb.canvas.script);
1787 } else if (lb_type == LB_TYPE_BUFFER) {
1788 id = buffer_handler_id(inst->lb.canvas.buffer);
1793 if (inst->content) {
1794 content = inst->content;
1800 title = inst->title;
1817 packet = packet_create_noack("lb_updated", "sssiidsssss",
1818 package_name(inst->info), inst->id, id,
1819 inst->lb.width, inst->lb.height, inst->lb.priority, content, title, safe_file, icon, name);
1821 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1825 (void)CLIENT_SEND_EVENT(inst, packet);
1828 HAPI int instance_hold_scroll(struct inst_info *inst, int hold)
1830 struct packet *packet;
1832 DbgPrint("HOLD: (%s) %d\n", inst->id, hold);
1833 if (inst->scroll_locked == hold) {
1834 return LB_STATUS_ERROR_ALREADY;
1837 packet = packet_create_noack("scroll", "ssi", package_name(inst->info), inst->id, hold);
1839 ErrPrint("Failed to build a packet\n");
1840 return LB_STATUS_ERROR_FAULT;
1843 inst->scroll_locked = hold;
1844 return CLIENT_SEND_EVENT(inst, packet);
1847 HAPI void instance_pd_updated_by_instance(struct inst_info *inst, const char *descfile)
1849 struct packet *packet;
1852 if (inst->client && inst->visible != LB_SHOW) {
1853 DbgPrint("Livebox is hidden. ignore update event\n");
1857 if (!inst->pd.need_to_send_close_event) {
1858 DbgPrint("PD is not created yet. Ignore update event - %s\n", descfile);
1860 if (inst->pd.pended_update_desc) {
1861 DbgFree(inst->pd.pended_update_desc);
1862 inst->pd.pended_update_desc = NULL;
1866 inst->pd.pended_update_desc = strdup(descfile);
1867 if (!inst->pd.pended_update_desc) {
1868 ErrPrint("Heap: %s\n", strerror(errno));
1872 inst->pd.pended_update_cnt++;
1877 descfile = inst->id;
1880 switch (package_pd_type(inst->info)) {
1881 case PD_TYPE_SCRIPT:
1882 id = script_handler_buffer_id(inst->pd.canvas.script);
1884 case PD_TYPE_BUFFER:
1885 id = buffer_handler_id(inst->pd.canvas.buffer);
1893 packet = packet_create_noack("pd_updated", "ssssii",
1894 package_name(inst->info), inst->id, descfile, id,
1895 inst->pd.width, inst->pd.height);
1897 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1901 (void)CLIENT_SEND_EVENT(inst, packet);
1904 HAPI void instance_pd_updated(const char *pkgname, const char *id, const char *descfile)
1906 struct inst_info *inst;
1908 inst = package_find_instance_by_id(pkgname, id);
1913 instance_pd_updated_by_instance(inst, descfile);
1916 HAPI int instance_set_update_mode(struct inst_info *inst, int active_update)
1918 struct packet *packet;
1919 struct update_mode_cbdata *cbdata;
1921 if (package_is_fault(inst->info)) {
1922 ErrPrint("Fault package [%s]\n", package_name(inst->info));
1923 return LB_STATUS_ERROR_FAULT;
1926 if (inst->active_update == active_update) {
1927 DbgPrint("Active update is not changed: %d\n", inst->active_update);
1928 return LB_STATUS_ERROR_ALREADY;
1931 cbdata = malloc(sizeof(*cbdata));
1933 ErrPrint("Heap: %s\n", strerror(errno));
1934 return LB_STATUS_ERROR_MEMORY;
1937 cbdata->inst = instance_ref(inst);
1938 cbdata->active_update = active_update;
1940 /* NOTE: param is resued from here */
1941 packet = packet_create("update_mode", "ssi", package_name(inst->info), inst->id, active_update);
1943 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1944 instance_unref(cbdata->inst);
1946 return LB_STATUS_ERROR_FAULT;
1949 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, update_mode_cb, cbdata, 0);
1952 HAPI int instance_active_update(struct inst_info *inst)
1954 return inst->active_update;
1957 HAPI void instance_set_lb_info(struct inst_info *inst, double priority, const char *content, const char *title)
1959 char *_content = NULL;
1960 char *_title = NULL;
1962 if (content && strlen(content)) {
1963 _content = strdup(content);
1965 ErrPrint("Heap: %s\n", strerror(errno));
1969 if (title && strlen(title)) {
1970 _title = strdup(title);
1972 ErrPrint("Heap: %s\n", strerror(errno));
1977 DbgFree(inst->content);
1978 inst->content= _content;
1982 DbgFree(inst->title);
1983 inst->title = _title;
1986 if (priority >= 0.0f && priority <= 1.0f) {
1987 inst->lb.priority = priority;
1991 HAPI void instance_set_alt_info(struct inst_info *inst, const char *icon, const char *name)
1996 if (icon && strlen(icon)) {
1997 _icon = strdup(icon);
1999 ErrPrint("Heap: %s\n", strerror(errno));
2003 if (name && strlen(name)) {
2004 _name = strdup(name);
2006 ErrPrint("Heap: %s\n", strerror(errno));
2011 DbgFree(inst->icon);
2016 DbgFree(inst->name);
2021 HAPI void instance_set_lb_size(struct inst_info *inst, int w, int h)
2023 if (inst->lb.width != w || inst->lb.height != h) {
2024 instance_send_resized_event(inst, IS_LB, w, h, LB_STATUS_SUCCESS);
2028 inst->lb.height = h;
2031 HAPI void instance_set_pd_size(struct inst_info *inst, int w, int h)
2033 if (inst->pd.width != w || inst->pd.height != h) {
2034 instance_send_resized_event(inst, IS_PD, w, h, LB_STATUS_SUCCESS);
2038 inst->pd.height = h;
2041 static void pinup_cb(struct slave_node *slave, const struct packet *packet, void *data)
2043 struct set_pinup_cbdata *cbdata = data;
2044 const char *content;
2045 struct packet *result;
2051 * Send pinup failed event to client.
2053 ret = LB_STATUS_ERROR_INVALID;
2057 if (packet_get(packet, "is", &ret, &content) != 2) {
2060 * Send pinup failed event to client
2062 ret = LB_STATUS_ERROR_INVALID;
2069 new_content = strdup(content);
2071 ErrPrint("Heap: %s\n", strerror(errno));
2074 * send pinup failed event to client
2076 ret = LB_STATUS_ERROR_MEMORY;
2080 cbdata->inst->is_pinned_up = cbdata->pinup;
2081 DbgFree(cbdata->inst->content);
2083 cbdata->inst->content = new_content;
2089 * Send PINUP Result to client.
2090 * Client should wait this event.
2092 result = packet_create_noack("pinup", "iisss", ret, cbdata->inst->is_pinned_up,
2093 package_name(cbdata->inst->info), cbdata->inst->id, cbdata->inst->content);
2095 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2097 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
2100 instance_unref(cbdata->inst);
2104 HAPI int instance_set_pinup(struct inst_info *inst, int pinup)
2106 struct set_pinup_cbdata *cbdata;
2107 struct packet *packet;
2110 ErrPrint("Invalid instance handle\n");
2111 return LB_STATUS_ERROR_INVALID;
2114 if (package_is_fault(inst->info)) {
2115 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2116 return LB_STATUS_ERROR_FAULT;
2119 if (!package_pinup(inst->info)) {
2120 return LB_STATUS_ERROR_INVALID;
2123 if (pinup == inst->is_pinned_up) {
2124 return LB_STATUS_ERROR_INVALID;
2127 cbdata = malloc(sizeof(*cbdata));
2129 return LB_STATUS_ERROR_MEMORY;
2132 cbdata->inst = instance_ref(inst);
2133 cbdata->pinup = pinup;
2135 packet = packet_create("pinup", "ssi", package_name(inst->info), inst->id, pinup);
2137 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2138 instance_unref(cbdata->inst);
2140 return LB_STATUS_ERROR_FAULT;
2143 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, pinup_cb, cbdata, 0);
2146 HAPI int instance_freeze_updator(struct inst_info *inst)
2148 if (!inst->update_timer) {
2149 return LB_STATUS_ERROR_INVALID;
2153 return LB_STATUS_SUCCESS;
2156 HAPI int instance_thaw_updator(struct inst_info *inst)
2158 if (!inst->update_timer) {
2159 return LB_STATUS_ERROR_INVALID;
2162 if (client_is_all_paused() || setting_is_lcd_off()) {
2163 return LB_STATUS_ERROR_INVALID;
2166 if (inst->visible == LB_HIDE_WITH_PAUSE) {
2167 return LB_STATUS_ERROR_INVALID;
2171 return LB_STATUS_SUCCESS;
2174 HAPI enum livebox_visible_state instance_visible_state(struct inst_info *inst)
2176 return inst->visible;
2179 HAPI int instance_set_visible_state(struct inst_info *inst, enum livebox_visible_state state)
2181 if (inst->visible == state) {
2182 return LB_STATUS_SUCCESS;
2188 if (inst->visible == LB_HIDE_WITH_PAUSE) {
2189 if (resume_livebox(inst) == 0) {
2190 inst->visible = state;
2193 instance_thaw_updator(inst);
2195 inst->visible = state;
2199 case LB_HIDE_WITH_PAUSE:
2200 if (pause_livebox(inst) == 0) {
2201 inst->visible = LB_HIDE_WITH_PAUSE;
2204 instance_freeze_updator(inst);
2208 return LB_STATUS_ERROR_INVALID;
2211 return LB_STATUS_SUCCESS;
2214 static void resize_cb(struct slave_node *slave, const struct packet *packet, void *data)
2216 struct resize_cbdata *cbdata = data;
2220 ErrPrint("RESIZE: Invalid packet\n");
2221 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_FAULT);
2222 instance_unref(cbdata->inst);
2227 if (packet_get(packet, "i", &ret) != 1) {
2228 ErrPrint("RESIZE: Invalid parameter\n");
2229 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_INVALID);
2230 instance_unref(cbdata->inst);
2235 if (ret == (int)LB_STATUS_SUCCESS) {
2238 * else waiting the first update with new size
2240 if (cbdata->inst->lb.width == cbdata->w && cbdata->inst->lb.height == cbdata->h) {
2243 * Right after the viewer adds a new box,
2244 * Box has no size information, then it will try to use the default size,
2245 * After a box returns created event.
2247 * A box will start to generate default size content.
2248 * But the viewer doesn't know it,.
2250 * So the viewer will try to change the size of a box.
2252 * At that time, the provider gots the size changed event from the box.
2253 * So it sent the size changed event to the viewer.
2254 * But the viewer ignores it. if it doesn't care the size changed event.
2255 * (even if it cares the size changed event, there is a timing issue)
2257 * And the provider receives resize request,
2258 * right before send the size changed event.
2259 * but there is no changes about the size.
2261 * Now the view will waits size changed event forever.
2262 * To resolve this timing issue.
2264 * Check the size of a box from here.
2265 * And if the size is already updated, send the ALREADY event to the viewer
2266 * to get the size changed event callback correctly.
2268 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_ALREADY);
2269 DbgPrint("RESIZE: Livebox is already resized [%s - %dx%d]\n", instance_id(cbdata->inst), cbdata->w, cbdata->h);
2271 DbgPrint("RESIZE: Request is successfully sent [%s - %dx%d]\n", instance_id(cbdata->inst), cbdata->w, cbdata->h);
2274 DbgPrint("RESIZE: Livebox rejects the new size: %s - %dx%d (%d)\n", instance_id(cbdata->inst), cbdata->w, cbdata->h, ret);
2275 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, ret);
2278 instance_unref(cbdata->inst);
2282 HAPI int instance_resize(struct inst_info *inst, int w, int h)
2284 struct resize_cbdata *cbdata;
2285 struct packet *packet;
2289 ErrPrint("Invalid instance handle\n");
2290 return LB_STATUS_ERROR_INVALID;
2293 if (package_is_fault(inst->info)) {
2294 ErrPrint("Fault package: %s\n", package_name(inst->info));
2295 return LB_STATUS_ERROR_FAULT;
2298 cbdata = malloc(sizeof(*cbdata));
2300 ErrPrint("Heap: %s\n", strerror(errno));
2301 return LB_STATUS_ERROR_MEMORY;
2304 cbdata->inst = instance_ref(inst);
2308 /* NOTE: param is resued from here */
2309 packet = packet_create("resize", "ssii", package_name(inst->info), inst->id, w, h);
2311 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2312 instance_unref(cbdata->inst);
2314 return LB_STATUS_ERROR_FAULT;
2317 DbgPrint("RESIZE: [%s] resize[%dx%d]\n", instance_id(inst), w, h);
2318 ret = slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, resize_cb, cbdata, 0);
2322 static void set_period_cb(struct slave_node *slave, const struct packet *packet, void *data)
2325 struct period_cbdata *cbdata = data;
2326 struct packet *result;
2329 ret = LB_STATUS_ERROR_FAULT;
2333 if (packet_get(packet, "i", &ret) != 1) {
2334 ret = LB_STATUS_ERROR_INVALID;
2339 cbdata->inst->lb.period = cbdata->period;
2341 ErrPrint("Failed to set period %d\n", ret);
2345 result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->lb.period, package_name(cbdata->inst->info), cbdata->inst->id);
2347 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2349 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
2352 instance_unref(cbdata->inst);
2357 static Eina_Bool timer_updator_cb(void *data)
2359 struct period_cbdata *cbdata = data;
2360 struct inst_info *inst;
2362 struct packet *result;
2364 period = cbdata->period;
2365 inst = cbdata->inst;
2368 inst->lb.period = period;
2369 if (inst->update_timer) {
2370 if (inst->lb.period == 0.0f) {
2371 ecore_timer_del(inst->update_timer);
2372 inst->update_timer = NULL;
2374 util_timer_interval_set(inst->update_timer, inst->lb.period);
2376 } else if (inst->lb.period > 0.0f) {
2377 inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
2378 if (!inst->update_timer) {
2379 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
2381 timer_freeze(inst); /* Freeze the update timer as default */
2385 result = packet_create_noack("period_changed", "idss", 0, inst->lb.period, package_name(inst->info), inst->id);
2387 (void)CLIENT_SEND_EVENT(inst, result);
2389 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2392 instance_unref(inst);
2393 return ECORE_CALLBACK_CANCEL;
2396 HAPI void instance_reload_period(struct inst_info *inst, double period)
2398 inst->lb.period = period;
2401 HAPI int instance_set_period(struct inst_info *inst, double period)
2403 struct packet *packet;
2404 struct period_cbdata *cbdata;
2407 ErrPrint("Invalid instance handle\n");
2408 return LB_STATUS_ERROR_INVALID;
2411 if (package_is_fault(inst->info)) {
2412 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2413 return LB_STATUS_ERROR_FAULT;
2416 if (period < 0.0f) { /* Use the default period */
2417 period = package_period(inst->info);
2418 } else if (period > 0.0f && period < MINIMUM_PERIOD) {
2419 period = MINIMUM_PERIOD; /* defined at conf.h */
2422 cbdata = malloc(sizeof(*cbdata));
2424 ErrPrint("Heap: %s\n", strerror(errno));
2425 return LB_STATUS_ERROR_MEMORY;
2428 cbdata->period = period;
2429 cbdata->inst = instance_ref(inst);
2431 if (package_secured(inst->info)) {
2434 * Secured livebox doesn't need to send its update period to the slave.
2435 * Slave has no local timer for updating liveboxes
2437 * So update its timer at here.
2439 if (!ecore_timer_add(DELAY_TIME, timer_updator_cb, cbdata)) {
2440 timer_updator_cb(cbdata);
2442 return LB_STATUS_SUCCESS;
2445 packet = packet_create("set_period", "ssd", package_name(inst->info), inst->id, period);
2447 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2448 instance_unref(cbdata->inst);
2450 return LB_STATUS_ERROR_FAULT;
2453 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, set_period_cb, cbdata, 0);
2456 HAPI int instance_clicked(struct inst_info *inst, const char *event, double timestamp, double x, double y)
2458 struct packet *packet;
2461 ErrPrint("Invalid instance handle\n");
2462 return LB_STATUS_ERROR_INVALID;
2465 if (package_is_fault(inst->info)) {
2466 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2467 return LB_STATUS_ERROR_FAULT;
2470 /* NOTE: param is resued from here */
2471 packet = packet_create_noack("clicked", "sssddd", package_name(inst->info), inst->id, event, timestamp, x, y);
2473 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2474 return LB_STATUS_ERROR_FAULT;
2477 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
2480 HAPI int instance_signal_emit(struct inst_info *inst, const char *signal, const char *part, double sx, double sy, double ex, double ey, double x, double y, int down)
2482 const char *pkgname;
2484 struct slave_node *slave;
2485 struct packet *packet;
2486 struct pkg_info *pkg;
2488 pkg = instance_package(inst);
2489 pkgname = package_name(pkg);
2490 id = instance_id(inst);
2491 if (!pkgname || !id) {
2492 return LB_STATUS_ERROR_INVALID;
2495 slave = package_slave(pkg);
2497 return LB_STATUS_ERROR_INVALID;
2500 packet = packet_create_noack("script", "ssssddddddi",
2506 return LB_STATUS_ERROR_FAULT;
2509 return slave_rpc_request_only(slave, pkgname, packet, 0);
2512 HAPI int instance_text_signal_emit(struct inst_info *inst, const char *emission, const char *source, double sx, double sy, double ex, double ey)
2514 struct packet *packet;
2517 ErrPrint("Invalid instance handle\n");
2518 return LB_STATUS_ERROR_INVALID;
2521 if (package_is_fault(inst->info)) {
2522 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2523 return LB_STATUS_ERROR_FAULT;
2526 packet = packet_create_noack("text_signal", "ssssdddd", package_name(inst->info), inst->id, emission, source, sx, sy, ex, ey);
2528 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2529 return LB_STATUS_ERROR_FAULT;
2532 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
2535 static void change_group_cb(struct slave_node *slave, const struct packet *packet, void *data)
2537 struct change_group_cbdata *cbdata = data;
2538 struct packet *result;
2542 DbgFree(cbdata->cluster);
2543 DbgFree(cbdata->category);
2544 ret = LB_STATUS_ERROR_FAULT;
2548 if (packet_get(packet, "i", &ret) != 1) {
2549 ErrPrint("Invalid packet\n");
2550 DbgFree(cbdata->cluster);
2551 DbgFree(cbdata->category);
2552 ret = LB_STATUS_ERROR_INVALID;
2557 DbgFree(cbdata->inst->cluster);
2558 cbdata->inst->cluster = cbdata->cluster;
2560 DbgFree(cbdata->inst->category);
2561 cbdata->inst->category = cbdata->category;
2563 DbgFree(cbdata->cluster);
2564 DbgFree(cbdata->category);
2568 result = packet_create_noack("group_changed", "ssiss",
2569 package_name(cbdata->inst->info), cbdata->inst->id, ret,
2570 cbdata->inst->cluster, cbdata->inst->category);
2572 ErrPrint("Failed to build a packet %s\n", package_name(cbdata->inst->info));
2574 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2577 instance_unref(cbdata->inst);
2581 HAPI int instance_change_group(struct inst_info *inst, const char *cluster, const char *category)
2583 struct packet *packet;
2584 struct change_group_cbdata *cbdata;
2587 ErrPrint("Invalid instance handle\n");
2588 return LB_STATUS_ERROR_INVALID;
2591 if (package_is_fault(inst->info)) {
2592 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2593 return LB_STATUS_ERROR_FAULT;
2596 cbdata = malloc(sizeof(*cbdata));
2598 ErrPrint("Heap: %s\n", strerror(errno));
2599 return LB_STATUS_ERROR_MEMORY;
2602 cbdata->cluster = strdup(cluster);
2603 if (!cbdata->cluster) {
2604 ErrPrint("Heap: %s\n", strerror(errno));
2606 return LB_STATUS_ERROR_MEMORY;
2609 cbdata->category = strdup(category);
2610 if (!cbdata->category) {
2611 ErrPrint("Heap: %s\n", strerror(errno));
2612 DbgFree(cbdata->cluster);
2614 return LB_STATUS_ERROR_MEMORY;
2617 cbdata->inst = instance_ref(inst);
2619 packet = packet_create("change_group","ssss", package_name(inst->info), inst->id, cluster, category);
2621 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2622 instance_unref(cbdata->inst);
2623 DbgFree(cbdata->category);
2624 DbgFree(cbdata->cluster);
2626 return LB_STATUS_ERROR_FAULT;
2629 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, change_group_cb, cbdata, 0);
2632 HAPI const char * const instance_auto_launch(const struct inst_info *inst)
2634 return package_auto_launch(inst->info);
2637 HAPI const int const instance_priority(const struct inst_info *inst)
2639 return inst->lb.priority;
2642 HAPI const struct client_node *const instance_client(const struct inst_info *inst)
2644 return inst->client;
2647 HAPI const int const instance_timeout(const struct inst_info *inst)
2649 return package_timeout(inst->info);
2652 HAPI const double const instance_period(const struct inst_info *inst)
2654 return inst->lb.period;
2657 HAPI const int const instance_lb_width(const struct inst_info *inst)
2659 return inst->lb.width;
2662 HAPI const int const instance_lb_height(const struct inst_info *inst)
2664 return inst->lb.height;
2667 HAPI const int const instance_pd_width(const struct inst_info *inst)
2669 return inst->pd.width;
2672 HAPI const int const instance_pd_height(const struct inst_info *inst)
2674 return inst->pd.height;
2677 HAPI struct pkg_info *const instance_package(const struct inst_info *inst)
2682 HAPI struct script_info *const instance_lb_script(const struct inst_info *inst)
2684 return (package_lb_type(inst->info) == LB_TYPE_SCRIPT) ? inst->lb.canvas.script : NULL;
2687 HAPI struct script_info *const instance_pd_script(const struct inst_info *inst)
2689 return (package_pd_type(inst->info) == PD_TYPE_SCRIPT) ? inst->pd.canvas.script : NULL;
2692 HAPI struct buffer_info *const instance_lb_buffer(const struct inst_info *inst)
2694 return (package_lb_type(inst->info) == LB_TYPE_BUFFER) ? inst->lb.canvas.buffer : NULL;
2697 HAPI struct buffer_info *const instance_pd_buffer(const struct inst_info *inst)
2699 return (package_pd_type(inst->info) == PD_TYPE_BUFFER) ? inst->pd.canvas.buffer : NULL;
2702 HAPI const char *const instance_id(const struct inst_info *inst)
2707 HAPI const char *const instance_content(const struct inst_info *inst)
2709 return inst->content;
2712 HAPI const char *const instance_category(const struct inst_info *inst)
2714 return inst->category;
2717 HAPI const char *const instance_cluster(const struct inst_info *inst)
2719 return inst->cluster;
2722 HAPI const char * const instance_title(const struct inst_info *inst)
2727 HAPI const double const instance_timestamp(const struct inst_info *inst)
2729 return inst->timestamp;
2732 HAPI const enum instance_state const instance_state(const struct inst_info *inst)
2737 HAPI int instance_destroyed(struct inst_info *inst, int reason)
2739 switch (inst->state) {
2741 case INST_REQUEST_TO_ACTIVATE:
2744 * No other clients know the existence of this instance,
2745 * only who added this knows it.
2746 * So send deleted event to only it.
2748 DbgPrint("Send deleted event - unicast - %p\n", inst->client);
2749 instance_unicast_deleted_event(inst, NULL, reason);
2750 instance_state_reset(inst);
2751 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2753 case INST_REQUEST_TO_REACTIVATE:
2754 case INST_REQUEST_TO_DESTROY:
2755 case INST_ACTIVATED:
2756 DbgPrint("Send deleted event - multicast\n");
2757 instance_broadcast_deleted_event(inst, reason);
2758 instance_state_reset(inst);
2759 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2760 case INST_DESTROYED:
2763 return LB_STATUS_ERROR_INVALID;
2766 return LB_STATUS_SUCCESS;
2770 * Invoked when a slave is activated
2772 HAPI int instance_recover_state(struct inst_info *inst)
2776 if (inst->changing_state) {
2777 DbgPrint("Doesn't need to recover the state\n");
2778 return LB_STATUS_SUCCESS;
2781 if (package_is_fault(inst->info)) {
2782 ErrPrint("Package is faulted(%s), Delete it\n", inst->id);
2783 inst->requested_state = INST_DESTROYED;
2786 switch (inst->state) {
2787 case INST_ACTIVATED:
2788 case INST_REQUEST_TO_REACTIVATE:
2789 case INST_REQUEST_TO_DESTROY:
2790 switch (inst->requested_state) {
2791 case INST_ACTIVATED:
2792 DbgPrint("Req. to RE-ACTIVATED (%s)\n", package_name(inst->info));
2793 instance_state_reset(inst);
2794 instance_reactivate(inst);
2797 case INST_DESTROYED:
2798 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2799 instance_state_reset(inst);
2800 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2807 case INST_REQUEST_TO_ACTIVATE:
2808 switch (inst->requested_state) {
2809 case INST_ACTIVATED:
2811 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2812 instance_state_reset(inst);
2813 if (instance_activate(inst) < 0) {
2814 DbgPrint("Failed to reactivate the instance\n");
2815 instance_broadcast_deleted_event(inst, LB_STATUS_ERROR_FAULT);
2816 instance_state_reset(inst);
2817 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2822 case INST_DESTROYED:
2823 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2824 instance_state_reset(inst);
2825 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2831 case INST_DESTROYED:
2840 * Invoked when a slave is deactivated
2842 HAPI int instance_need_slave(struct inst_info *inst)
2846 if (inst->client && client_is_faulted(inst->client)) {
2849 * In this case, the client is faulted(disconnected)
2850 * when the client is deactivated, its liveboxes should be removed too.
2851 * So if the current inst is created by the faulted client,
2852 * remove it and don't try to recover its states
2855 DbgPrint("CLIENT FAULT: Req. to DESTROYED (%s)\n", package_name(inst->info));
2856 switch (inst->state) {
2858 case INST_ACTIVATED:
2859 case INST_REQUEST_TO_REACTIVATE:
2860 case INST_REQUEST_TO_DESTROY:
2861 case INST_REQUEST_TO_ACTIVATE:
2862 instance_state_reset(inst);
2863 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2865 case INST_DESTROYED:
2869 return LB_STATUS_SUCCESS;
2872 switch (inst->state) {
2873 case INST_ACTIVATED:
2874 case INST_REQUEST_TO_REACTIVATE:
2875 case INST_REQUEST_TO_DESTROY:
2876 switch (inst->requested_state) {
2878 case INST_ACTIVATED:
2879 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2882 case INST_DESTROYED:
2883 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2884 instance_state_reset(inst);
2885 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2892 case INST_REQUEST_TO_ACTIVATE:
2893 switch (inst->requested_state) {
2895 case INST_ACTIVATED:
2896 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2899 case INST_DESTROYED:
2900 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2901 instance_state_reset(inst);
2902 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2908 case INST_DESTROYED:
2916 HAPI int instance_forward_packet(struct inst_info *inst, struct packet *packet)
2918 return CLIENT_SEND_EVENT(inst, packet);
2921 HAPI int instance_send_key_status(struct inst_info *inst, int status)
2923 struct packet *packet;
2925 packet = packet_create_noack("key_status", "ssi", package_name(inst->info), inst->id, status);
2927 ErrPrint("Failed to build a packet\n");
2928 return LB_STATUS_ERROR_FAULT;
2931 return CLIENT_SEND_EVENT(inst, packet);
2934 HAPI int instance_send_access_status(struct inst_info *inst, int status)
2936 struct packet *packet;
2938 packet = packet_create_noack("access_status", "ssi", package_name(inst->info), inst->id, status);
2940 ErrPrint("Failed to build a packet\n");
2941 return LB_STATUS_ERROR_FAULT;
2944 return CLIENT_SEND_EVENT(inst, packet);
2947 HAPI void instance_slave_set_pd_pos(struct inst_info *inst, double x, double y)
2953 HAPI void instance_slave_get_pd_pos(struct inst_info *inst, double *x, double *y)
2964 HAPI int instance_slave_open_pd(struct inst_info *inst, struct client_node *client)
2966 const char *pkgname;
2968 struct packet *packet;
2969 struct slave_node *slave;
2970 const struct pkg_info *info;
2974 client = inst->pd.owner;
2976 ErrPrint("Client is not valid\n");
2977 return LB_STATUS_ERROR_INVALID;
2979 } else if (inst->pd.owner) {
2980 if (inst->pd.owner != client) {
2981 ErrPrint("Client is already owned\n");
2982 return LB_STATUS_ERROR_ALREADY;
2986 info = instance_package(inst);
2988 ErrPrint("No package info\n");
2989 return LB_STATUS_ERROR_INVALID;
2992 slave = package_slave(info);
2994 ErrPrint("No slave\n");
2995 return LB_STATUS_ERROR_FAULT;
2998 pkgname = package_name(info);
2999 id = instance_id(inst);
3001 if (!pkgname || !id) {
3002 ErrPrint("pkgname[%s] id[%s]\n", pkgname, id);
3003 return LB_STATUS_ERROR_INVALID;
3006 packet = packet_create_noack("pd_show", "ssiidd", pkgname, id, instance_pd_width(inst), instance_pd_height(inst), inst->pd.x, inst->pd.y);
3008 ErrPrint("Failed to create a packet\n");
3009 return LB_STATUS_ERROR_FAULT;
3014 * Do not return from here even though we failed to freeze the TTL timer.
3015 * Because the TTL timer is not able to be exists.
3016 * So we can ignore this error.
3018 (void)slave_freeze_ttl(slave);
3020 DbgPrint("PERF_DBOX\n");
3021 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
3023 ErrPrint("Unable to send request to slave\n");
3026 * Also we can ignore the TTL timer at here too ;)
3028 (void)slave_thaw_ttl(slave);
3034 * If a client is disconnected, the slave has to close the PD
3035 * So the pd_buffer_close_cb/pd_script_close_cb will catch the disconnection event
3036 * then it will send the close request to the slave
3038 if (package_pd_type(info) == PD_TYPE_BUFFER) {
3040 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) < 0) {
3041 instance_unref(inst);
3043 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
3045 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) < 0) {
3046 instance_unref(inst);
3050 inst->pd.owner = client;
3054 HAPI int instance_slave_close_pd(struct inst_info *inst, struct client_node *client, int reason)
3056 const char *pkgname;
3058 struct packet *packet;
3059 struct slave_node *slave;
3060 struct pkg_info *pkg;
3063 if (inst->pd.owner != client) {
3064 ErrPrint("Has no permission\n");
3065 return LB_STATUS_ERROR_PERMISSION;
3068 pkg = instance_package(inst);
3070 ErrPrint("No package info\n");
3071 return LB_STATUS_ERROR_INVALID;
3074 slave = package_slave(pkg);
3076 ErrPrint("No assigned slave\n");
3077 return LB_STATUS_ERROR_FAULT;
3080 pkgname = package_name(pkg);
3081 id = instance_id(inst);
3083 if (!pkgname || !id) {
3084 ErrPrint("pkgname[%s] & id[%s] is not valid\n", pkgname, id);
3085 return LB_STATUS_ERROR_INVALID;
3088 packet = packet_create_noack("pd_hide", "ssi", pkgname, id, reason);
3090 ErrPrint("Failed to create a packet\n");
3091 return LB_STATUS_ERROR_FAULT;
3094 slave_thaw_ttl(slave);
3096 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
3097 release_resource_for_closing_pd(pkg, inst, client);
3098 inst->pd.owner = NULL;
3099 DbgPrint("PERF_DBOX\n");
3103 HAPI int instance_client_pd_created(struct inst_info *inst, int status)
3105 struct packet *packet;
3109 if (inst->pd.need_to_send_close_event) {
3110 DbgPrint("PD is already created\n");
3111 return LB_STATUS_ERROR_INVALID;
3114 switch (package_pd_type(inst->info)) {
3115 case PD_TYPE_SCRIPT:
3116 buf_id = script_handler_buffer_id(inst->pd.canvas.script);
3118 case PD_TYPE_BUFFER:
3119 buf_id = buffer_handler_id(inst->pd.canvas.buffer);
3127 inst->pd.need_to_send_close_event = (status == 0);
3129 packet = packet_create_noack("pd_created", "sssiii",
3130 package_name(inst->info), inst->id, buf_id,
3131 inst->pd.width, inst->pd.height, status);
3133 ErrPrint("Failed to create a packet\n");
3134 return LB_STATUS_ERROR_FAULT;
3137 ret = CLIENT_SEND_EVENT(inst, packet);
3139 if (inst->pd.need_to_send_close_event && inst->pd.pended_update_cnt) {
3140 DbgPrint("Apply pended desc(%d) - %s\n", inst->pd.pended_update_cnt, inst->pd.pended_update_desc);
3141 instance_pd_updated_by_instance(inst, inst->pd.pended_update_desc);
3142 inst->pd.pended_update_cnt = 0;
3143 DbgFree(inst->pd.pended_update_desc);
3144 inst->pd.pended_update_desc = NULL;
3150 HAPI int instance_client_pd_destroyed(struct inst_info *inst, int status)
3152 return send_pd_destroyed_to_client(inst, status);
3155 HAPI int instance_add_client(struct inst_info *inst, struct client_node *client)
3157 if (inst->client == client) {
3158 ErrPrint("Owner cannot be the viewer\n");
3159 return LB_STATUS_ERROR_INVALID;
3162 DbgPrint("%d is added to the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
3163 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst) < 0) {
3164 ErrPrint("Failed to add a deactivate callback\n");
3165 return LB_STATUS_ERROR_FAULT;
3169 inst->client_list = eina_list_append(inst->client_list, client);
3170 return LB_STATUS_SUCCESS;
3173 HAPI int instance_del_client(struct inst_info *inst, struct client_node *client)
3175 if (inst->client == client) {
3176 ErrPrint("Owner is not in the viewer list\n");
3177 return LB_STATUS_ERROR_INVALID;
3180 client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst);
3181 viewer_deactivated_cb(client, inst);
3182 return LB_STATUS_SUCCESS;
3185 HAPI int instance_has_client(struct inst_info *inst, struct client_node *client)
3187 return !!eina_list_data_find(inst->client_list, client);
3190 HAPI void *instance_client_list(struct inst_info *inst)
3192 return inst->client_list;
3195 HAPI int instance_init(void)
3197 if (!strcasecmp(PROVIDER_METHOD, "shm")) {
3198 s_info.env_buf_type = BUFFER_TYPE_SHM;
3199 } else if (!strcasecmp(PROVIDER_METHOD, "pixmap")) {
3200 s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
3202 /* Default method is BUFFER_TYPE_FILE */
3204 return LB_STATUS_SUCCESS;
3207 HAPI int instance_fini(void)
3209 return LB_STATUS_SUCCESS;
3212 static inline struct tag_item *find_tag_item(struct inst_info *inst, const char *tag)
3214 struct tag_item *item;
3217 EINA_LIST_FOREACH(inst->data_list, l, item) {
3218 if (!strcmp(item->tag, tag)) {
3226 HAPI int instance_set_data(struct inst_info *inst, const char *tag, void *data)
3228 struct tag_item *item;
3230 item = find_tag_item(inst, tag);
3232 item = malloc(sizeof(*item));
3234 ErrPrint("Heap: %s\n", strerror(errno));
3235 return LB_STATUS_ERROR_MEMORY;
3238 item->tag = strdup(tag);
3240 ErrPrint("Heap: %s\n", strerror(errno));
3242 return LB_STATUS_ERROR_MEMORY;
3245 inst->data_list = eina_list_append(inst->data_list, item);
3249 inst->data_list = eina_list_remove(inst->data_list, item);
3256 return LB_STATUS_SUCCESS;
3259 HAPI void *instance_del_data(struct inst_info *inst, const char *tag)
3261 struct tag_item *item;
3264 item = find_tag_item(inst, tag);
3269 inst->data_list = eina_list_remove(inst->data_list, item);
3277 HAPI void *instance_get_data(struct inst_info *inst, const char *tag)
3279 struct tag_item *item;
3281 item = find_tag_item(inst, tag);
3289 HAPI struct client_node *instance_pd_owner(struct inst_info *inst)
3291 return inst->pd.owner;