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 */
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 */
110 enum livebox_visible_state visible;
118 struct script_info *script;
119 struct buffer_info *buffer;
122 const char *auto_launch;
134 struct script_info *script;
135 struct buffer_info *buffer;
138 struct client_node *owner;
139 int is_opened_for_reactivate;
140 int need_to_send_close_event;
141 char *pended_update_desc;
142 int pended_update_cnt;
145 struct client_node *client; /*!< Owner - creator */
146 Eina_List *client_list; /*!< Viewer list */
149 Ecore_Timer *update_timer; /*!< Only used for secured livebox */
151 Eina_List *delete_event_list;
153 Eina_List *data_list;
156 #define CLIENT_SEND_EVENT(instance, packet) ((instance)->client ? client_rpc_async_request((instance)->client, (packet)) : client_broadcast((instance), (packet)))
158 static Eina_Bool update_timer_cb(void *data);
160 static inline void timer_thaw(struct inst_info *inst)
167 ecore_timer_thaw(inst->update_timer);
168 period = ecore_timer_interval_get(inst->update_timer);
169 pending = ecore_timer_pending_get(inst->update_timer);
170 delay = util_time_delay_for_compensation(period) - pending;
171 ecore_timer_delay(inst->update_timer, delay);
172 DbgPrint("Compensated: %lf\n", delay);
174 if (inst->sleep_at == 0.0f)
177 sleep_time = util_timestamp() - inst->sleep_at;
178 if (sleep_time > pending) {
179 DbgPrint("Update time elapsed\n");
180 (void)update_timer_cb(inst);
183 inst->sleep_at = 0.0f;
186 static inline void timer_freeze(struct inst_info *inst)
189 ecore_timer_freeze(inst->update_timer);
191 if (ecore_timer_interval_get(inst->update_timer) <= 1.0f)
194 if (gettimeofday(&tv, NULL) < 0) {
195 ErrPrint("gettimeofday: %s\n", strerror(errno));
199 inst->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
203 static int viewer_deactivated_cb(struct client_node *client, void *data)
205 struct inst_info *inst = data;
207 DbgPrint("%d is deleted from the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
208 if (!eina_list_data_find(inst->client_list, client)) {
209 DbgPrint("Not found\n");
210 return LB_STATUS_ERROR_NOT_EXIST;
213 inst->client_list = eina_list_remove(inst->client_list, client);
214 if (!inst->client_list && !inst->client) {
215 DbgPrint("Has no clients\n");
216 instance_destroy(inst);
219 instance_unref(inst);
220 return -1; /*!< Remove this callback from the cb list */
223 static inline int pause_livebox(struct inst_info *inst)
225 struct packet *packet;
227 packet = packet_create_noack("lb_pause", "ss", package_name(inst->info), inst->id);
229 ErrPrint("Failed to create a new packet\n");
230 return LB_STATUS_ERROR_FAULT;
233 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
236 /*! \TODO Wake up the freeze'd timer */
237 static inline int resume_livebox(struct inst_info *inst)
239 struct packet *packet;
241 packet = packet_create_noack("lb_resume", "ss", package_name(inst->info), inst->id);
243 ErrPrint("Failed to create a new packet\n");
244 return LB_STATUS_ERROR_FAULT;
247 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
250 static inline int instance_recover_visible_state(struct inst_info *inst)
254 switch (inst->visible) {
257 instance_thaw_updator(inst);
261 case LB_HIDE_WITH_PAUSE:
262 ret = pause_livebox(inst);
264 instance_freeze_updator(inst);
267 ret = LB_STATUS_ERROR_INVALID;
271 DbgPrint("Visible state is recovered to %d\n", ret);
275 static inline void instance_send_update_mode_event(struct inst_info *inst, int active_mode, int status)
277 struct packet *packet;
281 ErrPrint("Instance info is not ready to use\n");
285 pkgname = package_name(inst->info);
287 packet = packet_create_noack("update_mode", "ssii", pkgname, inst->id, status, active_mode);
289 CLIENT_SEND_EVENT(inst, packet);
291 ErrPrint("Failed to send update mode event\n");
294 static inline void instance_send_resized_event(struct inst_info *inst, int is_pd, int w, int h, int status)
296 struct packet *packet;
297 enum lb_type lb_type;
302 ErrPrint("Instance info is not ready to use\n");
306 pkgname = package_name(inst->info);
308 lb_type = package_lb_type(inst->info);
309 if (lb_type == LB_TYPE_SCRIPT)
310 id = fb_id(script_handler_fb(inst->lb.canvas.script));
311 else if (lb_type == LB_TYPE_BUFFER)
312 id = buffer_handler_id(inst->lb.canvas.buffer);
316 DbgPrint("Size is changed to %dx%d (%s) %s\n", w, h, id, is_pd ? "pd" : "lb");
318 packet = packet_create_noack("size_changed", "sssiiii", pkgname, inst->id, id, is_pd, w, h, status);
320 CLIENT_SEND_EVENT(inst, packet);
322 ErrPrint("Failed to send size changed event\n");
325 static void update_mode_cb(struct slave_node *slave, const struct packet *packet, void *data)
327 struct update_mode_cbdata *cbdata = data;
331 ErrPrint("Invalid packet\n");
332 instance_send_update_mode_event(cbdata->inst, cbdata->active_update, LB_STATUS_ERROR_FAULT);
333 instance_unref(cbdata->inst);
338 if (packet_get(packet, "i", &ret) != 1) {
339 ErrPrint("Invalid parameters\n");
340 instance_send_update_mode_event(cbdata->inst, cbdata->active_update, LB_STATUS_ERROR_INVALID);
341 instance_unref(cbdata->inst);
346 if (ret == LB_STATUS_SUCCESS)
347 cbdata->inst->active_update = cbdata->active_update;
349 instance_send_update_mode_event(cbdata->inst, cbdata->active_update, ret);
351 instance_unref(cbdata->inst);
355 HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_node *client)
357 struct packet *packet;
358 enum lb_type lb_type;
359 enum pd_type pd_type;
364 client = inst->client;
366 return LB_STATUS_SUCCESS;
369 lb_type = package_lb_type(inst->info);
370 pd_type = package_pd_type(inst->info);
372 if (lb_type == LB_TYPE_SCRIPT)
373 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
374 else if (lb_type == LB_TYPE_BUFFER)
375 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
379 if (pd_type == PD_TYPE_SCRIPT)
380 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
381 else if (pd_type == PD_TYPE_BUFFER)
382 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
386 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
388 package_name(inst->info), inst->id, inst->content,
389 inst->lb.width, inst->lb.height,
390 inst->pd.width, inst->pd.height,
391 inst->cluster, inst->category,
393 inst->lb.auto_launch,
395 package_size_list(inst->info),
397 package_pinup(inst->info),
399 inst->lb.period, inst->title,
402 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
403 return LB_STATUS_ERROR_FAULT;
406 return client_rpc_async_request(client, packet);
409 static int update_client_list(struct client_node *client, void *data)
411 struct inst_info *inst = data;
413 if (!instance_has_client(inst, client))
414 instance_add_client(inst, client);
416 return LB_STATUS_SUCCESS;
419 static int instance_broadcast_created_event(struct inst_info *inst)
421 struct packet *packet;
422 enum lb_type lb_type;
423 enum pd_type pd_type;
427 lb_type = package_lb_type(inst->info);
428 pd_type = package_pd_type(inst->info);
430 if (lb_type == LB_TYPE_SCRIPT)
431 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
432 else if (lb_type == LB_TYPE_BUFFER)
433 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
437 if (pd_type == PD_TYPE_SCRIPT)
438 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
439 else if (pd_type == PD_TYPE_BUFFER)
440 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
445 client_browse_list(inst->cluster, inst->category, update_client_list, inst);
447 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
449 package_name(inst->info), inst->id, inst->content,
450 inst->lb.width, inst->lb.height,
451 inst->pd.width, inst->pd.height,
452 inst->cluster, inst->category,
454 inst->lb.auto_launch,
456 package_size_list(inst->info),
458 package_pinup(inst->info),
460 inst->lb.period, inst->title,
463 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
464 return LB_STATUS_ERROR_FAULT;
467 return CLIENT_SEND_EVENT(inst, packet);
470 HAPI int instance_unicast_deleted_event(struct inst_info *inst, struct client_node *client)
472 struct packet *packet;
475 client = inst->client;
477 return LB_STATUS_ERROR_INVALID;
480 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
482 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
483 return LB_STATUS_ERROR_FAULT;
486 return client_rpc_async_request(client, packet);
489 static int instance_broadcast_deleted_event(struct inst_info *inst)
491 struct packet *packet;
492 struct client_node *client;
497 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
499 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
500 return LB_STATUS_ERROR_FAULT;
503 ret = CLIENT_SEND_EVENT(inst, packet);
505 EINA_LIST_FOREACH_SAFE(inst->client_list, l, n, client) {
506 instance_del_client(inst, client);
512 static int client_deactivated_cb(struct client_node *client, void *data)
514 struct inst_info *inst = data;
515 instance_destroy(inst);
516 return LB_STATUS_SUCCESS;
519 static int send_pd_destroyed_to_client(struct inst_info *inst, int status)
521 struct packet *packet;
523 packet = packet_create_noack("pd_destroyed", "ssi", package_name(inst->info), inst->id, status);
525 ErrPrint("Failed to create a packet\n");
526 return LB_STATUS_ERROR_FAULT;
529 return CLIENT_SEND_EVENT(inst, packet);
532 static inline void invoke_delete_callbacks(struct inst_info *inst)
536 struct event_item *item;
538 EINA_LIST_FOREACH_SAFE(inst->delete_event_list, l, n, item) {
539 if (item->event_cb(inst, item->data) < 0) {
540 if (eina_list_data_find(inst->delete_event_list, item)) {
541 inst->delete_event_list = eina_list_remove(inst->delete_event_list, item);
548 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)
550 struct event_item *item;
553 return LB_STATUS_ERROR_INVALID;
556 case INSTANCE_EVENT_DESTROY:
557 item = malloc(sizeof(*item));
559 ErrPrint("Heap: %s\n", strerror(errno));
560 return LB_STATUS_ERROR_MEMORY;
563 item->event_cb = event_cb;
566 inst->delete_event_list = eina_list_append(inst->delete_event_list, item);
569 return LB_STATUS_ERROR_INVALID;
572 return LB_STATUS_SUCCESS;
575 HAPI int instance_event_callback_del(struct inst_info *inst, enum instance_event type, int (*event_cb)(struct inst_info *inst, void *data))
579 struct event_item *item;
582 case INSTANCE_EVENT_DESTROY:
583 EINA_LIST_FOREACH_SAFE(inst->delete_event_list, l, n, item) {
584 if (item->event_cb == event_cb) {
585 inst->delete_event_list = eina_list_remove(inst->delete_event_list, item);
587 return LB_STATUS_SUCCESS;
595 return LB_STATUS_ERROR_NOT_EXIST;
598 static inline void destroy_instance(struct inst_info *inst)
600 struct pkg_info *pkg;
601 enum lb_type lb_type;
602 enum pd_type pd_type;
603 struct slave_node *slave;
604 struct event_item *item;
605 struct tag_item *tag_item;
607 invoke_delete_callbacks(inst);
611 lb_type = package_lb_type(pkg);
612 pd_type = package_pd_type(pkg);
613 slave = package_slave(inst->info);
615 DbgPrint("Instance is destroyed (%p), slave(%p)\n", inst, slave);
617 if (inst->pd.need_to_send_close_event)
618 send_pd_destroyed_to_client(inst, 0);
620 if (lb_type == LB_TYPE_SCRIPT) {
621 script_handler_unload(inst->lb.canvas.script, 0);
622 script_handler_destroy(inst->lb.canvas.script);
623 } else if (lb_type == LB_TYPE_BUFFER) {
624 buffer_handler_unload(inst->lb.canvas.buffer);
625 buffer_handler_destroy(inst->lb.canvas.buffer);
628 if (pd_type == PD_TYPE_SCRIPT) {
629 script_handler_unload(inst->pd.canvas.script, 1);
630 script_handler_destroy(inst->pd.canvas.script);
631 } else if (pd_type == PD_TYPE_BUFFER) {
632 buffer_handler_unload(inst->pd.canvas.buffer);
633 buffer_handler_destroy(inst->pd.canvas.buffer);
637 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
638 client_unref(inst->client);
641 if (inst->update_timer)
642 ecore_timer_del(inst->update_timer);
644 EINA_LIST_FREE(inst->data_list, tag_item) {
645 DbgPrint("Tagged item[%s] %p\n", tag_item->tag, tag_item->data);
653 * inst->lb.auto_launch
655 * will be released by the package object
656 * it is readonly value for instances
658 EINA_LIST_FREE(inst->delete_event_list, item) {
661 DbgFree(inst->category);
662 DbgFree(inst->cluster);
663 DbgFree(inst->content);
664 DbgFree(inst->title);
665 util_unlink(util_uri_to_path(inst->id));
667 package_del_instance(inst->info, inst);
670 slave = slave_unload_instance(slave);
673 static Eina_Bool update_timer_cb(void *data)
675 struct inst_info *inst = (struct inst_info *)data;
677 DbgPrint("Update instance %s (%s) %s/%s\n", package_name(inst->info), inst->id, inst->cluster, inst->category);
678 slave_rpc_request_update(package_name(inst->info), inst->id, inst->cluster, inst->category);
679 return ECORE_CALLBACK_RENEW;
682 static inline int fork_package(struct inst_info *inst, const char *pkgname)
684 struct pkg_info *info;
687 info = package_find(pkgname);
689 ErrPrint("%s is not found\n", pkgname);
690 return LB_STATUS_ERROR_NOT_EXIST;
693 len = strlen(SCHEMA_FILE "%s%s_%d_%lf.png") + strlen(IMAGE_PATH) + strlen(package_name(info)) + 50;
694 inst->id = malloc(len);
696 ErrPrint("Heap: %s\n", strerror(errno));
697 return LB_STATUS_ERROR_MEMORY;
700 snprintf(inst->id, len, SCHEMA_FILE "%s%s_%d_%lf.png", IMAGE_PATH, package_name(info), client_pid(inst->client), inst->timestamp);
701 inst->lb.auto_launch = package_auto_launch(info);
703 instance_set_pd_size(inst, package_pd_width(info), package_pd_height(info));
705 inst->lb.timeout = package_timeout(info);
706 inst->lb.period = package_period(info);
710 if (package_secured(info)) {
711 if (inst->lb.period > 0.0f) {
712 DbgPrint("Register the update timer for secured livebox [%s]\n", package_name(info));
713 inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
714 if (!inst->update_timer)
715 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
717 timer_freeze(inst); /* Freeze the update timer as default */
719 DbgPrint("secured livebox [%s] has no period (%lf)\n", package_name(info), inst->lb.period);
720 inst->update_timer = NULL;
724 return LB_STATUS_SUCCESS;
727 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)
729 struct inst_info *inst;
731 inst = calloc(1, sizeof(*inst));
733 ErrPrint("Heap: %s\n", strerror(errno));
737 inst->timestamp = timestamp;
738 inst->lb.width = width;
739 inst->lb.height = height;
741 inst->content = strdup(content);
742 if (!inst->content) {
743 ErrPrint("Heap: %s\n", strerror(errno));
748 inst->cluster = strdup(cluster);
749 if (!inst->cluster) {
750 ErrPrint("Heap: %s\n", strerror(errno));
751 DbgFree(inst->content);
756 inst->category = strdup(category);
757 if (!inst->category) {
758 ErrPrint("Heap: %s\n", strerror(errno));
759 DbgFree(inst->cluster);
760 DbgFree(inst->content);
765 inst->title = strdup(DEFAULT_TITLE); /*!< Use the DEFAULT Title "" */
767 ErrPrint("Heap: %s\n", strerror(errno));
768 DbgFree(inst->category);
769 DbgFree(inst->cluster);
770 DbgFree(inst->content);
776 inst->client = client_ref(client);
777 client_event_callback_add(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
780 if (fork_package(inst, pkgname) < 0) {
781 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
782 client_unref(inst->client);
783 DbgFree(inst->title);
784 DbgFree(inst->category);
785 DbgFree(inst->cluster);
786 DbgFree(inst->content);
791 inst->state = INST_INIT;
792 inst->requested_state = INST_INIT;
795 if (package_add_instance(inst->info, inst) < 0) {
796 instance_state_reset(inst);
797 instance_destroy(inst);
801 slave_load_instance(package_slave(inst->info));
803 if (instance_activate(inst) < 0) {
804 instance_state_reset(inst);
805 instance_destroy(inst);
812 HAPI struct inst_info *instance_ref(struct inst_info *inst)
821 HAPI struct inst_info *instance_unref(struct inst_info *inst)
826 if (inst->refcnt == 0) {
827 ErrPrint("Instance refcnt is not valid\n");
832 if (inst->refcnt == 0) {
833 destroy_instance(inst);
840 static void deactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
842 struct inst_info *inst = data;
843 struct pkg_info *info;
848 * In this callback, we cannot trust the "client" information.
849 * It could be cleared before reach to here.
853 DbgPrint("Consuming a request of a dead process\n");
856 * The instance_reload will care this.
857 * And it will be called from the slave activate callback.
859 inst->changing_state = 0;
860 instance_unref(inst);
864 if (packet_get(packet, "i", &ret) != 1) {
865 ErrPrint("Invalid argument\n");
866 inst->changing_state = 0;
867 instance_unref(inst);
871 if (inst->state == INST_DESTROYED) {
875 * Do nothing at here anymore.
877 inst->changing_state = 0;
878 instance_unref(inst);
886 * Successfully unloaded
888 switch (inst->requested_state) {
890 DbgPrint("REQ: ACTIVATED\n");
891 instance_state_reset(inst);
892 instance_reactivate(inst);
896 instance_broadcast_deleted_event(inst);
897 instance_state_reset(inst);
898 instance_destroy(inst);
899 DbgPrint("== %s\n", package_name(info));
901 /*!< Unable to reach here */
906 case LB_STATUS_ERROR_INVALID:
909 * Slave has no instance of this package.
911 case LB_STATUS_ERROR_NOT_EXIST:
914 * This instance's previous state is only can be the INST_ACTIVATED.
915 * So we should care the slave_unload_instance from here.
916 * And we should send notification to clients, about this is deleted.
920 * Slave has no instance of this.
921 * In this case, ignore the requested_state
922 * Because, this instance is already met a problem.
927 * Failed to unload this instance.
928 * This is not possible, slave will always return LB_STATUS_ERROR_NOT_EXIST, LB_STATUS_ERROR_INVALID, or 0.
929 * but care this exceptional case.
931 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(inst->info), ret);
933 instance_broadcast_deleted_event(inst);
934 instance_state_reset(inst);
935 instance_destroy(inst);
939 inst->changing_state = 0;
940 instance_unref(inst);
943 static void reactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
945 struct inst_info *inst = data;
946 struct pkg_info *info;
947 enum lb_type lb_type;
948 enum pd_type pd_type;
955 DbgPrint("Consuming a request of a dead process\n");
958 * instance_reload function will care this.
959 * and it will be called from the slave_activate callback
964 if (packet_get(packet, "issi", &ret, &content, &title, &is_pinned_up) != 4) {
965 ErrPrint("Invalid parameter\n");
969 if (strlen(content)) {
972 tmp = strdup(content);
974 ErrPrint("Heap: %s\n", strerror(errno));
978 DbgFree(inst->content);
981 DbgPrint("Update content info %s\n", tmp);
989 ErrPrint("Heap: %s\n", strerror(errno));
993 DbgFree(inst->title);
996 DbgPrint("Update title info %s\n", tmp);
999 if (inst->state == INST_DESTROYED) {
1002 * Already destroyed.
1003 * Do nothing at here anymore.
1009 case 0: /*!< normally created */
1010 inst->state = INST_ACTIVATED;
1011 switch (inst->requested_state) {
1012 case INST_DESTROYED:
1013 instance_destroy(inst);
1015 case INST_ACTIVATED:
1016 inst->is_pinned_up = is_pinned_up;
1018 lb_type = package_lb_type(info);
1019 pd_type = package_pd_type(info);
1023 * Optimization point.
1024 * In case of the BUFFER type,
1025 * the slave will request the buffer to render its contents.
1026 * so the buffer will be automatcially recreated when it gots the
1027 * buffer request packet.
1028 * so load a buffer from here is not neccessary.
1029 * I should to revise it and concrete the concept.
1030 * Just leave it only for now.
1033 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script) {
1034 script_handler_load(inst->lb.canvas.script, 0);
1035 } else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer) {
1036 buffer_handler_load(inst->lb.canvas.buffer);
1039 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script && inst->pd.is_opened_for_reactivate) {
1043 * We should to send a request to open a PD to slave.
1044 * if we didn't send it, the slave will not recognize the state of a PD.
1045 * We have to keep the view of PD seamless even if the livebox is reactivated.
1046 * To do that, send open request from here.
1048 ret = instance_slave_open_pd(inst, NULL);
1049 instance_slave_get_pd_pos(inst, &x, &y);
1053 * In this case, master already loads the PD script.
1054 * So just send the pd,show event to the slave again.
1056 ret = instance_signal_emit(inst, "pd,show", instance_id(inst), 0.0, 0.0, 0.0, 0.0, x, y, 0);
1057 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer && inst->pd.is_opened_for_reactivate) {
1060 buffer_handler_load(inst->pd.canvas.buffer);
1061 instance_slave_get_pd_pos(inst, &x, &y);
1065 * We should to send a request to open a PD to slave.
1066 * if we didn't send it, the slave will not recognize the state of a PD.
1067 * We have to keep the view of PD seamless even if the livebox is reactivated.
1068 * To do that, send open request from here.
1070 ret = instance_slave_open_pd(inst, NULL);
1074 * In this case, just send the pd,show event for keeping the compatibility
1076 ret = instance_signal_emit(inst, "pd,show", instance_id(inst), 0.0, 0.0, 0.0, 0.0, x, y, 0);
1081 * After create an instance again,
1082 * Send resize request to the livebox.
1083 * instance_resize(inst, inst->lb.width, inst->lb.height);
1085 * renew request will resize the livebox while creating it again
1090 * This function will check the visiblity of a livebox and
1091 * make decision whether it thaw the update timer or not.
1093 instance_recover_visible_state(inst);
1100 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(info), ret);
1101 instance_broadcast_deleted_event(inst);
1102 instance_state_reset(inst);
1103 instance_destroy(inst);
1108 inst->changing_state = 0;
1109 instance_unref(inst);
1112 static void activate_cb(struct slave_node *slave, const struct packet *packet, void *data)
1114 struct inst_info *inst = data;
1124 DbgPrint("Consuming a request of a dead process\n");
1127 * instance_reload will care this
1128 * it will be called from the slave_activate callback
1133 if (packet_get(packet, "iiidssi", &ret, &w, &h, &priority, &content, &title, &is_pinned_up) != 7) {
1134 ErrPrint("Invalid parameter\n");
1138 if (inst->state == INST_DESTROYED) {
1141 * Already destroyed.
1142 * Do nothing at here anymore.
1148 case 1: /*!< need to create */
1149 if (util_free_space(IMAGE_PATH) > MINIMUM_SPACE) {
1150 struct inst_info *new_inst;
1151 new_inst = instance_create(inst->client, util_timestamp(), package_name(inst->info),
1152 inst->content, inst->cluster, inst->category,
1153 inst->lb.period, 0, 0);
1155 ErrPrint("Failed to create a new instance\n");
1157 ErrPrint("Not enough space\n");
1159 case 0: /*!< normally created */
1162 * Anyway this instance is loaded to the slave,
1163 * just increase the loaded instance counter
1164 * And then reset jobs.
1166 instance_set_lb_size(inst, w, h);
1167 instance_set_lb_info(inst, priority, content, title);
1169 inst->state = INST_ACTIVATED;
1171 switch (inst->requested_state) {
1172 case INST_DESTROYED:
1173 instance_unicast_deleted_event(inst, NULL);
1174 instance_state_reset(inst);
1175 instance_destroy(inst);
1177 case INST_ACTIVATED:
1181 * LB should be created at the create time
1183 inst->is_pinned_up = is_pinned_up;
1184 if (package_lb_type(inst->info) == LB_TYPE_SCRIPT) {
1185 if (inst->lb.width == 0 && inst->lb.height == 0)
1186 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1188 inst->lb.canvas.script = script_handler_create(inst,
1189 package_lb_path(inst->info),
1190 package_lb_group(inst->info),
1191 inst->lb.width, inst->lb.height);
1193 if (!inst->lb.canvas.script)
1194 ErrPrint("Failed to create LB\n");
1196 script_handler_load(inst->lb.canvas.script, 0);
1197 } else if (package_lb_type(inst->info) == LB_TYPE_BUFFER) {
1198 instance_create_lb_buffer(inst);
1201 if (package_pd_type(inst->info) == PD_TYPE_SCRIPT) {
1202 if (inst->pd.width == 0 && inst->pd.height == 0)
1203 instance_set_pd_size(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1205 inst->pd.canvas.script = script_handler_create(inst,
1206 package_pd_path(inst->info),
1207 package_pd_group(inst->info),
1208 inst->pd.width, inst->pd.height);
1210 if (!inst->pd.canvas.script)
1211 ErrPrint("Failed to create PD\n");
1212 } else if (package_pd_type(inst->info) == PD_TYPE_BUFFER) {
1213 instance_create_pd_buffer(inst);
1216 instance_broadcast_created_event(inst);
1218 instance_thaw_updator(inst);
1223 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(inst->info), ret);
1224 instance_unicast_deleted_event(inst, NULL);
1225 instance_state_reset(inst);
1226 instance_destroy(inst);
1231 inst->changing_state = 0;
1232 instance_unref(inst);
1235 HAPI int instance_create_pd_buffer(struct inst_info *inst)
1237 if (inst->pd.width == 0 && inst->pd.height == 0)
1238 instance_set_pd_size(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1240 if (!inst->pd.canvas.buffer) {
1241 inst->pd.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->pd.width, inst->pd.height, sizeof(int));
1242 if (!inst->pd.canvas.buffer)
1243 ErrPrint("Failed to create PD Buffer\n");
1246 return !!inst->pd.canvas.buffer;
1249 HAPI int instance_create_lb_buffer(struct inst_info *inst)
1251 if (inst->lb.width == 0 && inst->lb.height == 0)
1252 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1254 if (!inst->lb.canvas.buffer) {
1257 * Slave doesn't call the acquire_buffer.
1258 * In this case, create the buffer from here.
1260 inst->lb.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->lb.width, inst->lb.height, sizeof(int));
1261 if (!inst->lb.canvas.buffer)
1262 ErrPrint("Failed to create LB\n");
1265 return !!inst->lb.canvas.buffer;
1268 HAPI int instance_destroy(struct inst_info *inst)
1270 struct packet *packet;
1273 ErrPrint("Invalid instance handle\n");
1274 return LB_STATUS_ERROR_INVALID;
1277 switch (inst->state) {
1278 case INST_REQUEST_TO_ACTIVATE:
1279 case INST_REQUEST_TO_DESTROY:
1280 case INST_REQUEST_TO_REACTIVATE:
1281 inst->requested_state = INST_DESTROYED;
1282 return LB_STATUS_SUCCESS;
1284 inst->state = INST_DESTROYED;
1285 inst->requested_state = INST_DESTROYED;
1286 instance_unref(inst);
1287 return LB_STATUS_SUCCESS;
1288 case INST_DESTROYED:
1289 inst->requested_state = INST_DESTROYED;
1290 return LB_STATUS_SUCCESS;
1295 packet = packet_create("delete", "ss", package_name(inst->info), inst->id);
1297 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1298 return LB_STATUS_ERROR_FAULT;
1301 inst->requested_state = INST_DESTROYED;
1302 inst->state = INST_REQUEST_TO_DESTROY;
1303 inst->changing_state = 1;
1304 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, deactivate_cb, instance_ref(inst), 0);
1307 /* Client Deactivated Callback */
1308 static int pd_buffer_close_cb(struct client_node *client, void *inst)
1312 ret = instance_slave_close_pd(inst, client);
1313 DbgPrint("Forcely close the PD ret: %d\n", ret);
1315 instance_unref(inst);
1317 return -1; /* Delete this callback */
1320 /* Client Deactivated Callback */
1321 static int pd_script_close_cb(struct client_node *client, void *inst)
1325 ret = script_handler_unload(instance_pd_script(inst), 1);
1326 DbgPrint("Unload script: %d\n", ret);
1328 ret = instance_slave_close_pd(inst, client);
1329 DbgPrint("Forcely close the PD ret: %d\n", ret);
1331 instance_unref(inst);
1333 return -1; /* Delete this callback */
1336 static inline void release_resource_for_closing_pd(struct pkg_info *info, struct inst_info *inst, struct client_node *client)
1339 client = inst->pd.owner;
1346 * Clean up the resources
1348 if (package_pd_type(info) == PD_TYPE_BUFFER) {
1349 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) == 0) {
1352 * Only if this function succeed to remove the pd_buffer_close_cb,
1353 * Decrease the reference count of this instance
1356 instance_unref(inst);
1357 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
1358 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) == 0) {
1361 * Only if this function succeed to remove the script_close_cb,
1362 * Decrease the reference count of this instance
1365 instance_unref(inst);
1367 ErrPrint("Unknown PD type\n");
1372 HAPI int instance_state_reset(struct inst_info *inst)
1374 enum lb_type lb_type;
1375 enum pd_type pd_type;
1378 ErrPrint("Invalid instance handle\n");
1379 return LB_STATUS_ERROR_INVALID;
1382 if (inst->state == INST_DESTROYED)
1385 lb_type = package_lb_type(inst->info);
1386 pd_type = package_pd_type(inst->info);
1388 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script)
1389 script_handler_unload(inst->lb.canvas.script, 0);
1390 else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer)
1391 buffer_handler_unload(inst->lb.canvas.buffer);
1393 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script) {
1394 inst->pd.is_opened_for_reactivate = script_handler_is_loaded(inst->pd.canvas.script);
1395 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1396 script_handler_unload(inst->pd.canvas.script, 1);
1397 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer) {
1398 inst->pd.is_opened_for_reactivate = buffer_handler_is_loaded(inst->pd.canvas.buffer);
1399 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1400 buffer_handler_unload(inst->pd.canvas.buffer);
1404 inst->state = INST_INIT;
1405 inst->requested_state = INST_INIT;
1406 return LB_STATUS_SUCCESS;
1409 HAPI int instance_reactivate(struct inst_info *inst)
1411 struct packet *packet;
1415 ErrPrint("Invalid instance handle\n");
1416 return LB_STATUS_ERROR_INVALID;
1419 if (package_is_fault(inst->info)) {
1420 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1421 return LB_STATUS_ERROR_FAULT;
1424 switch (inst->state) {
1425 case INST_REQUEST_TO_DESTROY:
1426 case INST_REQUEST_TO_ACTIVATE:
1427 case INST_REQUEST_TO_REACTIVATE:
1428 inst->requested_state = INST_ACTIVATED;
1429 return LB_STATUS_SUCCESS;
1430 case INST_DESTROYED:
1431 case INST_ACTIVATED:
1432 return LB_STATUS_SUCCESS;
1438 packet = packet_create("renew", "sssiidssiisii",
1439 package_name(inst->info),
1443 !!package_lb_path(inst->info),
1447 inst->lb.width, inst->lb.height,
1448 package_abi(inst->info),
1449 inst->scroll_locked,
1450 inst->active_update);
1452 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1453 return LB_STATUS_ERROR_FAULT;
1456 ret = slave_activate(package_slave(inst->info));
1457 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
1460 * If the master failed to launch the slave,
1461 * Do not send any requests to the slave.
1463 ErrPrint("Failed to launch the slave\n");
1464 packet_destroy(packet);
1468 inst->requested_state = INST_ACTIVATED;
1469 inst->state = INST_REQUEST_TO_REACTIVATE;
1470 inst->changing_state = 1;
1472 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, reactivate_cb, instance_ref(inst), 1);
1475 HAPI int instance_activate(struct inst_info *inst)
1477 struct packet *packet;
1481 ErrPrint("Invalid instance handle\n");
1482 return LB_STATUS_ERROR_INVALID;
1485 if (package_is_fault(inst->info)) {
1486 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1487 return LB_STATUS_ERROR_FAULT;
1490 switch (inst->state) {
1491 case INST_REQUEST_TO_REACTIVATE:
1492 case INST_REQUEST_TO_ACTIVATE:
1493 case INST_REQUEST_TO_DESTROY:
1494 inst->requested_state = INST_ACTIVATED;
1495 return LB_STATUS_SUCCESS;
1496 case INST_ACTIVATED:
1497 case INST_DESTROYED:
1498 return LB_STATUS_SUCCESS;
1504 packet = packet_create("new", "sssiidssisii",
1505 package_name(inst->info),
1509 !!package_lb_path(inst->info),
1514 package_abi(inst->info),
1518 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1519 return LB_STATUS_ERROR_FAULT;
1522 ret = slave_activate(package_slave(inst->info));
1523 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY) {
1526 * If the master failed to launch the slave,
1527 * Do not send any requests to the slave.
1529 ErrPrint("Failed to launch the slave\n");
1530 packet_destroy(packet);
1534 inst->state = INST_REQUEST_TO_ACTIVATE;
1535 inst->requested_state = INST_ACTIVATED;
1536 inst->changing_state = 1;
1540 * Try to activate a slave if it is not activated
1542 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, activate_cb, instance_ref(inst), 1);
1545 HAPI int instance_lb_update_begin(struct inst_info *inst, double priority, const char *content, const char *title)
1547 struct packet *packet;
1550 if (!inst->active_update) {
1551 ErrPrint("Invalid request [%s]\n", inst->id);
1552 return LB_STATUS_ERROR_INVALID;
1555 switch (package_lb_type(inst->info)) {
1556 case LB_TYPE_BUFFER:
1557 if (!inst->lb.canvas.buffer) {
1558 ErrPrint("Buffer is null [%s]\n", inst->id);
1559 return LB_STATUS_ERROR_INVALID;
1561 fbfile = buffer_handler_id(inst->lb.canvas.buffer);
1563 case LB_TYPE_SCRIPT:
1564 if (!inst->lb.canvas.script) {
1565 ErrPrint("Script is null [%s]\n", inst->id);
1566 return LB_STATUS_ERROR_INVALID;
1568 fbfile = fb_id(script_handler_fb(inst->lb.canvas.script));
1571 ErrPrint("Invalid request[%s]\n", inst->id);
1572 return LB_STATUS_ERROR_INVALID;
1575 packet = packet_create_noack("lb_update_begin", "ssdsss", package_name(inst->info), inst->id, priority, content, title, fbfile);
1577 ErrPrint("Unable to create a packet\n");
1578 return LB_STATUS_ERROR_FAULT;
1581 return CLIENT_SEND_EVENT(inst, packet);
1584 HAPI int instance_lb_update_end(struct inst_info *inst)
1586 struct packet *packet;
1588 if (!inst->active_update) {
1589 ErrPrint("Invalid request [%s]\n", inst->id);
1590 return LB_STATUS_ERROR_INVALID;
1593 switch (package_lb_type(inst->info)) {
1594 case LB_TYPE_BUFFER:
1595 if (!inst->lb.canvas.buffer) {
1596 ErrPrint("Buffer is null [%s]\n", inst->id);
1597 return LB_STATUS_ERROR_INVALID;
1600 case LB_TYPE_SCRIPT:
1601 if (!inst->lb.canvas.script) {
1602 ErrPrint("Script is null [%s]\n", inst->id);
1603 return LB_STATUS_ERROR_INVALID;
1607 ErrPrint("Invalid request[%s]\n", inst->id);
1608 return LB_STATUS_ERROR_INVALID;
1611 packet = packet_create_noack("lb_update_end", "ss", package_name(inst->info), inst->id);
1613 ErrPrint("Unable to create a packet\n");
1614 return LB_STATUS_ERROR_FAULT;
1617 return CLIENT_SEND_EVENT(inst, packet);
1620 HAPI int instance_pd_update_begin(struct inst_info *inst)
1622 struct packet *packet;
1625 if (!inst->active_update) {
1626 ErrPrint("Invalid request [%s]\n", inst->id);
1627 return LB_STATUS_ERROR_INVALID;
1630 switch (package_pd_type(inst->info)) {
1631 case PD_TYPE_BUFFER:
1632 if (!inst->pd.canvas.buffer) {
1633 ErrPrint("Buffer is null [%s]\n", inst->id);
1634 return LB_STATUS_ERROR_INVALID;
1636 fbfile = buffer_handler_id(inst->pd.canvas.buffer);
1638 case PD_TYPE_SCRIPT:
1639 if (!inst->pd.canvas.script) {
1640 ErrPrint("Script is null [%s]\n", inst->id);
1641 return LB_STATUS_ERROR_INVALID;
1643 fbfile = fb_id(script_handler_fb(inst->pd.canvas.script));
1646 ErrPrint("Invalid request[%s]\n", inst->id);
1647 return LB_STATUS_ERROR_INVALID;
1650 packet = packet_create_noack("pd_update_begin", "sss", package_name(inst->info), inst->id, fbfile);
1652 ErrPrint("Unable to create a packet\n");
1653 return LB_STATUS_ERROR_FAULT;
1656 return CLIENT_SEND_EVENT(inst, packet);
1659 HAPI int instance_pd_update_end(struct inst_info *inst)
1661 struct packet *packet;
1663 if (!inst->active_update) {
1664 ErrPrint("Invalid request [%s]\n", inst->id);
1665 return LB_STATUS_ERROR_INVALID;
1668 switch (package_pd_type(inst->info)) {
1669 case PD_TYPE_BUFFER:
1670 if (!inst->pd.canvas.buffer) {
1671 ErrPrint("Buffer is null [%s]\n", inst->id);
1672 return LB_STATUS_ERROR_INVALID;
1675 case PD_TYPE_SCRIPT:
1676 if (!inst->pd.canvas.script) {
1677 ErrPrint("Script is null [%s]\n", inst->id);
1678 return LB_STATUS_ERROR_INVALID;
1682 ErrPrint("Invalid request[%s]\n", inst->id);
1683 return LB_STATUS_ERROR_INVALID;
1686 packet = packet_create_noack("pd_update_end", "ss", package_name(inst->info), inst->id);
1688 ErrPrint("Unable to create a packet\n");
1689 return LB_STATUS_ERROR_FAULT;
1692 return CLIENT_SEND_EVENT(inst, packet);
1695 HAPI void instance_lb_updated(const char *pkgname, const char *id)
1697 struct inst_info *inst;
1699 inst = package_find_instance_by_id(pkgname, id);
1703 instance_lb_updated_by_instance(inst);
1706 HAPI void instance_lb_updated_by_instance(struct inst_info *inst)
1708 struct packet *packet;
1710 enum lb_type lb_type;
1712 const char *content;
1714 if (inst->client && inst->visible != LB_SHOW) {
1715 if (inst->visible == LB_HIDE) {
1716 DbgPrint("Ignore update event %s(HIDE)\n", inst->id);
1719 DbgPrint("Livebox(%s) is PAUSED. But content is updated.\n", inst->id);
1722 lb_type = package_lb_type(inst->info);
1723 if (lb_type == LB_TYPE_SCRIPT)
1724 id = fb_id(script_handler_fb(inst->lb.canvas.script));
1725 else if (lb_type == LB_TYPE_BUFFER)
1726 id = buffer_handler_id(inst->lb.canvas.buffer);
1731 content = inst->content;
1736 title = inst->title;
1740 packet = packet_create_noack("lb_updated", "sssiidss",
1741 package_name(inst->info), inst->id, id,
1742 inst->lb.width, inst->lb.height, inst->lb.priority, content, title);
1744 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1748 (void)CLIENT_SEND_EVENT(inst, packet);
1751 HAPI int instance_hold_scroll(struct inst_info *inst, int hold)
1753 struct packet *packet;
1755 if (inst->scroll_locked == hold) {
1756 DbgPrint("[HOLD] There is changes for hold state: %d\n", hold);
1757 return LB_STATUS_ERROR_ALREADY;
1760 packet = packet_create_noack("scroll", "ssi", package_name(inst->info), inst->id, hold);
1762 ErrPrint("[HOLD] Failed to build a packet\n");
1763 return LB_STATUS_ERROR_FAULT;
1766 DbgPrint("[HOLD] (%s) %d\n", inst->id, hold);
1767 inst->scroll_locked = hold;
1768 return CLIENT_SEND_EVENT(inst, packet);
1771 HAPI void instance_pd_updated_by_instance(struct inst_info *inst, const char *descfile)
1773 struct packet *packet;
1776 if (inst->client && inst->visible != LB_SHOW) {
1777 DbgPrint("Livebox is hidden. ignore update event\n");
1781 if (!inst->pd.need_to_send_close_event) {
1782 DbgPrint("PD is not created yet. Ignore update event - %s\n", descfile);
1784 if (inst->pd.pended_update_desc) {
1785 DbgFree(inst->pd.pended_update_desc);
1786 inst->pd.pended_update_desc = NULL;
1790 inst->pd.pended_update_desc = strdup(descfile);
1791 if (!inst->pd.pended_update_desc)
1792 ErrPrint("Heap: %s\n", strerror(errno));
1795 inst->pd.pended_update_cnt++;
1800 descfile = inst->id;
1802 switch (package_pd_type(inst->info)) {
1803 case PD_TYPE_SCRIPT:
1804 id = fb_id(script_handler_fb(inst->pd.canvas.script));
1806 case PD_TYPE_BUFFER:
1807 id = buffer_handler_id(inst->pd.canvas.buffer);
1815 packet = packet_create_noack("pd_updated", "ssssii",
1816 package_name(inst->info), inst->id, descfile, id,
1817 inst->pd.width, inst->pd.height);
1819 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1823 (void)CLIENT_SEND_EVENT(inst, packet);
1826 HAPI void instance_pd_updated(const char *pkgname, const char *id, const char *descfile)
1828 struct inst_info *inst;
1830 inst = package_find_instance_by_id(pkgname, id);
1834 instance_pd_updated_by_instance(inst, descfile);
1837 HAPI int instance_set_update_mode(struct inst_info *inst, int active_update)
1839 struct packet *packet;
1840 struct update_mode_cbdata *cbdata;
1842 if (package_is_fault(inst->info)) {
1843 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1844 return LB_STATUS_ERROR_FAULT;
1847 if (inst->active_update == active_update) {
1848 DbgPrint("Active update is not changed: %d\n", inst->active_update);
1849 return LB_STATUS_ERROR_ALREADY;
1852 cbdata = malloc(sizeof(*cbdata));
1854 ErrPrint("Heap: %s\n", strerror(errno));
1855 return LB_STATUS_ERROR_MEMORY;
1858 cbdata->inst = instance_ref(inst);
1859 cbdata->active_update = active_update;
1861 /* NOTE: param is resued from here */
1862 packet = packet_create("update_mode", "ssi", package_name(inst->info), inst->id, active_update);
1864 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1865 instance_unref(cbdata->inst);
1867 return LB_STATUS_ERROR_FAULT;
1870 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, update_mode_cb, cbdata, 0);
1873 HAPI int instance_active_update(struct inst_info *inst)
1875 return inst->active_update;
1878 HAPI void instance_set_lb_info(struct inst_info *inst, double priority, const char *content, const char *title)
1880 char *_content = NULL;
1881 char *_title = NULL;
1883 if (content && strlen(content)) {
1884 _content = strdup(content);
1886 ErrPrint("Heap: %s\n", strerror(errno));
1889 if (title && strlen(title)) {
1890 _title = strdup(title);
1892 ErrPrint("Heap: %s\n", strerror(errno));
1896 DbgFree(inst->content);
1897 inst->content= _content;
1901 DbgFree(inst->title);
1902 inst->title = _title;
1905 if (priority >= 0.0f && priority <= 1.0f)
1906 inst->lb.priority = priority;
1909 HAPI void instance_set_lb_size(struct inst_info *inst, int w, int h)
1911 if (inst->lb.width != w || inst->lb.height != h)
1912 instance_send_resized_event(inst, IS_LB, w, h, LB_STATUS_SUCCESS);
1915 inst->lb.height = h;
1918 HAPI void instance_set_pd_size(struct inst_info *inst, int w, int h)
1920 if (inst->pd.width != w || inst->pd.height != h)
1921 instance_send_resized_event(inst, IS_PD, w, h, LB_STATUS_SUCCESS);
1924 inst->pd.height = h;
1927 static void pinup_cb(struct slave_node *slave, const struct packet *packet, void *data)
1929 struct set_pinup_cbdata *cbdata = data;
1930 const char *content;
1931 struct packet *result;
1937 * Send pinup failed event to client.
1939 ret = LB_STATUS_ERROR_INVALID;
1943 if (packet_get(packet, "is", &ret, &content) != 2) {
1946 * Send pinup failed event to client
1948 ret = LB_STATUS_ERROR_INVALID;
1955 new_content = strdup(content);
1957 ErrPrint("Heap: %s\n", strerror(errno));
1960 * send pinup failed event to client
1962 ret = LB_STATUS_ERROR_MEMORY;
1966 cbdata->inst->is_pinned_up = cbdata->pinup;
1967 DbgFree(cbdata->inst->content);
1969 cbdata->inst->content = new_content;
1975 * Send PINUP Result to client.
1976 * Client should wait this event.
1978 result = packet_create_noack("pinup", "iisss", ret, cbdata->inst->is_pinned_up,
1979 package_name(cbdata->inst->info), cbdata->inst->id, cbdata->inst->content);
1981 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
1983 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
1985 instance_unref(cbdata->inst);
1989 HAPI int instance_set_pinup(struct inst_info *inst, int pinup)
1991 struct set_pinup_cbdata *cbdata;
1992 struct packet *packet;
1995 ErrPrint("Invalid instance handle\n");
1996 return LB_STATUS_ERROR_INVALID;
1999 if (package_is_fault(inst->info)) {
2000 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2001 return LB_STATUS_ERROR_FAULT;
2004 if (!package_pinup(inst->info))
2005 return LB_STATUS_ERROR_INVALID;
2007 if (pinup == inst->is_pinned_up)
2008 return LB_STATUS_ERROR_INVALID;
2010 cbdata = malloc(sizeof(*cbdata));
2012 return LB_STATUS_ERROR_MEMORY;
2014 cbdata->inst = instance_ref(inst);
2015 cbdata->pinup = pinup;
2017 packet = packet_create("pinup", "ssi", package_name(inst->info), inst->id, pinup);
2019 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2020 instance_unref(cbdata->inst);
2022 return LB_STATUS_ERROR_FAULT;
2025 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, pinup_cb, cbdata, 0);
2028 HAPI int instance_freeze_updator(struct inst_info *inst)
2030 if (!inst->update_timer)
2031 return LB_STATUS_ERROR_INVALID;
2033 DbgPrint("Freeze the update timer (%s)\n", inst->id);
2035 return LB_STATUS_SUCCESS;
2038 HAPI int instance_thaw_updator(struct inst_info *inst)
2040 if (!inst->update_timer)
2041 return LB_STATUS_ERROR_INVALID;
2043 if (client_is_all_paused() || setting_is_lcd_off()) {
2044 DbgPrint("Skip thaw (%s)\n", inst->id);
2045 return LB_STATUS_ERROR_INVALID;
2048 if (inst->visible == LB_HIDE_WITH_PAUSE) {
2049 DbgPrint("Live box is invisible (%s)\n", inst->id);
2050 return LB_STATUS_ERROR_INVALID;
2053 DbgPrint("Thaw the update timer (%s)\n", inst->id);
2055 return LB_STATUS_SUCCESS;
2058 HAPI enum livebox_visible_state instance_visible_state(struct inst_info *inst)
2060 return inst->visible;
2063 HAPI int instance_set_visible_state(struct inst_info *inst, enum livebox_visible_state state)
2065 if (inst->visible == state) {
2066 DbgPrint("Visibility has no changed\n");
2067 return LB_STATUS_SUCCESS;
2073 if (inst->visible == LB_HIDE_WITH_PAUSE) {
2074 if (resume_livebox(inst) == 0)
2075 inst->visible = state;
2077 instance_thaw_updator(inst);
2079 inst->visible = state;
2083 case LB_HIDE_WITH_PAUSE:
2084 if (pause_livebox(inst) == 0)
2085 inst->visible = LB_HIDE_WITH_PAUSE;
2087 instance_freeze_updator(inst);
2091 return LB_STATUS_ERROR_INVALID;
2094 return LB_STATUS_SUCCESS;
2097 static void resize_cb(struct slave_node *slave, const struct packet *packet, void *data)
2099 struct resize_cbdata *cbdata = data;
2103 ErrPrint("RESIZE: Invalid packet\n");
2104 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_FAULT);
2105 instance_unref(cbdata->inst);
2110 if (packet_get(packet, "i", &ret) != 1) {
2111 ErrPrint("RESIZE: Invalid parameter\n");
2112 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_INVALID);
2113 instance_unref(cbdata->inst);
2118 if (ret == LB_STATUS_SUCCESS) {
2121 * else waiting the first update with new size
2123 if (cbdata->inst->lb.width == cbdata->w && cbdata->inst->lb.height == cbdata->h) {
2126 * Right after the viewer adds a new box,
2127 * Box has no size information, then it will try to use the default size,
2128 * After a box returns created event.
2130 * A box will start to generate default size content.
2131 * But the viewer doesn't know it,.
2133 * So the viewer will try to change the size of a box.
2135 * At that time, the provider gots the size changed event from the box.
2136 * So it sent the size changed event to the viewer.
2137 * But the viewer ignores it. if it doesn't care the size changed event.
2138 * (even if it cares the size changed event, there is a timing issue)
2140 * And the provider receives resize request,
2141 * right before send the size changed event.
2142 * but there is no changes about the size.
2144 * Now the view will waits size changed event forever.
2145 * To resolve this timing issue.
2147 * Check the size of a box from here.
2148 * And if the size is already updated, send the ALREADY event to the viewer
2149 * to get the size changed event callback correctly.
2151 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, LB_STATUS_ERROR_ALREADY);
2152 DbgPrint("RESIZE: Livebox is already resized [%s - %dx%d]\n", instance_id(cbdata->inst), cbdata->w, cbdata->h);
2154 DbgPrint("RESIZE: Request is successfully sent [%s - %dx%d]\n", instance_id(cbdata->inst), cbdata->w, cbdata->h);
2157 DbgPrint("RESIZE: Livebox rejects the new size: %s - %dx%d (%d)\n", instance_id(cbdata->inst), cbdata->w, cbdata->h, ret);
2158 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, ret);
2161 instance_unref(cbdata->inst);
2165 HAPI int instance_resize(struct inst_info *inst, int w, int h)
2167 struct resize_cbdata *cbdata;
2168 struct packet *packet;
2172 ErrPrint("Invalid instance handle\n");
2173 return LB_STATUS_ERROR_INVALID;
2176 if (package_is_fault(inst->info)) {
2177 ErrPrint("Fault package: %s\n", package_name(inst->info));
2178 return LB_STATUS_ERROR_FAULT;
2181 cbdata = malloc(sizeof(*cbdata));
2183 ErrPrint("Heap: %s\n", strerror(errno));
2184 return LB_STATUS_ERROR_MEMORY;
2187 cbdata->inst = instance_ref(inst);
2191 /* NOTE: param is resued from here */
2192 packet = packet_create("resize", "ssii", package_name(inst->info), inst->id, w, h);
2194 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2195 instance_unref(cbdata->inst);
2197 return LB_STATUS_ERROR_FAULT;
2200 DbgPrint("RESIZE: INSTANCE[%s] Request resize[%dx%d] box\n", instance_id(inst), w, h);
2201 ret = slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, resize_cb, cbdata, 0);
2205 static void set_period_cb(struct slave_node *slave, const struct packet *packet, void *data)
2208 struct period_cbdata *cbdata = data;
2209 struct packet *result;
2212 ret = LB_STATUS_ERROR_FAULT;
2216 if (packet_get(packet, "i", &ret) != 1) {
2217 ret = LB_STATUS_ERROR_INVALID;
2222 cbdata->inst->lb.period = cbdata->period;
2224 ErrPrint("Failed to set period %d\n", ret);
2227 result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->lb.period, package_name(cbdata->inst->info), cbdata->inst->id);
2229 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2231 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
2233 instance_unref(cbdata->inst);
2238 static Eina_Bool timer_updator_cb(void *data)
2240 struct period_cbdata *cbdata = data;
2241 struct inst_info *inst;
2243 struct packet *result;
2245 period = cbdata->period;
2246 inst = cbdata->inst;
2249 DbgPrint("Update period is changed to %lf from %lf\n", period, inst->lb.period);
2251 inst->lb.period = period;
2252 if (inst->update_timer) {
2253 if (inst->lb.period == 0.0f) {
2254 ecore_timer_del(inst->update_timer);
2255 inst->update_timer = NULL;
2257 util_timer_interval_set(inst->update_timer, inst->lb.period);
2259 } else if (inst->lb.period > 0.0f) {
2260 inst->update_timer = util_timer_add(inst->lb.period, update_timer_cb, inst);
2261 if (!inst->update_timer)
2262 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
2264 timer_freeze(inst); /* Freeze the update timer as default */
2267 result = packet_create_noack("period_changed", "idss", 0, inst->lb.period, package_name(inst->info), inst->id);
2269 (void)CLIENT_SEND_EVENT(inst, result);
2271 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2273 instance_unref(inst);
2274 return ECORE_CALLBACK_CANCEL;
2277 HAPI int instance_set_period(struct inst_info *inst, double period)
2279 struct packet *packet;
2280 struct period_cbdata *cbdata;
2283 ErrPrint("Invalid instance handle\n");
2284 return LB_STATUS_ERROR_INVALID;
2287 if (package_is_fault(inst->info)) {
2288 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2289 return LB_STATUS_ERROR_FAULT;
2292 if (period < 0.0f) { /* Use the default period */
2293 period = package_period(inst->info);
2294 } else if (period > 0.0f && period < MINIMUM_PERIOD) {
2295 period = MINIMUM_PERIOD; /* defined at conf.h */
2298 cbdata = malloc(sizeof(*cbdata));
2300 ErrPrint("Heap: %s\n", strerror(errno));
2301 return LB_STATUS_ERROR_MEMORY;
2304 cbdata->period = period;
2305 cbdata->inst = instance_ref(inst);
2307 if (package_secured(inst->info)) {
2310 * Secured livebox doesn't need to send its update period to the slave.
2311 * Slave has no local timer for updating liveboxes
2313 * So update its timer at here.
2315 if (!ecore_timer_add(DELAY_TIME, timer_updator_cb, cbdata))
2316 timer_updator_cb(cbdata);
2317 return LB_STATUS_SUCCESS;
2320 packet = packet_create("set_period", "ssd", package_name(inst->info), inst->id, period);
2322 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2323 instance_unref(cbdata->inst);
2325 return LB_STATUS_ERROR_FAULT;
2328 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, set_period_cb, cbdata, 0);
2331 HAPI int instance_clicked(struct inst_info *inst, const char *event, double timestamp, double x, double y)
2333 struct packet *packet;
2336 ErrPrint("Invalid instance handle\n");
2337 return LB_STATUS_ERROR_INVALID;
2340 if (package_is_fault(inst->info)) {
2341 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2342 return LB_STATUS_ERROR_FAULT;
2345 /* NOTE: param is resued from here */
2346 packet = packet_create_noack("clicked", "sssddd", package_name(inst->info), inst->id, event, timestamp, x, y);
2348 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2349 return LB_STATUS_ERROR_FAULT;
2352 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
2355 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)
2357 const char *pkgname;
2359 struct slave_node *slave;
2360 struct packet *packet;
2361 struct pkg_info *pkg;
2363 pkg = instance_package(inst);
2364 pkgname = package_name(pkg);
2365 id = instance_id(inst);
2366 if (!pkgname || !id)
2367 return LB_STATUS_ERROR_INVALID;
2369 slave = package_slave(pkg);
2371 return LB_STATUS_ERROR_INVALID;
2373 packet = packet_create_noack("script", "ssssddddddi",
2379 return LB_STATUS_ERROR_FAULT;
2381 return slave_rpc_request_only(slave, pkgname, packet, 0);
2384 HAPI int instance_text_signal_emit(struct inst_info *inst, const char *emission, const char *source, double sx, double sy, double ex, double ey)
2386 struct packet *packet;
2389 ErrPrint("Invalid instance handle\n");
2390 return LB_STATUS_ERROR_INVALID;
2393 if (package_is_fault(inst->info)) {
2394 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2395 return LB_STATUS_ERROR_FAULT;
2398 packet = packet_create_noack("text_signal", "ssssdddd", package_name(inst->info), inst->id, emission, source, sx, sy, ex, ey);
2400 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2401 return LB_STATUS_ERROR_FAULT;
2404 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
2407 static void change_group_cb(struct slave_node *slave, const struct packet *packet, void *data)
2409 struct change_group_cbdata *cbdata = data;
2410 struct packet *result;
2414 DbgFree(cbdata->cluster);
2415 DbgFree(cbdata->category);
2416 ret = LB_STATUS_ERROR_FAULT;
2420 if (packet_get(packet, "i", &ret) != 1) {
2421 ErrPrint("Invalid packet\n");
2422 DbgFree(cbdata->cluster);
2423 DbgFree(cbdata->category);
2424 ret = LB_STATUS_ERROR_INVALID;
2429 DbgFree(cbdata->inst->cluster);
2430 cbdata->inst->cluster = cbdata->cluster;
2432 DbgFree(cbdata->inst->category);
2433 cbdata->inst->category = cbdata->category;
2435 DbgFree(cbdata->cluster);
2436 DbgFree(cbdata->category);
2440 result = packet_create_noack("group_changed", "ssiss",
2441 package_name(cbdata->inst->info), cbdata->inst->id, ret,
2442 cbdata->inst->cluster, cbdata->inst->category);
2444 ErrPrint("Failed to build a packet %s\n", package_name(cbdata->inst->info));
2446 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2448 instance_unref(cbdata->inst);
2452 HAPI int instance_change_group(struct inst_info *inst, const char *cluster, const char *category)
2454 struct packet *packet;
2455 struct change_group_cbdata *cbdata;
2458 ErrPrint("Invalid instance handle\n");
2459 return LB_STATUS_ERROR_INVALID;
2462 if (package_is_fault(inst->info)) {
2463 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2464 return LB_STATUS_ERROR_FAULT;
2467 cbdata = malloc(sizeof(*cbdata));
2469 ErrPrint("Heap: %s\n", strerror(errno));
2470 return LB_STATUS_ERROR_MEMORY;
2473 cbdata->cluster = strdup(cluster);
2474 if (!cbdata->cluster) {
2475 ErrPrint("Heap: %s\n", strerror(errno));
2477 return LB_STATUS_ERROR_MEMORY;
2480 cbdata->category = strdup(category);
2481 if (!cbdata->category) {
2482 ErrPrint("Heap: %s\n", strerror(errno));
2483 DbgFree(cbdata->cluster);
2485 return LB_STATUS_ERROR_MEMORY;
2488 cbdata->inst = instance_ref(inst);
2490 packet = packet_create("change_group","ssss", package_name(inst->info), inst->id, cluster, category);
2492 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2493 instance_unref(cbdata->inst);
2494 DbgFree(cbdata->category);
2495 DbgFree(cbdata->cluster);
2497 return LB_STATUS_ERROR_FAULT;
2500 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, change_group_cb, cbdata, 0);
2503 HAPI const char * const instance_auto_launch(const struct inst_info *inst)
2505 return inst->lb.auto_launch;
2508 HAPI const int const instance_priority(const struct inst_info *inst)
2510 return inst->lb.priority;
2513 HAPI const struct client_node *const instance_client(const struct inst_info *inst)
2515 return inst->client;
2518 HAPI const int const instance_timeout(const struct inst_info *inst)
2520 return inst->lb.timeout;
2523 HAPI const double const instance_period(const struct inst_info *inst)
2525 return inst->lb.period;
2528 HAPI const int const instance_lb_width(const struct inst_info *inst)
2530 return inst->lb.width;
2533 HAPI const int const instance_lb_height(const struct inst_info *inst)
2535 return inst->lb.height;
2538 HAPI const int const instance_pd_width(const struct inst_info *inst)
2540 return inst->pd.width;
2543 HAPI const int const instance_pd_height(const struct inst_info *inst)
2545 return inst->pd.height;
2548 HAPI struct pkg_info *const instance_package(const struct inst_info *inst)
2553 HAPI struct script_info *const instance_lb_script(const struct inst_info *inst)
2555 return (package_lb_type(inst->info) == LB_TYPE_SCRIPT) ? inst->lb.canvas.script : NULL;
2558 HAPI struct script_info *const instance_pd_script(const struct inst_info *inst)
2560 return (package_pd_type(inst->info) == PD_TYPE_SCRIPT) ? inst->pd.canvas.script : NULL;
2563 HAPI struct buffer_info *const instance_lb_buffer(const struct inst_info *inst)
2565 return (package_lb_type(inst->info) == LB_TYPE_BUFFER) ? inst->lb.canvas.buffer : NULL;
2568 HAPI struct buffer_info *const instance_pd_buffer(const struct inst_info *inst)
2570 return (package_pd_type(inst->info) == PD_TYPE_BUFFER) ? inst->pd.canvas.buffer : NULL;
2573 HAPI const char *const instance_id(const struct inst_info *inst)
2578 HAPI const char *const instance_content(const struct inst_info *inst)
2580 return inst->content;
2583 HAPI const char *const instance_category(const struct inst_info *inst)
2585 return inst->category;
2588 HAPI const char *const instance_cluster(const struct inst_info *inst)
2590 return inst->cluster;
2593 HAPI const char * const instance_title(const struct inst_info *inst)
2598 HAPI const double const instance_timestamp(const struct inst_info *inst)
2600 return inst->timestamp;
2603 HAPI const enum instance_state const instance_state(const struct inst_info *inst)
2608 HAPI int instance_destroyed(struct inst_info *inst)
2610 switch (inst->state) {
2612 case INST_REQUEST_TO_ACTIVATE:
2615 * No other clients know the existence of this instance,
2616 * only who added this knows it.
2617 * So send deleted event to only it.
2619 DbgPrint("Send deleted event - unicast - %p\n", inst->client);
2620 instance_unicast_deleted_event(inst, NULL);
2621 instance_state_reset(inst);
2622 instance_destroy(inst);
2624 case INST_REQUEST_TO_REACTIVATE:
2625 case INST_REQUEST_TO_DESTROY:
2626 case INST_ACTIVATED:
2627 DbgPrint("Send deleted event - multicast\n");
2628 instance_broadcast_deleted_event(inst);
2629 instance_state_reset(inst);
2630 instance_destroy(inst);
2631 case INST_DESTROYED:
2634 return LB_STATUS_ERROR_INVALID;
2637 return LB_STATUS_SUCCESS;
2641 * Invoked when a slave is activated
2643 HAPI int instance_recover_state(struct inst_info *inst)
2647 if (inst->changing_state) {
2648 DbgPrint("Doesn't need to recover the state\n");
2649 return LB_STATUS_SUCCESS;
2652 switch (inst->state) {
2653 case INST_ACTIVATED:
2654 case INST_REQUEST_TO_REACTIVATE:
2655 case INST_REQUEST_TO_DESTROY:
2656 switch (inst->requested_state) {
2657 case INST_ACTIVATED:
2658 DbgPrint("Req. to RE-ACTIVATED (%s)\n", package_name(inst->info));
2659 instance_state_reset(inst);
2660 instance_reactivate(inst);
2663 case INST_DESTROYED:
2664 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2665 instance_state_reset(inst);
2666 instance_destroy(inst);
2673 case INST_REQUEST_TO_ACTIVATE:
2674 switch (inst->requested_state) {
2675 case INST_ACTIVATED:
2677 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2678 instance_state_reset(inst);
2679 if (instance_activate(inst) < 0) {
2680 DbgPrint("Failed to reactivate the instance\n");
2681 instance_broadcast_deleted_event(inst);
2682 instance_state_reset(inst);
2683 instance_destroy(inst);
2688 case INST_DESTROYED:
2689 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2690 instance_state_reset(inst);
2691 instance_destroy(inst);
2698 case INST_DESTROYED:
2707 * Invoked when a slave is deactivated
2709 HAPI int instance_need_slave(struct inst_info *inst)
2713 if (inst->client && client_is_faulted(inst->client)) {
2716 * In this case, the client is faulted(disconnected)
2717 * when the client is deactivated, its liveboxes should be removed too.
2718 * So if the current inst is created by the faulted client,
2719 * remove it and don't try to recover its states
2722 DbgPrint("CLIENT FAULT: Req. to DESTROYED (%s)\n", package_name(inst->info));
2723 switch (inst->state) {
2725 case INST_ACTIVATED:
2726 case INST_REQUEST_TO_REACTIVATE:
2727 case INST_REQUEST_TO_DESTROY:
2728 case INST_REQUEST_TO_ACTIVATE:
2729 instance_state_reset(inst);
2730 instance_destroy(inst);
2732 case INST_DESTROYED:
2736 return LB_STATUS_SUCCESS;
2739 switch (inst->state) {
2740 case INST_ACTIVATED:
2741 case INST_REQUEST_TO_REACTIVATE:
2742 case INST_REQUEST_TO_DESTROY:
2743 switch (inst->requested_state) {
2745 case INST_ACTIVATED:
2746 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2749 case INST_DESTROYED:
2750 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2751 instance_state_reset(inst);
2752 instance_destroy(inst);
2759 case INST_REQUEST_TO_ACTIVATE:
2760 switch (inst->requested_state) {
2762 case INST_ACTIVATED:
2763 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2766 case INST_DESTROYED:
2767 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2768 instance_state_reset(inst);
2769 instance_destroy(inst);
2775 case INST_DESTROYED:
2783 HAPI int instance_forward_packet(struct inst_info *inst, struct packet *packet)
2785 return CLIENT_SEND_EVENT(inst, packet);
2788 HAPI int instance_send_access_status(struct inst_info *inst, int status)
2790 struct packet *packet;
2792 packet = packet_create_noack("access_status", "ssi", package_name(inst->info), inst->id, status);
2794 ErrPrint("Failed to build a packet\n");
2795 return LB_STATUS_ERROR_FAULT;
2798 return CLIENT_SEND_EVENT(inst, packet);
2801 HAPI void instance_slave_set_pd_pos(struct inst_info *inst, double x, double y)
2807 HAPI void instance_slave_get_pd_pos(struct inst_info *inst, double *x, double *y)
2815 HAPI int instance_slave_open_pd(struct inst_info *inst, struct client_node *client)
2817 const char *pkgname;
2819 struct packet *packet;
2820 struct slave_node *slave;
2821 const struct pkg_info *info;
2825 client = inst->pd.owner;
2827 ErrPrint("Client is not valid\n");
2828 return LB_STATUS_ERROR_INVALID;
2830 } else if (inst->pd.owner) {
2831 if (inst->pd.owner != client) {
2832 ErrPrint("Client is already owned\n");
2833 return LB_STATUS_ERROR_ALREADY;
2837 slave = package_slave(instance_package(inst));
2839 return LB_STATUS_ERROR_FAULT;
2841 info = instance_package(inst);
2843 return LB_STATUS_ERROR_INVALID;
2845 pkgname = package_name(info);
2846 id = instance_id(inst);
2848 if (!pkgname || !id)
2849 return LB_STATUS_ERROR_INVALID;
2851 packet = packet_create_noack("pd_show", "ssiidd", pkgname, id, instance_pd_width(inst), instance_pd_height(inst), inst->pd.x, inst->pd.y);
2853 ErrPrint("Failed to create a packet\n");
2854 return LB_STATUS_ERROR_FAULT;
2859 * Do not return from here even though we failed to freeze the TTL timer.
2860 * Because the TTL timer is not able to be exists.
2861 * So we can ignore this error.
2863 (void)slave_freeze_ttl(slave);
2865 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2867 ErrPrint("Unable to send request to slave\n");
2870 * Also we can ignore the TTL timer at here too ;)
2872 (void)slave_thaw_ttl(slave);
2878 * If a client is disconnected, the slave has to close the PD
2879 * So the pd_buffer_close_cb/pd_script_close_cb will catch the disconnection event
2880 * then it will send the close request to the slave
2882 if (package_pd_type(info) == PD_TYPE_BUFFER) {
2884 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) < 0)
2885 instance_unref(inst);
2886 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
2888 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) < 0)
2889 instance_unref(inst);
2892 inst->pd.owner = client;
2893 DbgPrint("pd,show event is sent\n");
2897 HAPI int instance_slave_close_pd(struct inst_info *inst, struct client_node *client)
2899 const char *pkgname;
2901 struct packet *packet;
2902 struct slave_node *slave;
2903 struct pkg_info *pkg;
2906 if (inst->pd.owner != client)
2907 return LB_STATUS_ERROR_INVALID;
2909 slave = package_slave(instance_package(inst));
2911 return LB_STATUS_ERROR_FAULT;
2913 pkg = instance_package(inst);
2915 return LB_STATUS_ERROR_INVALID;
2917 pkgname = package_name(pkg);
2918 id = instance_id(inst);
2920 if (!pkgname || !id)
2921 return LB_STATUS_ERROR_INVALID;
2923 packet = packet_create_noack("pd_hide", "ss", pkgname, id);
2925 return LB_STATUS_ERROR_FAULT;
2927 slave_thaw_ttl(slave);
2929 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2930 release_resource_for_closing_pd(pkg, inst, client);
2931 inst->pd.owner = NULL;
2935 HAPI int instance_client_pd_created(struct inst_info *inst, int status)
2937 struct packet *packet;
2941 if (inst->pd.need_to_send_close_event) {
2942 DbgPrint("PD is already created\n");
2943 return LB_STATUS_ERROR_INVALID;
2946 switch (package_pd_type(inst->info)) {
2947 case PD_TYPE_SCRIPT:
2948 buf_id = fb_id(script_handler_fb(inst->pd.canvas.script));
2950 case PD_TYPE_BUFFER:
2951 buf_id = buffer_handler_id(inst->pd.canvas.buffer);
2959 inst->pd.need_to_send_close_event = (status == 0);
2961 packet = packet_create_noack("pd_created", "sssiii",
2962 package_name(inst->info), inst->id, buf_id,
2963 inst->pd.width, inst->pd.height, status);
2965 ErrPrint("Failed to create a packet\n");
2966 return LB_STATUS_ERROR_FAULT;
2969 ret = CLIENT_SEND_EVENT(inst, packet);
2971 if (inst->pd.need_to_send_close_event && inst->pd.pended_update_cnt) {
2972 DbgPrint("Apply pended desc(%d) - %s\n", inst->pd.pended_update_cnt, inst->pd.pended_update_desc);
2973 instance_pd_updated_by_instance(inst, inst->pd.pended_update_desc);
2974 inst->pd.pended_update_cnt = 0;
2975 DbgFree(inst->pd.pended_update_desc);
2976 inst->pd.pended_update_desc = NULL;
2982 HAPI int instance_client_pd_destroyed(struct inst_info *inst, int status)
2984 if (!inst->pd.need_to_send_close_event) {
2985 DbgPrint("PD is not created\n");
2986 return LB_STATUS_ERROR_INVALID;
2989 inst->pd.need_to_send_close_event = 0;
2991 return send_pd_destroyed_to_client(inst, status);
2994 HAPI int instance_add_client(struct inst_info *inst, struct client_node *client)
2996 if (inst->client == client) {
2997 ErrPrint("Owner cannot be the viewer\n");
2998 return LB_STATUS_ERROR_INVALID;
3001 DbgPrint("%d is added to the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
3002 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst) < 0) {
3003 ErrPrint("Failed to add a deactivate callback\n");
3004 return LB_STATUS_ERROR_FAULT;
3008 inst->client_list = eina_list_append(inst->client_list, client);
3009 return LB_STATUS_SUCCESS;
3012 HAPI int instance_del_client(struct inst_info *inst, struct client_node *client)
3014 if (inst->client == client) {
3015 ErrPrint("Owner is not in the viewer list\n");
3016 return LB_STATUS_ERROR_INVALID;
3019 client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst);
3020 viewer_deactivated_cb(client, inst);
3021 return LB_STATUS_SUCCESS;
3024 HAPI int instance_has_client(struct inst_info *inst, struct client_node *client)
3026 return !!eina_list_data_find(inst->client_list, client);
3029 HAPI void *instance_client_list(struct inst_info *inst)
3031 return inst->client_list;
3034 HAPI int instance_init(void)
3036 if (!strcasecmp(PROVIDER_METHOD, "shm"))
3037 s_info.env_buf_type = BUFFER_TYPE_SHM;
3038 else if (!strcasecmp(PROVIDER_METHOD, "pixmap"))
3039 s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
3040 /* Default method is BUFFER_TYPE_FILE */
3042 return LB_STATUS_SUCCESS;
3045 HAPI int instance_fini(void)
3047 return LB_STATUS_SUCCESS;
3050 static inline struct tag_item *find_tag_item(struct inst_info *inst, const char *tag)
3052 struct tag_item *item;
3055 EINA_LIST_FOREACH(inst->data_list, l, item) {
3056 if (!strcmp(item->tag, tag))
3063 HAPI int instance_set_data(struct inst_info *inst, const char *tag, void *data)
3065 struct tag_item *item;
3067 item = find_tag_item(inst, tag);
3069 item = malloc(sizeof(*item));
3071 ErrPrint("Heap: %s\n", strerror(errno));
3072 return LB_STATUS_ERROR_MEMORY;
3075 item->tag = strdup(tag);
3077 ErrPrint("Heap: %s\n", strerror(errno));
3079 return LB_STATUS_ERROR_MEMORY;
3082 inst->data_list = eina_list_append(inst->data_list, item);
3086 inst->data_list = eina_list_remove(inst->data_list, item);
3093 return LB_STATUS_SUCCESS;
3096 HAPI void *instance_del_data(struct inst_info *inst, const char *tag)
3098 struct tag_item *item;
3101 item = find_tag_item(inst, tag);
3105 inst->data_list = eina_list_remove(inst->data_list, item);
3113 HAPI void *instance_get_data(struct inst_info *inst, const char *tag)
3115 struct tag_item *item;
3117 item = find_tag_item(inst, tag);