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.
22 #include <Ecore_Evas.h>
28 #include <com-core_packet.h>
29 #include <livebox-service.h>
30 #include <livebox-errno.h>
35 #include "slave_life.h"
36 #include "slave_rpc.h"
37 #include "client_life.h"
39 #include "client_rpc.h"
41 #include "script_handler.h"
42 #include "buffer_handler.h"
49 enum buffer_type env_buf_type;
51 .env_buf_type = BUFFER_TYPE_FILE,
54 struct set_pinup_cbdata {
55 struct inst_info *inst;
59 struct resize_cbdata {
60 struct inst_info *inst;
65 struct update_mode_cbdata {
66 struct inst_info *inst;
70 struct change_group_cbdata {
71 struct inst_info *inst;
76 struct period_cbdata {
77 struct inst_info *inst;
82 int (*event_cb)(struct inst_info *inst, void *data);
92 struct pkg_info *info;
94 enum instance_state state; /*!< Represents current state */
95 enum instance_state requested_state; /*!< Only ACTIVATED | DESTROYED is acceptable */
96 enum instance_destroy_type destroy_type;
108 int scroll_locked; /*!< Scroller which is in viewer is locked. */
109 int active_update; /*!< Viewer will reload the buffer by itself, so the provider doesn't need to send the updated event */
111 enum livebox_visible_state visible;
119 struct script_info *script;
120 struct buffer_info *buffer;
133 struct script_info *script;
134 struct buffer_info *buffer;
137 struct client_node *owner;
138 int is_opened_for_reactivate;
139 int need_to_send_close_event;
140 char *pended_update_desc;
141 int pended_update_cnt;
144 struct client_node *client; /*!< Owner - creator */
145 Eina_List *client_list; /*!< Viewer list */
148 Ecore_Timer *update_timer; /*!< Only used for secured livebox */
150 Eina_List *delete_event_list;
152 Eina_List *data_list;
155 #define CLIENT_SEND_EVENT(instance, packet) ((instance)->client ? client_rpc_async_request((instance)->client, (packet)) : client_broadcast((instance), (packet)))
157 static Eina_Bool update_timer_cb(void *data);
159 static inline void timer_thaw(struct inst_info *inst)
166 ecore_timer_thaw(inst->update_timer);
167 period = ecore_timer_interval_get(inst->update_timer);
168 pending = ecore_timer_pending_get(inst->update_timer);
169 delay = util_time_delay_for_compensation(period) - pending;
170 ecore_timer_delay(inst->update_timer, delay);
172 if (inst->sleep_at == 0.0f) {
176 sleep_time = util_timestamp() - inst->sleep_at;
177 if (sleep_time > pending) {
178 (void)update_timer_cb(inst);
181 inst->sleep_at = 0.0f;
184 static inline void timer_freeze(struct inst_info *inst)
186 ecore_timer_freeze(inst->update_timer);
188 if (ecore_timer_interval_get(inst->update_timer) <= 1.0f) {
192 #if defined(_USE_ECORE_TIME_GET)
193 inst->sleep_at = ecore_time_get();
196 if (gettimeofday(&tv, NULL) < 0) {
197 ErrPrint("gettimeofday: %s\n", strerror(errno));
201 inst->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
206 static int viewer_deactivated_cb(struct client_node *client, void *data)
208 struct inst_info *inst = data;
210 DbgPrint("%d is deleted from the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
211 if (!eina_list_data_find(inst->client_list, client)) {
212 ErrPrint("Not found\n");
213 return LB_STATUS_ERROR_NOT_EXIST;
216 inst->client_list = eina_list_remove(inst->client_list, client);
217 if (!inst->client_list && !inst->client) {
218 DbgPrint("Has no clients\n");
219 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
222 instance_unref(inst);
223 return -1; /*!< Remove this callback from the cb list */
226 static int pause_livebox(struct inst_info *inst)
228 struct packet *packet;
230 packet = packet_create_noack("lb_pause", "ss", package_name(inst->info), inst->id);
232 ErrPrint("Failed to create a new packet\n");
233 return LB_STATUS_ERROR_FAULT;
236 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
239 /*! \TODO Wake up the freeze'd timer */
240 static int resume_livebox(struct inst_info *inst)
242 struct packet *packet;
244 packet = packet_create_noack("lb_resume", "ss", package_name(inst->info), inst->id);
246 ErrPrint("Failed to create a new packet\n");
247 return LB_STATUS_ERROR_FAULT;
250 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
253 static inline int instance_recover_visible_state(struct inst_info *inst)
257 switch (inst->visible) {
260 instance_thaw_updator(inst);
264 case LB_HIDE_WITH_PAUSE:
265 ret = pause_livebox(inst);
267 instance_freeze_updator(inst);
270 ret = LB_STATUS_ERROR_INVALID;
274 DbgPrint("Visible state is recovered to %d\n", ret);
278 static inline void instance_send_update_mode_event(struct inst_info *inst, int active_mode, int status)
280 struct packet *packet;
284 ErrPrint("Instance info is not ready to use\n");
288 pkgname = package_name(inst->info);
290 packet = packet_create_noack("update_mode", "ssii", pkgname, inst->id, status, active_mode);
292 CLIENT_SEND_EVENT(inst, packet);
294 ErrPrint("Failed to send update mode event\n");
298 static inline void instance_send_resized_event(struct inst_info *inst, int is_pd, int w, int h, int status)
300 struct packet *packet;
301 enum lb_type lb_type;
306 ErrPrint("Instance info is not ready to use\n");
310 pkgname = package_name(inst->info);
312 lb_type = package_lb_type(inst->info);
313 if (lb_type == LB_TYPE_SCRIPT) {
314 id = fb_id(script_handler_fb(inst->lb.canvas.script));
315 } else if (lb_type == LB_TYPE_BUFFER) {
316 id = buffer_handler_id(inst->lb.canvas.buffer);
321 packet = packet_create_noack("size_changed", "sssiiii", pkgname, inst->id, id, is_pd, w, h, status);
323 CLIENT_SEND_EVENT(inst, packet);
325 ErrPrint("Failed to send size changed event\n");
329 static void update_mode_cb(struct slave_node *slave, const struct packet *packet, void *data)
331 struct update_mode_cbdata *cbdata = data;
335 ErrPrint("Invalid packet\n");
336 instance_send_update_mode_event(cbdata->inst, cbdata->active_update, LB_STATUS_ERROR_FAULT);
337 instance_unref(cbdata->inst);
342 if (packet_get(packet, "i", &ret) != 1) {
343 ErrPrint("Invalid parameters\n");
344 instance_send_update_mode_event(cbdata->inst, cbdata->active_update, LB_STATUS_ERROR_INVALID);
345 instance_unref(cbdata->inst);
350 if (ret == LB_STATUS_SUCCESS) {
351 cbdata->inst->active_update = cbdata->active_update;
354 instance_send_update_mode_event(cbdata->inst, cbdata->active_update, ret);
356 instance_unref(cbdata->inst);
360 HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_node *client)
362 struct packet *packet;
363 enum lb_type lb_type;
364 enum pd_type pd_type;
369 client = inst->client;
371 return LB_STATUS_SUCCESS;
375 lb_type = package_lb_type(inst->info);
376 pd_type = package_pd_type(inst->info);
378 if (lb_type == LB_TYPE_SCRIPT) {
379 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
380 } else if (lb_type == LB_TYPE_BUFFER) {
381 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
386 if (pd_type == PD_TYPE_SCRIPT) {
387 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
388 } else if (pd_type == PD_TYPE_BUFFER) {
389 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
394 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
396 package_name(inst->info), inst->id, inst->content,
397 inst->lb.width, inst->lb.height,
398 inst->pd.width, inst->pd.height,
399 inst->cluster, inst->category,
401 package_auto_launch(inst->info),
403 package_size_list(inst->info),
405 package_pinup(inst->info),
407 inst->lb.period, inst->title,
410 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
411 return LB_STATUS_ERROR_FAULT;
414 return client_rpc_async_request(client, packet);
417 static int update_client_list(struct client_node *client, void *data)
419 struct inst_info *inst = data;
421 if (!instance_has_client(inst, client)) {
422 instance_add_client(inst, client);
425 return LB_STATUS_SUCCESS;
428 static int instance_broadcast_created_event(struct inst_info *inst)
430 struct packet *packet;
431 enum lb_type lb_type;
432 enum pd_type pd_type;
436 lb_type = package_lb_type(inst->info);
437 pd_type = package_pd_type(inst->info);
439 if (lb_type == LB_TYPE_SCRIPT) {
440 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
441 } else if (lb_type == LB_TYPE_BUFFER) {
442 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
447 if (pd_type == PD_TYPE_SCRIPT) {
448 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
449 } else if (pd_type == PD_TYPE_BUFFER) {
450 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
456 client_browse_list(inst->cluster, inst->category, update_client_list, inst);
459 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
461 package_name(inst->info), inst->id, inst->content,
462 inst->lb.width, inst->lb.height,
463 inst->pd.width, inst->pd.height,
464 inst->cluster, inst->category,
466 package_auto_launch(inst->info),
468 package_size_list(inst->info),
470 package_pinup(inst->info),
472 inst->lb.period, inst->title,
475 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
476 return LB_STATUS_ERROR_FAULT;
479 return CLIENT_SEND_EVENT(inst, packet);
482 HAPI int instance_unicast_deleted_event(struct inst_info *inst, struct client_node *client)
484 struct packet *packet;
487 client = inst->client;
489 return LB_STATUS_ERROR_INVALID;
493 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
495 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
496 return LB_STATUS_ERROR_FAULT;
499 return client_rpc_async_request(client, packet);
502 static int instance_broadcast_deleted_event(struct inst_info *inst)
504 struct packet *packet;
505 struct client_node *client;
510 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
512 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
513 return LB_STATUS_ERROR_FAULT;
516 ret = CLIENT_SEND_EVENT(inst, packet);
518 EINA_LIST_FOREACH_SAFE(inst->client_list, l, n, client) {
519 instance_del_client(inst, client);
525 static int client_deactivated_cb(struct client_node *client, void *data)
527 struct inst_info *inst = data;
528 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
529 return LB_STATUS_SUCCESS;
532 static int send_pd_destroyed_to_client(struct inst_info *inst, int status)
534 struct packet *packet;
536 packet = packet_create_noack("pd_destroyed", "ssi", package_name(inst->info), inst->id, status);
538 ErrPrint("Failed to create a packet\n");
539 return LB_STATUS_ERROR_FAULT;
542 return CLIENT_SEND_EVENT(inst, packet);
545 static inline void invoke_delete_callbacks(struct inst_info *inst)
549 struct event_item *item;
551 EINA_LIST_FOREACH_SAFE(inst->delete_event_list, l, n, item) {
552 if (item->event_cb(inst, item->data) < 0) {
553 if (eina_list_data_find(inst->delete_event_list, item)) {
554 inst->delete_event_list = eina_list_remove(inst->delete_event_list, item);
561 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)
563 struct event_item *item;
566 return LB_STATUS_ERROR_INVALID;
570 case INSTANCE_EVENT_DESTROY:
571 item = malloc(sizeof(*item));
573 ErrPrint("Heap: %s\n", strerror(errno));
574 return LB_STATUS_ERROR_MEMORY;
577 item->event_cb = event_cb;
580 inst->delete_event_list = eina_list_append(inst->delete_event_list, item);
583 return LB_STATUS_ERROR_INVALID;
586 return LB_STATUS_SUCCESS;
589 HAPI int instance_event_callback_del(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data))
593 struct event_item *item;
596 case INSTANCE_EVENT_DESTROY:
597 EINA_LIST_FOREACH_SAFE(inst->delete_event_list, l, n, item) {
598 if (item->event_cb == event_cb) {
599 inst->delete_event_list = eina_list_remove(inst->delete_event_list, item);
601 return LB_STATUS_SUCCESS;
609 return LB_STATUS_ERROR_NOT_EXIST;
612 static inline void destroy_instance(struct inst_info *inst)
614 struct pkg_info *pkg;
615 enum lb_type lb_type;
616 enum pd_type pd_type;
617 struct slave_node *slave;
618 struct event_item *item;
619 struct tag_item *tag_item;
621 invoke_delete_callbacks(inst);
625 lb_type = package_lb_type(pkg);
626 pd_type = package_pd_type(pkg);
627 slave = package_slave(inst->info);
629 DbgPrint("Instance is destroyed (%p), slave(%p)\n", inst, slave);
631 if (inst->pd.need_to_send_close_event) {
632 send_pd_destroyed_to_client(inst, 0);
635 if (lb_type == LB_TYPE_SCRIPT) {
636 script_handler_unload(inst->lb.canvas.script, 0);
637 script_handler_destroy(inst->lb.canvas.script);
638 } else if (lb_type == LB_TYPE_BUFFER) {
639 buffer_handler_unload(inst->lb.canvas.buffer);
640 buffer_handler_destroy(inst->lb.canvas.buffer);
643 if (pd_type == PD_TYPE_SCRIPT) {
644 script_handler_unload(inst->pd.canvas.script, 1);
645 script_handler_destroy(inst->pd.canvas.script);
646 } else if (pd_type == PD_TYPE_BUFFER) {
647 buffer_handler_unload(inst->pd.canvas.buffer);
648 buffer_handler_destroy(inst->pd.canvas.buffer);
652 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
653 client_unref(inst->client);
656 if (inst->update_timer) {
657 ecore_timer_del(inst->update_timer);
660 EINA_LIST_FREE(inst->data_list, tag_item) {
661 DbgPrint("Tagged item[%s] %p\n", tag_item->tag, tag_item->data);
662 DbgFree(tag_item->tag);
666 EINA_LIST_FREE(inst->delete_event_list, item) {
669 DbgFree(inst->category);
670 DbgFree(inst->cluster);
671 DbgFree(inst->content);
672 DbgFree(inst->title);
673 util_unlink(util_uri_to_path(inst->id));
675 package_del_instance(inst->info, inst);
678 slave = slave_unload_instance(slave);
681 static Eina_Bool update_timer_cb(void *data)
683 struct inst_info *inst = (struct inst_info *)data;
685 slave_rpc_request_update(package_name(inst->info), inst->id, inst->cluster, inst->category);
686 return ECORE_CALLBACK_RENEW;
689 static inline int fork_package(struct inst_info *inst, const char *pkgname)
691 struct pkg_info *info;
694 info = package_find(pkgname);
696 ErrPrint("%s is not found\n", pkgname);
697 return LB_STATUS_ERROR_NOT_EXIST;
700 len = strlen(SCHEMA_FILE "%s%s_%d_%lf.png") + strlen(IMAGE_PATH) + strlen(package_name(info)) + 50;
701 inst->id = malloc(len);
703 ErrPrint("Heap: %s\n", strerror(errno));
704 return LB_STATUS_ERROR_MEMORY;
707 snprintf(inst->id, len, SCHEMA_FILE "%s%s_%d_%lf.png", IMAGE_PATH, package_name(info), client_pid(inst->client), inst->timestamp);
709 instance_set_pd_size(inst, package_pd_width(info), package_pd_height(info));
711 inst->lb.period = package_period(info);
715 if (package_secured(info)) {
716 if (inst->lb.period > 0.0f) {
717 inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
718 if (!inst->update_timer) {
719 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
721 timer_freeze(inst); /* Freeze the update timer as default */
724 inst->update_timer = NULL;
728 return LB_STATUS_SUCCESS;
731 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)
733 struct inst_info *inst;
735 inst = calloc(1, sizeof(*inst));
737 ErrPrint("Heap: %s\n", strerror(errno));
741 inst->timestamp = timestamp;
742 inst->lb.width = width;
743 inst->lb.height = height;
745 inst->content = strdup(content);
746 if (!inst->content) {
747 ErrPrint("Heap: %s\n", strerror(errno));
752 inst->cluster = strdup(cluster);
753 if (!inst->cluster) {
754 ErrPrint("Heap: %s\n", strerror(errno));
755 DbgFree(inst->content);
760 inst->category = strdup(category);
761 if (!inst->category) {
762 ErrPrint("Heap: %s\n", strerror(errno));
763 DbgFree(inst->cluster);
764 DbgFree(inst->content);
769 inst->title = strdup(DEFAULT_TITLE); /*!< Use the DEFAULT Title "" */
771 ErrPrint("Heap: %s\n", strerror(errno));
772 DbgFree(inst->category);
773 DbgFree(inst->cluster);
774 DbgFree(inst->content);
780 inst->client = client_ref(client);
781 client_event_callback_add(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
784 if (fork_package(inst, pkgname) < 0) {
785 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
786 client_unref(inst->client);
787 DbgFree(inst->title);
788 DbgFree(inst->category);
789 DbgFree(inst->cluster);
790 DbgFree(inst->content);
795 inst->state = INST_INIT;
796 inst->requested_state = INST_INIT;
799 if (package_add_instance(inst->info, inst) < 0) {
800 instance_state_reset(inst);
801 instance_destroy(inst, INSTANCE_DESTROY_FAULT);
805 slave_load_instance(package_slave(inst->info));
807 if (instance_activate(inst) < 0) {
808 instance_state_reset(inst);
809 instance_destroy(inst, INSTANCE_DESTROY_FAULT);
816 HAPI struct inst_info *instance_ref(struct inst_info *inst)
826 HAPI struct inst_info *instance_unref(struct inst_info *inst)
832 if (inst->refcnt == 0) {
833 ErrPrint("Instance refcnt is not valid\n");
838 if (inst->refcnt == 0) {
839 destroy_instance(inst);
846 static void deactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
848 struct inst_info *inst = data;
853 * In this callback, we cannot trust the "client" information.
854 * It could be cleared before reach to here.
860 * The instance_reload will care this.
861 * And it will be called from the slave activate callback.
866 if (packet_get(packet, "i", &ret) != 1) {
867 ErrPrint("Invalid argument\n");
871 if (inst->state == INST_DESTROYED) {
875 * Do nothing at here anymore.
884 * Successfully unloaded
886 switch (inst->requested_state) {
888 instance_state_reset(inst);
889 instance_reactivate(inst);
892 instance_broadcast_deleted_event(inst);
893 instance_state_reset(inst);
894 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
896 /*!< Unable to reach here */
901 case LB_STATUS_ERROR_INVALID:
904 * Slave has no instance of this package.
906 case LB_STATUS_ERROR_NOT_EXIST:
909 * This instance's previous state is only can be the INST_ACTIVATED.
910 * So we should care the slave_unload_instance from here.
911 * And we should send notification to clients, about this is deleted.
915 * Slave has no instance of this.
916 * In this case, ignore the requested_state
917 * Because, this instance is already met a problem.
922 * Failed to unload this instance.
923 * This is not possible, slave will always return LB_STATUS_ERROR_NOT_EXIST, LB_STATUS_ERROR_INVALID, or 0.
924 * but care this exceptional case.
926 instance_broadcast_deleted_event(inst);
927 instance_state_reset(inst);
928 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
933 inst->changing_state = 0;
934 instance_unref(inst);
937 static void reactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
939 struct inst_info *inst = data;
940 struct pkg_info *info;
941 enum lb_type lb_type;
942 enum pd_type pd_type;
951 * instance_reload function will care this.
952 * and it will be called from the slave_activate callback
957 if (packet_get(packet, "issi", &ret, &content, &title, &is_pinned_up) != 4) {
958 ErrPrint("Invalid parameter\n");
962 if (strlen(content)) {
965 tmp = strdup(content);
967 ErrPrint("Heap: %s\n", strerror(errno));
971 DbgFree(inst->content);
980 ErrPrint("Heap: %s\n", strerror(errno));
984 DbgFree(inst->title);
988 if (inst->state == INST_DESTROYED) {
992 * Do nothing at here anymore.
998 case 0: /*!< normally created */
999 inst->state = INST_ACTIVATED;
1000 switch (inst->requested_state) {
1001 case INST_DESTROYED:
1002 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1004 case INST_ACTIVATED:
1005 inst->is_pinned_up = is_pinned_up;
1007 lb_type = package_lb_type(info);
1008 pd_type = package_pd_type(info);
1012 * Optimization point.
1013 * In case of the BUFFER type,
1014 * the slave will request the buffer to render its contents.
1015 * so the buffer will be automatcially recreated when it gots the
1016 * buffer request packet.
1017 * so load a buffer from here is not neccessary.
1018 * I should to revise it and concrete the concept.
1019 * Just leave it only for now.
1022 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script) {
1023 script_handler_load(inst->lb.canvas.script, 0);
1024 } else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer) {
1025 buffer_handler_load(inst->lb.canvas.buffer);
1028 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script && inst->pd.is_opened_for_reactivate) {
1032 * We should to send a request to open a PD to slave.
1033 * if we didn't send it, the slave will not recognize the state of a PD.
1034 * We have to keep the view of PD seamless even if the livebox is reactivated.
1035 * To do that, send open request from here.
1037 ret = instance_slave_open_pd(inst, NULL);
1038 instance_slave_get_pd_pos(inst, &x, &y);
1042 * In this case, master already loads the PD script.
1043 * So just send the pd,show event to the slave again.
1045 ret = instance_signal_emit(inst, "pd,show", instance_id(inst), 0.0, 0.0, 0.0, 0.0, x, y, 0);
1046 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer && inst->pd.is_opened_for_reactivate) {
1049 buffer_handler_load(inst->pd.canvas.buffer);
1050 instance_slave_get_pd_pos(inst, &x, &y);
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);
1063 * In this case, just send the pd,show event for keeping the compatibility
1065 ret = instance_signal_emit(inst, "pd,show", instance_id(inst), 0.0, 0.0, 0.0, 0.0, x, y, 0);
1070 * After create an instance again,
1071 * Send resize request to the livebox.
1072 * instance_resize(inst, inst->lb.width, inst->lb.height);
1074 * renew request will resize the livebox while creating it again
1079 * This function will check the visiblity of a livebox and
1080 * make decision whether it thaw the update timer or not.
1082 instance_recover_visible_state(inst);
1089 instance_broadcast_deleted_event(inst);
1090 instance_state_reset(inst);
1091 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1096 inst->changing_state = 0;
1097 instance_unref(inst);
1100 static void activate_cb(struct slave_node *slave, const struct packet *packet, void *data)
1102 struct inst_info *inst = data;
1114 * instance_reload will care this
1115 * it will be called from the slave_activate callback
1120 if (packet_get(packet, "iiidssi", &ret, &w, &h, &priority, &content, &title, &is_pinned_up) != 7) {
1121 ErrPrint("Invalid parameter\n");
1125 if (inst->state == INST_DESTROYED) {
1128 * Already destroyed.
1129 * Do nothing at here anymore.
1135 case 1: /*!< need to create */
1136 if (util_free_space(IMAGE_PATH) > MINIMUM_SPACE) {
1137 struct inst_info *new_inst;
1138 new_inst = instance_create(inst->client, util_timestamp(), package_name(inst->info),
1139 inst->content, inst->cluster, inst->category,
1140 inst->lb.period, 0, 0);
1142 ErrPrint("Failed to create a new instance\n");
1145 ErrPrint("Not enough space\n");
1147 case 0: /*!< normally created */
1150 * Anyway this instance is loaded to the slave,
1151 * just increase the loaded instance counter
1152 * And then reset jobs.
1154 instance_set_lb_size(inst, w, h);
1155 instance_set_lb_info(inst, priority, content, title);
1157 inst->state = INST_ACTIVATED;
1159 switch (inst->requested_state) {
1160 case INST_DESTROYED:
1161 instance_unicast_deleted_event(inst, NULL);
1162 instance_state_reset(inst);
1163 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1165 case INST_ACTIVATED:
1169 * LB should be created at the create time
1171 inst->is_pinned_up = is_pinned_up;
1172 if (package_lb_type(inst->info) == LB_TYPE_SCRIPT) {
1173 if (inst->lb.width == 0 && inst->lb.height == 0) {
1174 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1177 inst->lb.canvas.script = script_handler_create(inst,
1178 package_lb_path(inst->info),
1179 package_lb_group(inst->info),
1180 inst->lb.width, inst->lb.height);
1182 if (!inst->lb.canvas.script) {
1183 ErrPrint("Failed to create LB\n");
1185 script_handler_load(inst->lb.canvas.script, 0);
1187 } else if (package_lb_type(inst->info) == LB_TYPE_BUFFER) {
1188 instance_create_lb_buffer(inst);
1191 if (package_pd_type(inst->info) == PD_TYPE_SCRIPT) {
1192 if (inst->pd.width == 0 && inst->pd.height == 0) {
1193 instance_set_pd_size(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1196 inst->pd.canvas.script = script_handler_create(inst,
1197 package_pd_path(inst->info),
1198 package_pd_group(inst->info),
1199 inst->pd.width, inst->pd.height);
1201 if (!inst->pd.canvas.script) {
1202 ErrPrint("Failed to create PD\n");
1204 } else if (package_pd_type(inst->info) == PD_TYPE_BUFFER) {
1205 instance_create_pd_buffer(inst);
1208 instance_broadcast_created_event(inst);
1210 instance_thaw_updator(inst);
1215 instance_unicast_deleted_event(inst, NULL);
1216 instance_state_reset(inst);
1217 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
1222 inst->changing_state = 0;
1223 instance_unref(inst);
1226 HAPI int instance_create_pd_buffer(struct inst_info *inst)
1228 if (inst->pd.width == 0 && inst->pd.height == 0) {
1229 instance_set_pd_size(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1232 if (!inst->pd.canvas.buffer) {
1233 inst->pd.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->pd.width, inst->pd.height, sizeof(int));
1234 if (!inst->pd.canvas.buffer) {
1235 ErrPrint("Failed to create PD Buffer\n");
1239 return !!inst->pd.canvas.buffer;
1242 HAPI int instance_create_lb_buffer(struct inst_info *inst)
1244 if (inst->lb.width == 0 && inst->lb.height == 0) {
1245 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1248 if (!inst->lb.canvas.buffer) {
1251 * Slave doesn't call the acquire_buffer.
1252 * In this case, create the buffer from here.
1254 inst->lb.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->lb.width, inst->lb.height, sizeof(int));
1255 if (!inst->lb.canvas.buffer) {
1256 ErrPrint("Failed to create LB\n");
1260 return !!inst->lb.canvas.buffer;
1263 HAPI int instance_destroy(struct inst_info *inst, enum instance_destroy_type type)
1265 struct packet *packet;
1268 ErrPrint("Invalid instance handle\n");
1269 return LB_STATUS_ERROR_INVALID;
1272 switch (inst->state) {
1273 case INST_REQUEST_TO_ACTIVATE:
1274 case INST_REQUEST_TO_DESTROY:
1275 case INST_REQUEST_TO_REACTIVATE:
1276 inst->requested_state = INST_DESTROYED;
1277 return LB_STATUS_SUCCESS;
1279 inst->state = INST_DESTROYED;
1280 inst->requested_state = INST_DESTROYED;
1281 instance_unref(inst);
1282 return LB_STATUS_SUCCESS;
1283 case INST_DESTROYED:
1284 inst->requested_state = INST_DESTROYED;
1285 return LB_STATUS_SUCCESS;
1290 packet = packet_create("delete", "ssi", package_name(inst->info), inst->id, type);
1292 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1293 return LB_STATUS_ERROR_FAULT;
1296 inst->destroy_type = type;
1297 inst->requested_state = INST_DESTROYED;
1298 inst->state = INST_REQUEST_TO_DESTROY;
1299 inst->changing_state = 1;
1300 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, deactivate_cb, instance_ref(inst), 0);
1303 HAPI int instance_reload(struct inst_info *inst, enum instance_destroy_type type)
1305 struct packet *packet;
1309 ErrPrint("Invalid instance handle\n");
1310 return LB_STATUS_ERROR_INVALID;
1313 DbgPrint("Reload instance (%s)\n", instance_id(inst));
1315 switch (inst->state) {
1316 case INST_REQUEST_TO_ACTIVATE:
1317 case INST_REQUEST_TO_REACTIVATE:
1318 return LB_STATUS_SUCCESS;
1320 ret = instance_activate(inst);
1322 ErrPrint("Failed to activate instance: %d (%s)\n", ret, instance_id(inst));
1324 return LB_STATUS_SUCCESS;
1325 case INST_DESTROYED:
1326 case INST_REQUEST_TO_DESTROY:
1327 DbgPrint("Instance is destroying now\n");
1328 return LB_STATUS_SUCCESS;
1333 packet = packet_create("delete", "ssi", package_name(inst->info), inst->id, type);
1335 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1336 return LB_STATUS_ERROR_FAULT;
1339 inst->destroy_type = type;
1340 inst->requested_state = INST_ACTIVATED;
1341 inst->state = INST_REQUEST_TO_DESTROY;
1342 inst->changing_state = 1;
1343 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, deactivate_cb, instance_ref(inst), 0);
1346 /* Client Deactivated Callback */
1347 static int pd_buffer_close_cb(struct client_node *client, void *inst)
1351 ret = instance_slave_close_pd(inst, client);
1352 DbgPrint("Forcely close the PD ret: %d\n", ret);
1354 instance_unref(inst);
1356 return -1; /* Delete this callback */
1359 /* Client Deactivated Callback */
1360 static int pd_script_close_cb(struct client_node *client, void *inst)
1364 ret = script_handler_unload(instance_pd_script(inst), 1);
1365 DbgPrint("Unload script: %d\n", ret);
1367 ret = instance_slave_close_pd(inst, client);
1368 DbgPrint("Forcely close the PD ret: %d\n", ret);
1370 instance_unref(inst);
1372 return -1; /* Delete this callback */
1375 static inline void release_resource_for_closing_pd(struct pkg_info *info, struct inst_info *inst, struct client_node *client)
1378 client = inst->pd.owner;
1386 * Clean up the resources
1388 if (package_pd_type(info) == PD_TYPE_BUFFER) {
1389 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) == 0) {
1392 * Only if this function succeed to remove the pd_buffer_close_cb,
1393 * Decrease the reference count of this instance
1396 instance_unref(inst);
1397 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
1398 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) == 0) {
1401 * Only if this function succeed to remove the script_close_cb,
1402 * Decrease the reference count of this instance
1405 instance_unref(inst);
1407 ErrPrint("Unknown PD type\n");
1412 HAPI int instance_state_reset(struct inst_info *inst)
1414 enum lb_type lb_type;
1415 enum pd_type pd_type;
1418 ErrPrint("Invalid instance handle\n");
1419 return LB_STATUS_ERROR_INVALID;
1422 if (inst->state == INST_DESTROYED) {
1426 lb_type = package_lb_type(inst->info);
1427 pd_type = package_pd_type(inst->info);
1429 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script) {
1430 script_handler_unload(inst->lb.canvas.script, 0);
1431 } else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer) {
1432 buffer_handler_unload(inst->lb.canvas.buffer);
1435 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script) {
1436 inst->pd.is_opened_for_reactivate = script_handler_is_loaded(inst->pd.canvas.script);
1437 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1438 script_handler_unload(inst->pd.canvas.script, 1);
1439 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer) {
1440 inst->pd.is_opened_for_reactivate = buffer_handler_is_loaded(inst->pd.canvas.buffer);
1441 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1442 buffer_handler_unload(inst->pd.canvas.buffer);
1446 inst->state = INST_INIT;
1447 inst->requested_state = INST_INIT;
1448 return LB_STATUS_SUCCESS;
1451 HAPI int instance_reactivate(struct inst_info *inst)
1453 struct packet *packet;
1457 ErrPrint("Invalid instance handle\n");
1458 return LB_STATUS_ERROR_INVALID;
1461 if (package_is_fault(inst->info)) {
1462 ErrPrint("Fault package [%s]\n", package_name(inst->info));
1463 return LB_STATUS_ERROR_FAULT;
1466 switch (inst->state) {
1467 case INST_REQUEST_TO_DESTROY:
1468 case INST_REQUEST_TO_ACTIVATE:
1469 case INST_REQUEST_TO_REACTIVATE:
1470 inst->requested_state = INST_ACTIVATED;
1471 return LB_STATUS_SUCCESS;
1472 case INST_DESTROYED:
1473 case INST_ACTIVATED:
1474 return LB_STATUS_SUCCESS;
1480 packet = packet_create("renew", "sssiidssiisii",
1481 package_name(inst->info),
1484 package_timeout(inst->info),
1485 !!package_lb_path(inst->info),
1489 inst->lb.width, inst->lb.height,
1490 package_abi(inst->info),
1491 inst->scroll_locked,
1492 inst->active_update);
1494 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1495 return LB_STATUS_ERROR_FAULT;
1498 ret = slave_activate(package_slave(inst->info));
1499 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
1502 * If the master failed to launch the slave,
1503 * Do not send any requests to the slave.
1505 ErrPrint("Failed to launch the slave\n");
1506 packet_destroy(packet);
1510 inst->requested_state = INST_ACTIVATED;
1511 inst->state = INST_REQUEST_TO_REACTIVATE;
1512 inst->changing_state = 1;
1514 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, reactivate_cb, instance_ref(inst), 1);
1517 HAPI int instance_activate(struct inst_info *inst)
1519 struct packet *packet;
1523 ErrPrint("Invalid instance handle\n");
1524 return LB_STATUS_ERROR_INVALID;
1527 if (package_is_fault(inst->info)) {
1528 ErrPrint("Fault package [%s]\n", package_name(inst->info));
1529 return LB_STATUS_ERROR_FAULT;
1532 switch (inst->state) {
1533 case INST_REQUEST_TO_REACTIVATE:
1534 case INST_REQUEST_TO_ACTIVATE:
1535 case INST_REQUEST_TO_DESTROY:
1536 inst->requested_state = INST_ACTIVATED;
1537 return LB_STATUS_SUCCESS;
1538 case INST_ACTIVATED:
1539 case INST_DESTROYED:
1540 return LB_STATUS_SUCCESS;
1546 packet = packet_create("new", "sssiidssisii",
1547 package_name(inst->info),
1550 package_timeout(inst->info),
1551 !!package_lb_path(inst->info),
1556 package_abi(inst->info),
1560 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1561 return LB_STATUS_ERROR_FAULT;
1564 ret = slave_activate(package_slave(inst->info));
1565 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
1568 * If the master failed to launch the slave,
1569 * Do not send any requests to the slave.
1571 ErrPrint("Failed to launch the slave\n");
1572 packet_destroy(packet);
1576 inst->state = INST_REQUEST_TO_ACTIVATE;
1577 inst->requested_state = INST_ACTIVATED;
1578 inst->changing_state = 1;
1582 * Try to activate a slave if it is not activated
1584 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, activate_cb, instance_ref(inst), 1);
1587 HAPI int instance_lb_update_begin(struct inst_info *inst, double priority, const char *content, const char *title)
1589 struct packet *packet;
1592 if (!inst->active_update) {
1593 ErrPrint("Invalid request [%s]\n", inst->id);
1594 return LB_STATUS_ERROR_INVALID;
1597 switch (package_lb_type(inst->info)) {
1598 case LB_TYPE_BUFFER:
1599 if (!inst->lb.canvas.buffer) {
1600 ErrPrint("Buffer is null [%s]\n", inst->id);
1601 return LB_STATUS_ERROR_INVALID;
1603 fbfile = buffer_handler_id(inst->lb.canvas.buffer);
1605 case LB_TYPE_SCRIPT:
1606 if (!inst->lb.canvas.script) {
1607 ErrPrint("Script is null [%s]\n", inst->id);
1608 return LB_STATUS_ERROR_INVALID;
1610 fbfile = fb_id(script_handler_fb(inst->lb.canvas.script));
1613 ErrPrint("Invalid request[%s]\n", inst->id);
1614 return LB_STATUS_ERROR_INVALID;
1617 packet = packet_create_noack("lb_update_begin", "ssdsss", package_name(inst->info), inst->id, priority, content, title, fbfile);
1619 ErrPrint("Unable to create a packet\n");
1620 return LB_STATUS_ERROR_FAULT;
1623 return CLIENT_SEND_EVENT(inst, packet);
1626 HAPI int instance_lb_update_end(struct inst_info *inst)
1628 struct packet *packet;
1630 if (!inst->active_update) {
1631 ErrPrint("Invalid request [%s]\n", inst->id);
1632 return LB_STATUS_ERROR_INVALID;
1635 switch (package_lb_type(inst->info)) {
1636 case LB_TYPE_BUFFER:
1637 if (!inst->lb.canvas.buffer) {
1638 ErrPrint("Buffer is null [%s]\n", inst->id);
1639 return LB_STATUS_ERROR_INVALID;
1642 case LB_TYPE_SCRIPT:
1643 if (!inst->lb.canvas.script) {
1644 ErrPrint("Script is null [%s]\n", inst->id);
1645 return LB_STATUS_ERROR_INVALID;
1649 ErrPrint("Invalid request[%s]\n", inst->id);
1650 return LB_STATUS_ERROR_INVALID;
1653 packet = packet_create_noack("lb_update_end", "ss", package_name(inst->info), inst->id);
1655 ErrPrint("Unable to create a packet\n");
1656 return LB_STATUS_ERROR_FAULT;
1659 return CLIENT_SEND_EVENT(inst, packet);
1662 HAPI int instance_pd_update_begin(struct inst_info *inst)
1664 struct packet *packet;
1667 if (!inst->active_update) {
1668 ErrPrint("Invalid request [%s]\n", inst->id);
1669 return LB_STATUS_ERROR_INVALID;
1672 switch (package_pd_type(inst->info)) {
1673 case PD_TYPE_BUFFER:
1674 if (!inst->pd.canvas.buffer) {
1675 ErrPrint("Buffer is null [%s]\n", inst->id);
1676 return LB_STATUS_ERROR_INVALID;
1678 fbfile = buffer_handler_id(inst->pd.canvas.buffer);
1680 case PD_TYPE_SCRIPT:
1681 if (!inst->pd.canvas.script) {
1682 ErrPrint("Script is null [%s]\n", inst->id);
1683 return LB_STATUS_ERROR_INVALID;
1685 fbfile = fb_id(script_handler_fb(inst->pd.canvas.script));
1688 ErrPrint("Invalid request[%s]\n", inst->id);
1689 return LB_STATUS_ERROR_INVALID;
1692 packet = packet_create_noack("pd_update_begin", "sss", package_name(inst->info), inst->id, fbfile);
1694 ErrPrint("Unable to create a packet\n");
1695 return LB_STATUS_ERROR_FAULT;
1698 return CLIENT_SEND_EVENT(inst, packet);
1701 HAPI int instance_pd_update_end(struct inst_info *inst)
1703 struct packet *packet;
1705 if (!inst->active_update) {
1706 ErrPrint("Invalid request [%s]\n", inst->id);
1707 return LB_STATUS_ERROR_INVALID;
1710 switch (package_pd_type(inst->info)) {
1711 case PD_TYPE_BUFFER:
1712 if (!inst->pd.canvas.buffer) {
1713 ErrPrint("Buffer is null [%s]\n", inst->id);
1714 return LB_STATUS_ERROR_INVALID;
1717 case PD_TYPE_SCRIPT:
1718 if (!inst->pd.canvas.script) {
1719 ErrPrint("Script is null [%s]\n", inst->id);
1720 return LB_STATUS_ERROR_INVALID;
1724 ErrPrint("Invalid request[%s]\n", inst->id);
1725 return LB_STATUS_ERROR_INVALID;
1728 packet = packet_create_noack("pd_update_end", "ss", package_name(inst->info), inst->id);
1730 ErrPrint("Unable to create a packet\n");
1731 return LB_STATUS_ERROR_FAULT;
1734 return CLIENT_SEND_EVENT(inst, packet);
1737 HAPI void instance_lb_updated_by_instance(struct inst_info *inst, const char *safe_file)
1739 struct packet *packet;
1741 enum lb_type lb_type;
1743 const char *content;
1745 if (inst->client && inst->visible != LB_SHOW) {
1746 if (inst->visible == LB_HIDE) {
1747 DbgPrint("Ignore update event %s(HIDE)\n", inst->id);
1750 DbgPrint("Livebox(%s) is PAUSED. But content is updated.\n", inst->id);
1753 lb_type = package_lb_type(inst->info);
1754 if (lb_type == LB_TYPE_SCRIPT) {
1755 id = fb_id(script_handler_fb(inst->lb.canvas.script));
1756 } else if (lb_type == LB_TYPE_BUFFER) {
1757 id = buffer_handler_id(inst->lb.canvas.buffer);
1762 if (inst->content) {
1763 content = inst->content;
1769 title = inst->title;
1774 packet = packet_create_noack("lb_updated", "sssiidsss",
1775 package_name(inst->info), inst->id, id,
1776 inst->lb.width, inst->lb.height, inst->lb.priority, content, title, safe_file);
1778 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1782 (void)CLIENT_SEND_EVENT(inst, packet);
1785 HAPI int instance_hold_scroll(struct inst_info *inst, int hold)
1787 struct packet *packet;
1789 DbgPrint("HOLD: (%s) %d\n", inst->id, hold);
1790 if (inst->scroll_locked == hold) {
1791 return LB_STATUS_ERROR_ALREADY;
1794 packet = packet_create_noack("scroll", "ssi", package_name(inst->info), inst->id, hold);
1796 ErrPrint("Failed to build a packet\n");
1797 return LB_STATUS_ERROR_FAULT;
1800 inst->scroll_locked = hold;
1801 return CLIENT_SEND_EVENT(inst, packet);
1804 HAPI void instance_pd_updated_by_instance(struct inst_info *inst, const char *descfile)
1806 struct packet *packet;
1809 if (inst->client && inst->visible != LB_SHOW) {
1810 DbgPrint("Livebox is hidden. ignore update event\n");
1814 if (!inst->pd.need_to_send_close_event) {
1815 DbgPrint("PD is not created yet. Ignore update event - %s\n", descfile);
1817 if (inst->pd.pended_update_desc) {
1818 DbgFree(inst->pd.pended_update_desc);
1819 inst->pd.pended_update_desc = NULL;
1823 inst->pd.pended_update_desc = strdup(descfile);
1824 if (!inst->pd.pended_update_desc) {
1825 ErrPrint("Heap: %s\n", strerror(errno));
1829 inst->pd.pended_update_cnt++;
1834 descfile = inst->id;
1837 switch (package_pd_type(inst->info)) {
1838 case PD_TYPE_SCRIPT:
1839 id = fb_id(script_handler_fb(inst->pd.canvas.script));
1841 case PD_TYPE_BUFFER:
1842 id = buffer_handler_id(inst->pd.canvas.buffer);
1850 packet = packet_create_noack("pd_updated", "ssssii",
1851 package_name(inst->info), inst->id, descfile, id,
1852 inst->pd.width, inst->pd.height);
1854 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1858 (void)CLIENT_SEND_EVENT(inst, packet);
1861 HAPI void instance_pd_updated(const char *pkgname, const char *id, const char *descfile)
1863 struct inst_info *inst;
1865 inst = package_find_instance_by_id(pkgname, id);
1870 instance_pd_updated_by_instance(inst, descfile);
1873 HAPI int instance_set_update_mode(struct inst_info *inst, int active_update)
1875 struct packet *packet;
1876 struct update_mode_cbdata *cbdata;
1878 if (package_is_fault(inst->info)) {
1879 ErrPrint("Fault package [%s]\n", package_name(inst->info));
1880 return LB_STATUS_ERROR_FAULT;
1883 if (inst->active_update == active_update) {
1884 DbgPrint("Active update is not changed: %d\n", inst->active_update);
1885 return LB_STATUS_ERROR_ALREADY;
1888 cbdata = malloc(sizeof(*cbdata));
1890 ErrPrint("Heap: %s\n", strerror(errno));
1891 return LB_STATUS_ERROR_MEMORY;
1894 cbdata->inst = instance_ref(inst);
1895 cbdata->active_update = active_update;
1897 /* NOTE: param is resued from here */
1898 packet = packet_create("update_mode", "ssi", package_name(inst->info), inst->id, active_update);
1900 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1901 instance_unref(cbdata->inst);
1903 return LB_STATUS_ERROR_FAULT;
1906 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, update_mode_cb, cbdata, 0);
1909 HAPI int instance_active_update(struct inst_info *inst)
1911 return inst->active_update;
1914 HAPI void instance_set_lb_info(struct inst_info *inst, double priority, const char *content, const char *title)
1916 char *_content = NULL;
1917 char *_title = NULL;
1919 if (content && strlen(content)) {
1920 _content = strdup(content);
1922 ErrPrint("Heap: %s\n", strerror(errno));
1926 if (title && strlen(title)) {
1927 _title = strdup(title);
1929 ErrPrint("Heap: %s\n", strerror(errno));
1934 DbgFree(inst->content);
1935 inst->content= _content;
1939 DbgFree(inst->title);
1940 inst->title = _title;
1943 if (priority >= 0.0f && priority <= 1.0f) {
1944 inst->lb.priority = priority;
1948 HAPI void instance_set_lb_size(struct inst_info *inst, int w, int h)
1950 if (inst->lb.width != w || inst->lb.height != h) {
1951 instance_send_resized_event(inst, IS_LB, w, h, LB_STATUS_SUCCESS);
1955 inst->lb.height = h;
1958 HAPI void instance_set_pd_size(struct inst_info *inst, int w, int h)
1960 if (inst->pd.width != w || inst->pd.height != h) {
1961 instance_send_resized_event(inst, IS_PD, w, h, LB_STATUS_SUCCESS);
1965 inst->pd.height = h;
1968 static void pinup_cb(struct slave_node *slave, const struct packet *packet, void *data)
1970 struct set_pinup_cbdata *cbdata = data;
1971 const char *content;
1972 struct packet *result;
1978 * Send pinup failed event to client.
1980 ret = LB_STATUS_ERROR_INVALID;
1984 if (packet_get(packet, "is", &ret, &content) != 2) {
1987 * Send pinup failed event to client
1989 ret = LB_STATUS_ERROR_INVALID;
1996 new_content = strdup(content);
1998 ErrPrint("Heap: %s\n", strerror(errno));
2001 * send pinup failed event to client
2003 ret = LB_STATUS_ERROR_MEMORY;
2007 cbdata->inst->is_pinned_up = cbdata->pinup;
2008 DbgFree(cbdata->inst->content);
2010 cbdata->inst->content = new_content;
2016 * Send PINUP Result to client.
2017 * Client should wait this event.
2019 result = packet_create_noack("pinup", "iisss", ret, cbdata->inst->is_pinned_up,
2020 package_name(cbdata->inst->info), cbdata->inst->id, cbdata->inst->content);
2022 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2024 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
2027 instance_unref(cbdata->inst);
2031 HAPI int instance_set_pinup(struct inst_info *inst, int pinup)
2033 struct set_pinup_cbdata *cbdata;
2034 struct packet *packet;
2037 ErrPrint("Invalid instance handle\n");
2038 return LB_STATUS_ERROR_INVALID;
2041 if (package_is_fault(inst->info)) {
2042 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2043 return LB_STATUS_ERROR_FAULT;
2046 if (!package_pinup(inst->info)) {
2047 return LB_STATUS_ERROR_INVALID;
2050 if (pinup == inst->is_pinned_up) {
2051 return LB_STATUS_ERROR_INVALID;
2054 cbdata = malloc(sizeof(*cbdata));
2056 return LB_STATUS_ERROR_MEMORY;
2059 cbdata->inst = instance_ref(inst);
2060 cbdata->pinup = pinup;
2062 packet = packet_create("pinup", "ssi", package_name(inst->info), inst->id, pinup);
2064 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2065 instance_unref(cbdata->inst);
2067 return LB_STATUS_ERROR_FAULT;
2070 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, pinup_cb, cbdata, 0);
2073 HAPI int instance_freeze_updator(struct inst_info *inst)
2075 if (!inst->update_timer) {
2076 return LB_STATUS_ERROR_INVALID;
2080 return LB_STATUS_SUCCESS;
2083 HAPI int instance_thaw_updator(struct inst_info *inst)
2085 if (!inst->update_timer) {
2086 return LB_STATUS_ERROR_INVALID;
2089 if (client_is_all_paused() || setting_is_lcd_off()) {
2090 return LB_STATUS_ERROR_INVALID;
2093 if (inst->visible == LB_HIDE_WITH_PAUSE) {
2094 return LB_STATUS_ERROR_INVALID;
2098 return LB_STATUS_SUCCESS;
2101 HAPI enum livebox_visible_state instance_visible_state(struct inst_info *inst)
2103 return inst->visible;
2106 HAPI int instance_set_visible_state(struct inst_info *inst, enum livebox_visible_state state)
2108 if (inst->visible == state) {
2109 return LB_STATUS_SUCCESS;
2115 if (inst->visible == LB_HIDE_WITH_PAUSE) {
2116 if (resume_livebox(inst) == 0) {
2117 inst->visible = state;
2120 instance_thaw_updator(inst);
2122 inst->visible = state;
2126 case LB_HIDE_WITH_PAUSE:
2127 if (pause_livebox(inst) == 0) {
2128 inst->visible = LB_HIDE_WITH_PAUSE;
2131 instance_freeze_updator(inst);
2135 return LB_STATUS_ERROR_INVALID;
2138 return LB_STATUS_SUCCESS;
2141 static void resize_cb(struct slave_node *slave, const struct packet *packet, void *data)
2143 struct resize_cbdata *cbdata = data;
2147 ErrPrint("RESIZE: Invalid packet\n");
2148 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_FAULT);
2149 instance_unref(cbdata->inst);
2154 if (packet_get(packet, "i", &ret) != 1) {
2155 ErrPrint("RESIZE: Invalid parameter\n");
2156 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_INVALID);
2157 instance_unref(cbdata->inst);
2162 if (ret == LB_STATUS_SUCCESS) {
2165 * else waiting the first update with new size
2167 if (cbdata->inst->lb.width == cbdata->w && cbdata->inst->lb.height == cbdata->h) {
2170 * Right after the viewer adds a new box,
2171 * Box has no size information, then it will try to use the default size,
2172 * After a box returns created event.
2174 * A box will start to generate default size content.
2175 * But the viewer doesn't know it,.
2177 * So the viewer will try to change the size of a box.
2179 * At that time, the provider gots the size changed event from the box.
2180 * So it sent the size changed event to the viewer.
2181 * But the viewer ignores it. if it doesn't care the size changed event.
2182 * (even if it cares the size changed event, there is a timing issue)
2184 * And the provider receives resize request,
2185 * right before send the size changed event.
2186 * but there is no changes about the size.
2188 * Now the view will waits size changed event forever.
2189 * To resolve this timing issue.
2191 * Check the size of a box from here.
2192 * And if the size is already updated, send the ALREADY event to the viewer
2193 * to get the size changed event callback correctly.
2195 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_ALREADY);
2196 DbgPrint("RESIZE: Livebox is already resized [%s - %dx%d]\n", instance_id(cbdata->inst), cbdata->w, cbdata->h);
2198 DbgPrint("RESIZE: Request is successfully sent [%s - %dx%d]\n", instance_id(cbdata->inst), cbdata->w, cbdata->h);
2201 DbgPrint("RESIZE: Livebox rejects the new size: %s - %dx%d (%d)\n", instance_id(cbdata->inst), cbdata->w, cbdata->h, ret);
2202 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, ret);
2205 instance_unref(cbdata->inst);
2209 HAPI int instance_resize(struct inst_info *inst, int w, int h)
2211 struct resize_cbdata *cbdata;
2212 struct packet *packet;
2216 ErrPrint("Invalid instance handle\n");
2217 return LB_STATUS_ERROR_INVALID;
2220 if (package_is_fault(inst->info)) {
2221 ErrPrint("Fault package: %s\n", package_name(inst->info));
2222 return LB_STATUS_ERROR_FAULT;
2225 cbdata = malloc(sizeof(*cbdata));
2227 ErrPrint("Heap: %s\n", strerror(errno));
2228 return LB_STATUS_ERROR_MEMORY;
2231 cbdata->inst = instance_ref(inst);
2235 /* NOTE: param is resued from here */
2236 packet = packet_create("resize", "ssii", package_name(inst->info), inst->id, w, h);
2238 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2239 instance_unref(cbdata->inst);
2241 return LB_STATUS_ERROR_FAULT;
2244 DbgPrint("RESIZE: [%s] resize[%dx%d]\n", instance_id(inst), w, h);
2245 ret = slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, resize_cb, cbdata, 0);
2249 static void set_period_cb(struct slave_node *slave, const struct packet *packet, void *data)
2252 struct period_cbdata *cbdata = data;
2253 struct packet *result;
2256 ret = LB_STATUS_ERROR_FAULT;
2260 if (packet_get(packet, "i", &ret) != 1) {
2261 ret = LB_STATUS_ERROR_INVALID;
2266 cbdata->inst->lb.period = cbdata->period;
2268 ErrPrint("Failed to set period %d\n", ret);
2272 result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->lb.period, package_name(cbdata->inst->info), cbdata->inst->id);
2274 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2276 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
2279 instance_unref(cbdata->inst);
2284 static Eina_Bool timer_updator_cb(void *data)
2286 struct period_cbdata *cbdata = data;
2287 struct inst_info *inst;
2289 struct packet *result;
2291 period = cbdata->period;
2292 inst = cbdata->inst;
2295 inst->lb.period = period;
2296 if (inst->update_timer) {
2297 if (inst->lb.period == 0.0f) {
2298 ecore_timer_del(inst->update_timer);
2299 inst->update_timer = NULL;
2301 util_timer_interval_set(inst->update_timer, inst->lb.period);
2303 } else if (inst->lb.period > 0.0f) {
2304 inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
2305 if (!inst->update_timer) {
2306 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
2308 timer_freeze(inst); /* Freeze the update timer as default */
2312 result = packet_create_noack("period_changed", "idss", 0, inst->lb.period, package_name(inst->info), inst->id);
2314 (void)CLIENT_SEND_EVENT(inst, result);
2316 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2319 instance_unref(inst);
2320 return ECORE_CALLBACK_CANCEL;
2323 HAPI int instance_set_period(struct inst_info *inst, double period)
2325 struct packet *packet;
2326 struct period_cbdata *cbdata;
2329 ErrPrint("Invalid instance handle\n");
2330 return LB_STATUS_ERROR_INVALID;
2333 if (package_is_fault(inst->info)) {
2334 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2335 return LB_STATUS_ERROR_FAULT;
2338 if (period < 0.0f) { /* Use the default period */
2339 period = package_period(inst->info);
2340 } else if (period > 0.0f && period < MINIMUM_PERIOD) {
2341 period = MINIMUM_PERIOD; /* defined at conf.h */
2344 cbdata = malloc(sizeof(*cbdata));
2346 ErrPrint("Heap: %s\n", strerror(errno));
2347 return LB_STATUS_ERROR_MEMORY;
2350 cbdata->period = period;
2351 cbdata->inst = instance_ref(inst);
2353 if (package_secured(inst->info)) {
2356 * Secured livebox doesn't need to send its update period to the slave.
2357 * Slave has no local timer for updating liveboxes
2359 * So update its timer at here.
2361 if (!ecore_timer_add(DELAY_TIME, timer_updator_cb, cbdata)) {
2362 timer_updator_cb(cbdata);
2364 return LB_STATUS_SUCCESS;
2367 packet = packet_create("set_period", "ssd", package_name(inst->info), inst->id, period);
2369 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2370 instance_unref(cbdata->inst);
2372 return LB_STATUS_ERROR_FAULT;
2375 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, set_period_cb, cbdata, 0);
2378 HAPI int instance_clicked(struct inst_info *inst, const char *event, double timestamp, double x, double y)
2380 struct packet *packet;
2383 ErrPrint("Invalid instance handle\n");
2384 return LB_STATUS_ERROR_INVALID;
2387 if (package_is_fault(inst->info)) {
2388 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2389 return LB_STATUS_ERROR_FAULT;
2392 /* NOTE: param is resued from here */
2393 packet = packet_create_noack("clicked", "sssddd", package_name(inst->info), inst->id, event, timestamp, x, y);
2395 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2396 return LB_STATUS_ERROR_FAULT;
2399 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
2402 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)
2404 const char *pkgname;
2406 struct slave_node *slave;
2407 struct packet *packet;
2408 struct pkg_info *pkg;
2410 pkg = instance_package(inst);
2411 pkgname = package_name(pkg);
2412 id = instance_id(inst);
2413 if (!pkgname || !id) {
2414 return LB_STATUS_ERROR_INVALID;
2417 slave = package_slave(pkg);
2419 return LB_STATUS_ERROR_INVALID;
2422 packet = packet_create_noack("script", "ssssddddddi",
2428 return LB_STATUS_ERROR_FAULT;
2431 return slave_rpc_request_only(slave, pkgname, packet, 0);
2434 HAPI int instance_text_signal_emit(struct inst_info *inst, const char *emission, const char *source, double sx, double sy, double ex, double ey)
2436 struct packet *packet;
2439 ErrPrint("Invalid instance handle\n");
2440 return LB_STATUS_ERROR_INVALID;
2443 if (package_is_fault(inst->info)) {
2444 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2445 return LB_STATUS_ERROR_FAULT;
2448 packet = packet_create_noack("text_signal", "ssssdddd", package_name(inst->info), inst->id, emission, source, sx, sy, ex, ey);
2450 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2451 return LB_STATUS_ERROR_FAULT;
2454 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
2457 static void change_group_cb(struct slave_node *slave, const struct packet *packet, void *data)
2459 struct change_group_cbdata *cbdata = data;
2460 struct packet *result;
2464 DbgFree(cbdata->cluster);
2465 DbgFree(cbdata->category);
2466 ret = LB_STATUS_ERROR_FAULT;
2470 if (packet_get(packet, "i", &ret) != 1) {
2471 ErrPrint("Invalid packet\n");
2472 DbgFree(cbdata->cluster);
2473 DbgFree(cbdata->category);
2474 ret = LB_STATUS_ERROR_INVALID;
2479 DbgFree(cbdata->inst->cluster);
2480 cbdata->inst->cluster = cbdata->cluster;
2482 DbgFree(cbdata->inst->category);
2483 cbdata->inst->category = cbdata->category;
2485 DbgFree(cbdata->cluster);
2486 DbgFree(cbdata->category);
2490 result = packet_create_noack("group_changed", "ssiss",
2491 package_name(cbdata->inst->info), cbdata->inst->id, ret,
2492 cbdata->inst->cluster, cbdata->inst->category);
2494 ErrPrint("Failed to build a packet %s\n", package_name(cbdata->inst->info));
2496 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2499 instance_unref(cbdata->inst);
2503 HAPI int instance_change_group(struct inst_info *inst, const char *cluster, const char *category)
2505 struct packet *packet;
2506 struct change_group_cbdata *cbdata;
2509 ErrPrint("Invalid instance handle\n");
2510 return LB_STATUS_ERROR_INVALID;
2513 if (package_is_fault(inst->info)) {
2514 ErrPrint("Fault package [%s]\n", package_name(inst->info));
2515 return LB_STATUS_ERROR_FAULT;
2518 cbdata = malloc(sizeof(*cbdata));
2520 ErrPrint("Heap: %s\n", strerror(errno));
2521 return LB_STATUS_ERROR_MEMORY;
2524 cbdata->cluster = strdup(cluster);
2525 if (!cbdata->cluster) {
2526 ErrPrint("Heap: %s\n", strerror(errno));
2528 return LB_STATUS_ERROR_MEMORY;
2531 cbdata->category = strdup(category);
2532 if (!cbdata->category) {
2533 ErrPrint("Heap: %s\n", strerror(errno));
2534 DbgFree(cbdata->cluster);
2536 return LB_STATUS_ERROR_MEMORY;
2539 cbdata->inst = instance_ref(inst);
2541 packet = packet_create("change_group","ssss", package_name(inst->info), inst->id, cluster, category);
2543 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2544 instance_unref(cbdata->inst);
2545 DbgFree(cbdata->category);
2546 DbgFree(cbdata->cluster);
2548 return LB_STATUS_ERROR_FAULT;
2551 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, change_group_cb, cbdata, 0);
2554 HAPI const char * const instance_auto_launch(const struct inst_info *inst)
2556 return package_auto_launch(inst->info);
2559 HAPI const int const instance_priority(const struct inst_info *inst)
2561 return inst->lb.priority;
2564 HAPI const struct client_node *const instance_client(const struct inst_info *inst)
2566 return inst->client;
2569 HAPI const int const instance_timeout(const struct inst_info *inst)
2571 return package_timeout(inst->info);
2574 HAPI const double const instance_period(const struct inst_info *inst)
2576 return inst->lb.period;
2579 HAPI const int const instance_lb_width(const struct inst_info *inst)
2581 return inst->lb.width;
2584 HAPI const int const instance_lb_height(const struct inst_info *inst)
2586 return inst->lb.height;
2589 HAPI const int const instance_pd_width(const struct inst_info *inst)
2591 return inst->pd.width;
2594 HAPI const int const instance_pd_height(const struct inst_info *inst)
2596 return inst->pd.height;
2599 HAPI struct pkg_info *const instance_package(const struct inst_info *inst)
2604 HAPI struct script_info *const instance_lb_script(const struct inst_info *inst)
2606 return (package_lb_type(inst->info) == LB_TYPE_SCRIPT) ? inst->lb.canvas.script : NULL;
2609 HAPI struct script_info *const instance_pd_script(const struct inst_info *inst)
2611 return (package_pd_type(inst->info) == PD_TYPE_SCRIPT) ? inst->pd.canvas.script : NULL;
2614 HAPI struct buffer_info *const instance_lb_buffer(const struct inst_info *inst)
2616 return (package_lb_type(inst->info) == LB_TYPE_BUFFER) ? inst->lb.canvas.buffer : NULL;
2619 HAPI struct buffer_info *const instance_pd_buffer(const struct inst_info *inst)
2621 return (package_pd_type(inst->info) == PD_TYPE_BUFFER) ? inst->pd.canvas.buffer : NULL;
2624 HAPI const char *const instance_id(const struct inst_info *inst)
2629 HAPI const char *const instance_content(const struct inst_info *inst)
2631 return inst->content;
2634 HAPI const char *const instance_category(const struct inst_info *inst)
2636 return inst->category;
2639 HAPI const char *const instance_cluster(const struct inst_info *inst)
2641 return inst->cluster;
2644 HAPI const char * const instance_title(const struct inst_info *inst)
2649 HAPI const double const instance_timestamp(const struct inst_info *inst)
2651 return inst->timestamp;
2654 HAPI const enum instance_state const instance_state(const struct inst_info *inst)
2659 HAPI int instance_destroyed(struct inst_info *inst)
2661 switch (inst->state) {
2663 case INST_REQUEST_TO_ACTIVATE:
2666 * No other clients know the existence of this instance,
2667 * only who added this knows it.
2668 * So send deleted event to only it.
2670 DbgPrint("Send deleted event - unicast - %p\n", inst->client);
2671 instance_unicast_deleted_event(inst, NULL);
2672 instance_state_reset(inst);
2673 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2675 case INST_REQUEST_TO_REACTIVATE:
2676 case INST_REQUEST_TO_DESTROY:
2677 case INST_ACTIVATED:
2678 DbgPrint("Send deleted event - multicast\n");
2679 instance_broadcast_deleted_event(inst);
2680 instance_state_reset(inst);
2681 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2682 case INST_DESTROYED:
2685 return LB_STATUS_ERROR_INVALID;
2688 return LB_STATUS_SUCCESS;
2692 * Invoked when a slave is activated
2694 HAPI int instance_recover_state(struct inst_info *inst)
2698 if (inst->changing_state) {
2699 DbgPrint("Doesn't need to recover the state\n");
2700 return LB_STATUS_SUCCESS;
2703 switch (inst->state) {
2704 case INST_ACTIVATED:
2705 case INST_REQUEST_TO_REACTIVATE:
2706 case INST_REQUEST_TO_DESTROY:
2707 switch (inst->requested_state) {
2708 case INST_ACTIVATED:
2709 DbgPrint("Req. to RE-ACTIVATED (%s)\n", package_name(inst->info));
2710 instance_state_reset(inst);
2711 instance_reactivate(inst);
2714 case INST_DESTROYED:
2715 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2716 instance_state_reset(inst);
2717 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2724 case INST_REQUEST_TO_ACTIVATE:
2725 switch (inst->requested_state) {
2726 case INST_ACTIVATED:
2728 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2729 instance_state_reset(inst);
2730 if (instance_activate(inst) < 0) {
2731 DbgPrint("Failed to reactivate the instance\n");
2732 instance_broadcast_deleted_event(inst);
2733 instance_state_reset(inst);
2734 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2739 case INST_DESTROYED:
2740 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2741 instance_state_reset(inst);
2742 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2749 case INST_DESTROYED:
2758 * Invoked when a slave is deactivated
2760 HAPI int instance_need_slave(struct inst_info *inst)
2764 if (inst->client && client_is_faulted(inst->client)) {
2767 * In this case, the client is faulted(disconnected)
2768 * when the client is deactivated, its liveboxes should be removed too.
2769 * So if the current inst is created by the faulted client,
2770 * remove it and don't try to recover its states
2773 DbgPrint("CLIENT FAULT: Req. to DESTROYED (%s)\n", package_name(inst->info));
2774 switch (inst->state) {
2776 case INST_ACTIVATED:
2777 case INST_REQUEST_TO_REACTIVATE:
2778 case INST_REQUEST_TO_DESTROY:
2779 case INST_REQUEST_TO_ACTIVATE:
2780 instance_state_reset(inst);
2781 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2783 case INST_DESTROYED:
2787 return LB_STATUS_SUCCESS;
2790 switch (inst->state) {
2791 case INST_ACTIVATED:
2792 case INST_REQUEST_TO_REACTIVATE:
2793 case INST_REQUEST_TO_DESTROY:
2794 switch (inst->requested_state) {
2796 case INST_ACTIVATED:
2797 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2800 case INST_DESTROYED:
2801 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2802 instance_state_reset(inst);
2803 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2810 case INST_REQUEST_TO_ACTIVATE:
2811 switch (inst->requested_state) {
2813 case INST_ACTIVATED:
2814 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2817 case INST_DESTROYED:
2818 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2819 instance_state_reset(inst);
2820 instance_destroy(inst, INSTANCE_DESTROY_DEFAULT);
2826 case INST_DESTROYED:
2834 HAPI int instance_forward_packet(struct inst_info *inst, struct packet *packet)
2836 return CLIENT_SEND_EVENT(inst, packet);
2839 HAPI int instance_send_access_status(struct inst_info *inst, int status)
2841 struct packet *packet;
2843 packet = packet_create_noack("access_status", "ssi", package_name(inst->info), inst->id, status);
2845 ErrPrint("Failed to build a packet\n");
2846 return LB_STATUS_ERROR_FAULT;
2849 return CLIENT_SEND_EVENT(inst, packet);
2852 HAPI void instance_slave_set_pd_pos(struct inst_info *inst, double x, double y)
2858 HAPI void instance_slave_get_pd_pos(struct inst_info *inst, double *x, double *y)
2869 HAPI int instance_slave_open_pd(struct inst_info *inst, struct client_node *client)
2871 const char *pkgname;
2873 struct packet *packet;
2874 struct slave_node *slave;
2875 const struct pkg_info *info;
2879 client = inst->pd.owner;
2881 ErrPrint("Client is not valid\n");
2882 return LB_STATUS_ERROR_INVALID;
2884 } else if (inst->pd.owner) {
2885 if (inst->pd.owner != client) {
2886 ErrPrint("Client is already owned\n");
2887 return LB_STATUS_ERROR_ALREADY;
2891 info = instance_package(inst);
2893 ErrPrint("No package info\n");
2894 return LB_STATUS_ERROR_INVALID;
2897 slave = package_slave(info);
2899 ErrPrint("No slave\n");
2900 return LB_STATUS_ERROR_FAULT;
2903 pkgname = package_name(info);
2904 id = instance_id(inst);
2906 if (!pkgname || !id) {
2907 ErrPrint("pkgname[%s] id[%s]\n", pkgname, id);
2908 return LB_STATUS_ERROR_INVALID;
2911 packet = packet_create_noack("pd_show", "ssiidd", pkgname, id, instance_pd_width(inst), instance_pd_height(inst), inst->pd.x, inst->pd.y);
2913 ErrPrint("Failed to create a packet\n");
2914 return LB_STATUS_ERROR_FAULT;
2919 * Do not return from here even though we failed to freeze the TTL timer.
2920 * Because the TTL timer is not able to be exists.
2921 * So we can ignore this error.
2923 (void)slave_freeze_ttl(slave);
2925 DbgPrint("PERF_DBOX\n");
2926 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2928 ErrPrint("Unable to send request to slave\n");
2931 * Also we can ignore the TTL timer at here too ;)
2933 (void)slave_thaw_ttl(slave);
2939 * If a client is disconnected, the slave has to close the PD
2940 * So the pd_buffer_close_cb/pd_script_close_cb will catch the disconnection event
2941 * then it will send the close request to the slave
2943 if (package_pd_type(info) == PD_TYPE_BUFFER) {
2945 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) < 0) {
2946 instance_unref(inst);
2948 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
2950 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) < 0) {
2951 instance_unref(inst);
2955 inst->pd.owner = client;
2959 HAPI int instance_slave_close_pd(struct inst_info *inst, struct client_node *client)
2961 const char *pkgname;
2963 struct packet *packet;
2964 struct slave_node *slave;
2965 struct pkg_info *pkg;
2968 if (inst->pd.owner != client) {
2969 ErrPrint("Has no permission\n");
2970 return LB_STATUS_ERROR_PERMISSION;
2973 pkg = instance_package(inst);
2975 ErrPrint("No package info\n");
2976 return LB_STATUS_ERROR_INVALID;
2979 slave = package_slave(pkg);
2981 ErrPrint("No assigned slave\n");
2982 return LB_STATUS_ERROR_FAULT;
2985 pkgname = package_name(pkg);
2986 id = instance_id(inst);
2988 if (!pkgname || !id) {
2989 ErrPrint("pkgname[%s] & id[%s] is not valid\n", pkgname, id);
2990 return LB_STATUS_ERROR_INVALID;
2993 packet = packet_create_noack("pd_hide", "ss", pkgname, id);
2995 ErrPrint("Failed to create a packet\n");
2996 return LB_STATUS_ERROR_FAULT;
2999 slave_thaw_ttl(slave);
3001 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
3002 release_resource_for_closing_pd(pkg, inst, client);
3003 inst->pd.owner = NULL;
3004 DbgPrint("PERF_DBOX\n");
3008 HAPI int instance_client_pd_created(struct inst_info *inst, int status)
3010 struct packet *packet;
3014 if (inst->pd.need_to_send_close_event) {
3015 DbgPrint("PD is already created\n");
3016 return LB_STATUS_ERROR_INVALID;
3019 switch (package_pd_type(inst->info)) {
3020 case PD_TYPE_SCRIPT:
3021 buf_id = fb_id(script_handler_fb(inst->pd.canvas.script));
3023 case PD_TYPE_BUFFER:
3024 buf_id = buffer_handler_id(inst->pd.canvas.buffer);
3032 inst->pd.need_to_send_close_event = (status == 0);
3034 packet = packet_create_noack("pd_created", "sssiii",
3035 package_name(inst->info), inst->id, buf_id,
3036 inst->pd.width, inst->pd.height, status);
3038 ErrPrint("Failed to create a packet\n");
3039 return LB_STATUS_ERROR_FAULT;
3042 ret = CLIENT_SEND_EVENT(inst, packet);
3044 if (inst->pd.need_to_send_close_event && inst->pd.pended_update_cnt) {
3045 DbgPrint("Apply pended desc(%d) - %s\n", inst->pd.pended_update_cnt, inst->pd.pended_update_desc);
3046 instance_pd_updated_by_instance(inst, inst->pd.pended_update_desc);
3047 inst->pd.pended_update_cnt = 0;
3048 DbgFree(inst->pd.pended_update_desc);
3049 inst->pd.pended_update_desc = NULL;
3055 HAPI int instance_client_pd_destroyed(struct inst_info *inst, int status)
3057 if (!inst->pd.need_to_send_close_event) {
3058 ErrPrint("PD is not created\n");
3059 return LB_STATUS_ERROR_INVALID;
3062 inst->pd.need_to_send_close_event = 0;
3064 return send_pd_destroyed_to_client(inst, status);
3067 HAPI int instance_add_client(struct inst_info *inst, struct client_node *client)
3069 if (inst->client == client) {
3070 ErrPrint("Owner cannot be the viewer\n");
3071 return LB_STATUS_ERROR_INVALID;
3074 DbgPrint("%d is added to the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
3075 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst) < 0) {
3076 ErrPrint("Failed to add a deactivate callback\n");
3077 return LB_STATUS_ERROR_FAULT;
3081 inst->client_list = eina_list_append(inst->client_list, client);
3082 return LB_STATUS_SUCCESS;
3085 HAPI int instance_del_client(struct inst_info *inst, struct client_node *client)
3087 if (inst->client == client) {
3088 ErrPrint("Owner is not in the viewer list\n");
3089 return LB_STATUS_ERROR_INVALID;
3092 client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst);
3093 viewer_deactivated_cb(client, inst);
3094 return LB_STATUS_SUCCESS;
3097 HAPI int instance_has_client(struct inst_info *inst, struct client_node *client)
3099 return !!eina_list_data_find(inst->client_list, client);
3102 HAPI void *instance_client_list(struct inst_info *inst)
3104 return inst->client_list;
3107 HAPI int instance_init(void)
3109 if (!strcasecmp(PROVIDER_METHOD, "shm")) {
3110 s_info.env_buf_type = BUFFER_TYPE_SHM;
3111 } else if (!strcasecmp(PROVIDER_METHOD, "pixmap")) {
3112 s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
3114 /* Default method is BUFFER_TYPE_FILE */
3116 return LB_STATUS_SUCCESS;
3119 HAPI int instance_fini(void)
3121 return LB_STATUS_SUCCESS;
3124 static inline struct tag_item *find_tag_item(struct inst_info *inst, const char *tag)
3126 struct tag_item *item;
3129 EINA_LIST_FOREACH(inst->data_list, l, item) {
3130 if (!strcmp(item->tag, tag)) {
3138 HAPI int instance_set_data(struct inst_info *inst, const char *tag, void *data)
3140 struct tag_item *item;
3142 item = find_tag_item(inst, tag);
3144 item = malloc(sizeof(*item));
3146 ErrPrint("Heap: %s\n", strerror(errno));
3147 return LB_STATUS_ERROR_MEMORY;
3150 item->tag = strdup(tag);
3152 ErrPrint("Heap: %s\n", strerror(errno));
3154 return LB_STATUS_ERROR_MEMORY;
3157 inst->data_list = eina_list_append(inst->data_list, item);
3161 inst->data_list = eina_list_remove(inst->data_list, item);
3168 return LB_STATUS_SUCCESS;
3171 HAPI void *instance_del_data(struct inst_info *inst, const char *tag)
3173 struct tag_item *item;
3176 item = find_tag_item(inst, tag);
3181 inst->data_list = eina_list_remove(inst->data_list, item);
3189 HAPI void *instance_get_data(struct inst_info *inst, const char *tag)
3191 struct tag_item *item;
3193 item = find_tag_item(inst, tag);
3201 HAPI struct client_node *instance_pd_owner(struct inst_info *inst)
3203 return inst->pd.owner;