2 * Copyright 2012 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.0 (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://www.tizenopensource.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>
34 #include "slave_life.h"
35 #include "slave_rpc.h"
36 #include "client_life.h"
38 #include "client_rpc.h"
40 #include "script_handler.h"
41 #include "buffer_handler.h"
48 enum buffer_type env_buf_type;
50 .env_buf_type = BUFFER_TYPE_FILE,
53 struct set_pinup_cbdata {
54 struct inst_info *inst;
58 struct resize_cbdata {
59 struct inst_info *inst;
64 struct change_group_cbdata {
65 struct inst_info *inst;
70 struct period_cbdata {
71 struct inst_info *inst;
76 struct pkg_info *info;
78 enum instance_state state; /*!< Represents current state */
79 enum instance_state requested_state; /*!< Only ACTIVATED | DESTROYED is acceptable */
92 enum livebox_visible_state visible;
100 struct script_info *script;
101 struct buffer_info *buffer;
104 const char *auto_launch;
114 struct script_info *script;
115 struct buffer_info *buffer;
118 struct client_node *owner;
119 int is_opened_for_reactivate;
120 int need_to_send_close_event;
121 char *pended_update_desc;
122 int pended_update_cnt;
128 struct client_node *client; /*!< Owner - creator */
129 Eina_List *client_list; /*!< Viewer list */
132 Ecore_Timer *update_timer; /*!< Only used for secured livebox */
135 #define CLIENT_SEND_EVENT(instance, packet) ((instance)->client ? client_rpc_async_request((instance)->client, (packet)) : client_broadcast((instance), (packet)))
137 static Eina_Bool update_timer_cb(void *data);
139 static inline void timer_thaw(struct inst_info *inst)
146 ecore_timer_thaw(inst->update_timer);
147 period = ecore_timer_interval_get(inst->update_timer);
148 pending = ecore_timer_pending_get(inst->update_timer);
149 delay = util_time_delay_for_compensation(period) - pending;
150 ecore_timer_delay(inst->update_timer, delay);
151 DbgPrint("Compensated: %lf\n", delay);
153 if (inst->sleep_at == 0.0f)
156 sleep_time = util_timestamp() - inst->sleep_at;
157 if (sleep_time > pending) {
158 DbgPrint("Update time elapsed\n");
159 (void)update_timer_cb(inst);
162 inst->sleep_at = 0.0f;
165 static inline void timer_freeze(struct inst_info *inst)
168 ecore_timer_freeze(inst->update_timer);
170 if (ecore_timer_interval_get(inst->update_timer) <= 1.0f)
173 gettimeofday(&tv, NULL);
174 inst->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
178 static int viewer_deactivated_cb(struct client_node *client, void *data)
180 struct inst_info *inst = data;
182 DbgPrint("%d is deleted from the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
183 if (!eina_list_data_find(inst->client_list, client)) {
184 DbgPrint("Not found\n");
188 inst->client_list = eina_list_remove(inst->client_list, client);
189 if (!inst->client_list && !inst->client) {
190 DbgPrint("Has no clients\n");
191 instance_destroy(inst);
194 instance_unref(inst);
195 return -1; /*!< Remove this callback from the cb list */
198 static inline int pause_livebox(struct inst_info *inst)
200 struct packet *packet;
202 packet = packet_create_noack("lb_pause", "ss", package_name(inst->info), inst->id);
204 ErrPrint("Failed to create a new packet\n");
208 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
211 /*! \TODO Wake up the freeze'd timer */
212 static inline int resume_livebox(struct inst_info *inst)
214 struct packet *packet;
216 packet = packet_create_noack("lb_resume", "ss", package_name(inst->info), inst->id);
218 ErrPrint("Failed to create a new packet\n");
222 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
225 static inline int instance_recover_visible_state(struct inst_info *inst)
229 switch (inst->visible) {
232 instance_thaw_updator(inst);
236 case LB_HIDE_WITH_PAUSE:
237 ret = pause_livebox(inst);
239 instance_freeze_updator(inst);
246 DbgPrint("Visible state is recovered to %d\n", ret);
250 HAPI void instance_send_resized_event(struct inst_info *inst, int is_pd, int w, int h, int status)
252 struct packet *packet;
256 pkgname = package_name(inst->info);
259 DbgPrint("Size is changed to %dx%d (%s) %s\n", w, h, id, is_pd ? "pd" : "lb");
261 packet = packet_create_noack("size_changed", "ssiiii", pkgname, id, is_pd, w, h, status);
263 CLIENT_SEND_EVENT(inst, packet);
265 ErrPrint("Failed to send size changed event\n");
268 HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_node *client)
270 struct packet *packet;
271 enum lb_type lb_type;
272 enum pd_type pd_type;
277 client = inst->client;
282 lb_type = package_lb_type(inst->info);
283 pd_type = package_pd_type(inst->info);
285 if (lb_type == LB_TYPE_SCRIPT)
286 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
287 else if (lb_type == LB_TYPE_BUFFER)
288 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
292 if (pd_type == PD_TYPE_SCRIPT)
293 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
294 else if (pd_type == PD_TYPE_BUFFER)
295 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
299 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
301 package_name(inst->info), inst->id, inst->content,
302 inst->lb.width, inst->lb.height,
303 inst->pd.width, inst->pd.height,
304 inst->cluster, inst->category,
306 inst->lb.auto_launch,
308 package_size_list(inst->info),
310 package_pinup(inst->info),
312 inst->period, inst->title,
315 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
319 return client_rpc_async_request(client, packet);
322 static int update_client_list(struct client_node *client, void *data)
324 struct inst_info *inst = data;
326 if (!instance_has_client(inst, client)) {
327 instance_add_client(inst, client);
333 static int instance_broadcast_created_event(struct inst_info *inst)
335 struct packet *packet;
336 enum lb_type lb_type;
337 enum pd_type pd_type;
341 lb_type = package_lb_type(inst->info);
342 pd_type = package_pd_type(inst->info);
344 if (lb_type == LB_TYPE_SCRIPT)
345 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
346 else if (lb_type == LB_TYPE_BUFFER)
347 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
351 if (pd_type == PD_TYPE_SCRIPT)
352 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
353 else if (pd_type == PD_TYPE_BUFFER)
354 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
359 client_browse_list(inst->cluster, inst->category, update_client_list, inst);
361 packet = packet_create_noack("created", "dsssiiiisssssdiiiiidsi",
363 package_name(inst->info), inst->id, inst->content,
364 inst->lb.width, inst->lb.height,
365 inst->pd.width, inst->pd.height,
366 inst->cluster, inst->category,
368 inst->lb.auto_launch,
370 package_size_list(inst->info),
372 package_pinup(inst->info),
374 inst->period, inst->title,
377 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
381 return CLIENT_SEND_EVENT(inst, packet);
384 HAPI int instance_unicast_deleted_event(struct inst_info *inst, struct client_node *client)
386 struct packet *packet;
389 client = inst->client;
394 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
396 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
400 return client_rpc_async_request(client, packet);
403 static int instance_broadcast_deleted_event(struct inst_info *inst)
405 struct packet *packet;
406 struct client_node *client;
411 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
413 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
417 ret = CLIENT_SEND_EVENT(inst, packet);
419 EINA_LIST_FOREACH_SAFE(inst->client_list, l, n, client) {
420 instance_del_client(inst, client);
426 static int client_deactivated_cb(struct client_node *client, void *data)
428 struct inst_info *inst = data;
429 instance_destroy(inst);
433 static int send_pd_destroyed_to_client(struct inst_info *inst, int status)
435 struct packet *packet;
437 packet = packet_create_noack("pd_destroyed", "ssi", package_name(inst->info), inst->id, status);
439 ErrPrint("Failed to create a packet\n");
443 return CLIENT_SEND_EVENT(inst, packet);
446 static inline void destroy_instance(struct inst_info *inst)
448 struct pkg_info *pkg;
449 enum lb_type lb_type;
450 enum pd_type pd_type;
451 struct slave_node *slave;
455 lb_type = package_lb_type(pkg);
456 pd_type = package_pd_type(pkg);
457 slave = package_slave(inst->info);
459 DbgPrint("Instance is destroyed (%p), slave(%p)\n", inst, slave);
461 if (inst->pd.need_to_send_close_event)
462 send_pd_destroyed_to_client(inst, 0);
464 if (lb_type == LB_TYPE_SCRIPT) {
465 script_handler_unload(inst->lb.canvas.script, 0);
466 script_handler_destroy(inst->lb.canvas.script);
467 } else if (lb_type == LB_TYPE_BUFFER) {
468 buffer_handler_unload(inst->lb.canvas.buffer);
469 buffer_handler_destroy(inst->lb.canvas.buffer);
472 if (pd_type == PD_TYPE_SCRIPT) {
473 script_handler_unload(inst->pd.canvas.script, 1);
474 script_handler_destroy(inst->pd.canvas.script);
475 } else if (pd_type == PD_TYPE_BUFFER) {
476 buffer_handler_unload(inst->pd.canvas.buffer);
477 buffer_handler_destroy(inst->pd.canvas.buffer);
481 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
482 client_unref(inst->client);
485 if (inst->update_timer)
486 ecore_timer_del(inst->update_timer);
491 * inst->lb.auto_launch
493 * will be released by the package object
494 * it is readonly value for instances
496 DbgFree(inst->category);
497 DbgFree(inst->cluster);
498 DbgFree(inst->content);
499 DbgFree(inst->title);
500 util_unlink(inst->id);
502 package_del_instance(inst->info, inst);
505 slave = slave_unload_instance(slave);
508 static Eina_Bool update_timer_cb(void *data)
510 struct inst_info *inst = (struct inst_info *)data;
512 DbgPrint("Update instance %s (%s) %s/%s\n", package_name(inst->info), inst->id, inst->cluster, inst->category);
513 slave_rpc_request_update(package_name(inst->info), inst->id, inst->cluster, inst->category);
514 return ECORE_CALLBACK_RENEW;
517 static inline int fork_package(struct inst_info *inst, const char *pkgname)
519 struct pkg_info *info;
522 info = package_find(pkgname);
524 ErrPrint("%s is not found\n", pkgname);
528 len = strlen(SCHEMA_FILE "%s%s_%d_%lf.png") + strlen(IMAGE_PATH) + strlen(package_name(info)) + 50;
529 inst->id = malloc(len);
531 ErrPrint("Heap: %s\n", strerror(errno));
535 snprintf(inst->id, len, SCHEMA_FILE "%s%s_%d_%lf.png", IMAGE_PATH, package_name(info), client_pid(inst->client), inst->timestamp);
536 inst->lb.auto_launch = package_auto_launch(info);
538 instance_set_pd_info(inst, package_pd_width(info), package_pd_height(info));
540 inst->timeout = package_timeout(info);
541 inst->period = package_period(info);
545 if (package_secured(info)) {
546 DbgPrint("Register the update timer for secured livebox [%s]\n", package_name(info));
547 inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst);
548 if (!inst->update_timer)
549 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
551 timer_freeze(inst); /* Freeze the update timer as default */
557 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)
559 struct inst_info *inst;
561 inst = calloc(1, sizeof(*inst));
563 ErrPrint("Heap: %s\n", strerror(errno));
567 inst->timestamp = timestamp;
568 inst->lb.width = width;
569 inst->lb.height = height;
571 inst->content = strdup(content);
572 if (!inst->content) {
573 ErrPrint("Heap: %s\n", strerror(errno));
578 inst->cluster = strdup(cluster);
579 if (!inst->cluster) {
580 ErrPrint("Heap: %s\n", strerror(errno));
581 DbgFree(inst->content);
586 inst->category = strdup(category);
587 if (!inst->category) {
588 ErrPrint("Heap: %s\n", strerror(errno));
589 DbgFree(inst->cluster);
590 DbgFree(inst->content);
595 inst->title = strdup(DEFAULT_TITLE); /*!< Use the DEFAULT Title "" */
597 ErrPrint("Heap: %s\n", strerror(errno));
598 DbgFree(inst->category);
599 DbgFree(inst->cluster);
600 DbgFree(inst->content);
606 inst->client = client_ref(client);
607 client_event_callback_add(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
610 if (fork_package(inst, pkgname) < 0) {
611 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
612 client_unref(inst->client);
613 DbgFree(inst->title);
614 DbgFree(inst->category);
615 DbgFree(inst->cluster);
616 DbgFree(inst->content);
621 inst->state = INST_INIT;
622 inst->requested_state = INST_INIT;
625 if (package_add_instance(inst->info, inst) < 0) {
626 instance_state_reset(inst);
627 instance_destroy(inst);
631 slave_load_instance(package_slave(inst->info));
633 if (instance_activate(inst) < 0) {
634 instance_state_reset(inst);
635 instance_destroy(inst);
642 HAPI struct inst_info *instance_ref(struct inst_info *inst)
651 HAPI struct inst_info *instance_unref(struct inst_info *inst)
656 if (inst->refcnt == 0) {
657 ErrPrint("Instance refcnt is not valid\n");
662 if (inst->refcnt == 0) {
663 destroy_instance(inst);
670 static void deactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
672 struct inst_info *inst = data;
673 struct pkg_info *info;
678 * In this callback, we cannot trust the "client" information.
679 * It could be cleared before reach to here.
683 DbgPrint("Consuming a request of a dead process\n");
686 * The instance_reload will care this.
687 * And it will be called from the slave activate callback.
689 inst->changing_state = 0;
690 instance_unref(inst);
694 if (packet_get(packet, "i", &ret) != 1) {
695 ErrPrint("Invalid argument\n");
696 inst->changing_state = 0;
697 instance_unref(inst);
701 if (inst->state == INST_DESTROYED) {
705 * Do nothing at here anymore.
707 inst->changing_state = 0;
708 instance_unref(inst);
716 * Successfully unloaded
718 switch (inst->requested_state) {
720 DbgPrint("REQ: ACTIVATED\n");
721 instance_state_reset(inst);
722 instance_reactivate(inst);
726 instance_broadcast_deleted_event(inst);
727 instance_state_reset(inst);
728 instance_destroy(inst);
729 DbgPrint("== %s\n", package_name(info));
731 /*!< Unable to reach here */
739 * Slave has no instance of this package.
744 * This instance's previous state is only can be the INST_ACTIVATED.
745 * So we should care the slave_unload_instance from here.
746 * And we should send notification to clients, about this is deleted.
750 * Slave has no instance of this.
751 * In this case, ignore the requested_state
752 * Because, this instance is already met a problem.
757 * Failed to unload this instance.
758 * This is not possible, slave will always return -ENOENT, -EINVAL, or 0.
759 * but care this exceptional case.
761 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(inst->info), ret);
763 instance_broadcast_deleted_event(inst);
764 instance_state_reset(inst);
765 instance_destroy(inst);
769 inst->changing_state = 0;
770 instance_unref(inst);
773 static void reactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
775 struct inst_info *inst = data;
776 struct pkg_info *info;
777 enum lb_type lb_type;
778 enum pd_type pd_type;
785 DbgPrint("Consuming a request of a dead process\n");
788 * instance_reload function will care this.
789 * and it will be called from the slave_activate callback
794 if (packet_get(packet, "issi", &ret, &content, &title, &is_pinned_up) != 4) {
795 ErrPrint("Invalid parameter\n");
799 if (strlen(content)) {
802 tmp = strdup(content);
804 ErrPrint("Heap: %s\n", strerror(errno));
808 DbgFree(inst->content);
811 DbgPrint("Update content info %s\n", tmp);
819 ErrPrint("Heap: %s\n", strerror(errno));
823 DbgFree(inst->title);
826 DbgPrint("Update title info %s\n", tmp);
829 if (inst->state == INST_DESTROYED) {
833 * Do nothing at here anymore.
839 case 0: /*!< normally created */
840 inst->state = INST_ACTIVATED;
841 switch (inst->requested_state) {
843 instance_destroy(inst);
846 inst->is_pinned_up = is_pinned_up;
848 lb_type = package_lb_type(info);
849 pd_type = package_pd_type(info);
853 * Optimization point.
854 * In case of the BUFFER type,
855 * the slave will request the buffer to render its contents.
856 * so the buffer will be automatcially recreated when it gots the
857 * buffer request packet.
858 * so load a buffer from here is not neccessary.
859 * I should to revise it and concrete the concept.
860 * Just leave it only for now.
863 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script) {
864 script_handler_load(inst->lb.canvas.script, 0);
865 } else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer) {
866 buffer_handler_load(inst->lb.canvas.buffer);
869 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script && inst->pd.is_opened_for_reactivate) {
872 instance_slave_get_pd_pos(inst, &x, &y);
876 * We should to send a request to open a PD to slave.
877 * if we didn't send it, the slave will not recognize the state of a PD.
878 * We have to keep the view of PD seamless even if the livebox is reactivated.
879 * To do that, send open request from here.
881 ret = instance_slave_open_pd(inst, NULL);
885 * In this case, master already loads the PD script.
886 * So just send the pd,show event to the slave again.
888 ret = instance_signal_emit(inst,
889 "pd,show", util_uri_to_path(instance_id(inst)),
890 0.0, 0.0, 0.0, 0.0, x, y, 0);
891 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer && inst->pd.is_opened_for_reactivate) {
894 buffer_handler_load(inst->pd.canvas.buffer);
895 instance_slave_get_pd_pos(inst, &x, &y);
899 * We should to send a request to open a PD to slave.
900 * if we didn't send it, the slave will not recognize the state of a PD.
901 * We have to keep the view of PD seamless even if the livebox is reactivated.
902 * To do that, send open request from here.
904 ret = instance_slave_open_pd(inst, NULL);
908 * In this case, just send the pd,show event for keeping the compatibility
910 ret = instance_signal_emit(inst,
911 "pd,show", util_uri_to_path(instance_id(inst)),
912 0.0, 0.0, 0.0, 0.0, x, y, 0);
917 * After create an instance again,
918 * Send resize request to the livebox.
919 * instance_resize(inst, inst->lb.width, inst->lb.height);
921 * renew request will resize the livebox while creating it again
926 * This function will check the visiblity of a livebox and
927 * make decision whether it thaw the update timer or not.
929 instance_recover_visible_state(inst);
936 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(info), ret);
937 instance_broadcast_deleted_event(inst);
938 instance_state_reset(inst);
939 instance_destroy(inst);
944 inst->changing_state = 0;
945 instance_unref(inst);
948 static void activate_cb(struct slave_node *slave, const struct packet *packet, void *data)
950 struct inst_info *inst = data;
960 DbgPrint("Consuming a request of a dead process\n");
963 * instance_reload will care this
964 * it will be called from the slave_activate callback
969 if (packet_get(packet, "iiidssi", &ret, &w, &h, &priority, &content, &title, &is_pinned_up) != 7) {
970 ErrPrint("Invalid parameter\n");
974 if (inst->state == INST_DESTROYED) {
978 * Do nothing at here anymore.
984 case 1: /*!< need to create */
985 if (util_free_space(IMAGE_PATH) > MINIMUM_SPACE) {
986 struct inst_info *new_inst;
987 new_inst = instance_create(inst->client, util_timestamp(), package_name(inst->info),
988 inst->content, inst->cluster, inst->category,
991 ErrPrint("Failed to create a new instance\n");
993 ErrPrint("Not enough space\n");
995 case 0: /*!< normally created */
998 * Anyway this instance is loaded to the slave,
999 * so just increase the loaded instance counter
1000 * After that, do reset jobs.
1002 instance_set_lb_info(inst, w, h, priority, content, title);
1004 inst->state = INST_ACTIVATED;
1006 switch (inst->requested_state) {
1007 case INST_DESTROYED:
1008 instance_unicast_deleted_event(inst, NULL);
1009 instance_state_reset(inst);
1010 instance_destroy(inst);
1012 case INST_ACTIVATED:
1016 * LB should be created at the create time
1018 inst->is_pinned_up = is_pinned_up;
1019 if (package_lb_type(inst->info) == LB_TYPE_SCRIPT) {
1020 if (inst->lb.width == 0 && inst->lb.height == 0)
1021 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1023 inst->lb.canvas.script = script_handler_create(inst,
1024 package_lb_path(inst->info),
1025 package_lb_group(inst->info),
1026 inst->lb.width, inst->lb.height);
1028 if (!inst->lb.canvas.script)
1029 ErrPrint("Failed to create LB\n");
1031 script_handler_load(inst->lb.canvas.script, 0);
1032 } else if (package_lb_type(inst->info) == LB_TYPE_BUFFER) {
1033 instance_create_lb_buffer(inst);
1036 if (package_pd_type(inst->info) == PD_TYPE_SCRIPT) {
1037 if (inst->pd.width == 0 && inst->pd.height == 0)
1038 instance_set_pd_info(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1040 inst->pd.canvas.script = script_handler_create(inst,
1041 package_pd_path(inst->info),
1042 package_pd_group(inst->info),
1043 inst->pd.width, inst->pd.height);
1045 if (!inst->pd.canvas.script)
1046 ErrPrint("Failed to create PD\n");
1047 } else if (package_pd_type(inst->info) == PD_TYPE_BUFFER) {
1048 instance_create_pd_buffer(inst);
1051 instance_broadcast_created_event(inst);
1053 instance_thaw_updator(inst);
1058 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(inst->info), ret);
1059 instance_unicast_deleted_event(inst, NULL);
1060 instance_state_reset(inst);
1061 instance_destroy(inst);
1066 inst->changing_state = 0;
1067 instance_unref(inst);
1070 HAPI int instance_create_pd_buffer(struct inst_info *inst)
1072 if (inst->pd.width == 0 && inst->pd.height == 0)
1073 instance_set_pd_info(inst, package_pd_width(inst->info), package_pd_height(inst->info));
1075 if (!inst->pd.canvas.buffer) {
1076 inst->pd.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->pd.width, inst->pd.height, sizeof(int));
1077 if (!inst->pd.canvas.buffer)
1078 ErrPrint("Failed to create PD Buffer\n");
1081 return !!inst->pd.canvas.buffer;
1084 HAPI int instance_create_lb_buffer(struct inst_info *inst)
1086 if (inst->lb.width == 0 && inst->lb.height == 0)
1087 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1089 if (!inst->lb.canvas.buffer) {
1092 * Slave doesn't call the acquire_buffer.
1093 * In this case, create the buffer from here.
1095 inst->lb.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->lb.width, inst->lb.height, sizeof(int));
1096 if (!inst->lb.canvas.buffer)
1097 ErrPrint("Failed to create LB\n");
1100 return !!inst->lb.canvas.buffer;
1103 HAPI int instance_destroy(struct inst_info *inst)
1105 struct packet *packet;
1108 ErrPrint("Invalid instance handle\n");
1112 switch (inst->state) {
1113 case INST_REQUEST_TO_ACTIVATE:
1114 case INST_REQUEST_TO_DESTROY:
1115 case INST_REQUEST_TO_REACTIVATE:
1116 inst->requested_state = INST_DESTROYED;
1119 inst->state = INST_DESTROYED;
1120 inst->requested_state = INST_DESTROYED;
1121 instance_unref(inst);
1123 case INST_DESTROYED:
1124 inst->requested_state = INST_DESTROYED;
1130 packet = packet_create("delete", "ss", package_name(inst->info), inst->id);
1132 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1136 inst->requested_state = INST_DESTROYED;
1137 inst->state = INST_REQUEST_TO_DESTROY;
1138 inst->changing_state = 1;
1139 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, deactivate_cb, instance_ref(inst), 0);
1142 /* Client Deactivated Callback */
1143 static int pd_buffer_close_cb(struct client_node *client, void *inst)
1147 ret = instance_slave_close_pd(inst, client);
1148 DbgPrint("Forcely close the PD ret: %d\n", ret);
1149 return -1; /* Delete this callback */
1152 /* Client Deactivated Callback */
1153 static int pd_script_close_cb(struct client_node *client, void *inst)
1157 ret = instance_slave_close_pd(inst, client);
1158 DbgPrint("Forcely close the PD ret: %d\n", ret);
1160 ret = script_handler_unload(instance_pd_script(inst), 1);
1161 return -1; /* Delete this callback */
1164 static inline void release_resource_for_closing_pd(struct pkg_info *info, struct inst_info *inst, struct client_node *client)
1167 client = inst->pd.owner;
1174 * Clean up the resources
1176 if (package_pd_type(info) == PD_TYPE_BUFFER) {
1177 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) == 0) {
1180 * Only if this function succeed to remove the pd_buffer_close_cb,
1181 * Decrease the reference count of this instance
1184 instance_unref(inst);
1185 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
1186 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) == 0) {
1189 * Only if this function succeed to remove the script_close_cb,
1190 * Decrease the reference count of this instance
1193 instance_unref(inst);
1195 ErrPrint("Unknown PD type\n");
1200 HAPI int instance_state_reset(struct inst_info *inst)
1202 enum lb_type lb_type;
1203 enum pd_type pd_type;
1206 ErrPrint("Invalid instance handle\n");
1210 if (inst->state == INST_DESTROYED)
1213 lb_type = package_lb_type(inst->info);
1214 pd_type = package_pd_type(inst->info);
1216 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script)
1217 script_handler_unload(inst->lb.canvas.script, 0);
1218 else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer)
1219 buffer_handler_unload(inst->lb.canvas.buffer);
1221 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script) {
1222 inst->pd.is_opened_for_reactivate = script_handler_is_loaded(inst->pd.canvas.script);
1223 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1224 script_handler_unload(inst->pd.canvas.script, 1);
1225 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer) {
1226 inst->pd.is_opened_for_reactivate = buffer_handler_is_loaded(inst->pd.canvas.buffer);
1227 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1228 buffer_handler_unload(inst->pd.canvas.buffer);
1231 inst->state = INST_INIT;
1232 inst->requested_state = INST_INIT;
1236 HAPI int instance_reactivate(struct inst_info *inst)
1238 struct packet *packet;
1242 ErrPrint("Invalid instance handle\n");
1246 if (package_is_fault(inst->info)) {
1247 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1251 switch (inst->state) {
1252 case INST_REQUEST_TO_DESTROY:
1253 case INST_REQUEST_TO_ACTIVATE:
1254 case INST_REQUEST_TO_REACTIVATE:
1255 inst->requested_state = INST_ACTIVATED;
1257 case INST_DESTROYED:
1258 case INST_ACTIVATED:
1265 packet = packet_create("renew", "sssiidssiis",
1266 package_name(inst->info),
1270 !!package_lb_path(inst->info),
1274 inst->lb.width, inst->lb.height,
1275 package_abi(inst->info));
1277 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1281 ret = slave_activate(package_slave(inst->info));
1282 if (ret < 0 && ret != -EALREADY) {
1285 * If the master failed to launch the slave,
1286 * Do not send any requests to the slave.
1288 ErrPrint("Failed to launch the slave\n");
1289 packet_destroy(packet);
1293 inst->requested_state = INST_ACTIVATED;
1294 inst->state = INST_REQUEST_TO_REACTIVATE;
1295 inst->changing_state = 1;
1297 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, reactivate_cb, instance_ref(inst), 1);
1300 HAPI int instance_activate(struct inst_info *inst)
1302 struct packet *packet;
1306 ErrPrint("Invalid instance handle\n");
1310 if (package_is_fault(inst->info)) {
1311 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1315 switch (inst->state) {
1316 case INST_REQUEST_TO_REACTIVATE:
1317 case INST_REQUEST_TO_ACTIVATE:
1318 case INST_REQUEST_TO_DESTROY:
1319 inst->requested_state = INST_ACTIVATED;
1321 case INST_ACTIVATED:
1322 case INST_DESTROYED:
1329 packet = packet_create("new", "sssiidssisii",
1330 package_name(inst->info),
1334 !!package_lb_path(inst->info),
1339 package_abi(inst->info),
1343 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1347 ret = slave_activate(package_slave(inst->info));
1348 if (ret < 0 && ret != -EALREADY) {
1351 * If the master failed to launch the slave,
1352 * Do not send any requests to the slave.
1354 ErrPrint("Failed to launch the slave\n");
1355 packet_destroy(packet);
1359 inst->state = INST_REQUEST_TO_ACTIVATE;
1360 inst->requested_state = INST_ACTIVATED;
1361 inst->changing_state = 1;
1365 * Try to activate a slave if it is not activated
1367 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, activate_cb, instance_ref(inst), 1);
1370 HAPI void instance_lb_updated(const char *pkgname, const char *id)
1372 struct inst_info *inst;
1374 inst = package_find_instance_by_id(pkgname, id);
1378 instance_lb_updated_by_instance(inst);
1381 HAPI void instance_lb_updated_by_instance(struct inst_info *inst)
1383 struct packet *packet;
1385 enum lb_type lb_type;
1387 const char *content;
1389 if (inst->client && inst->visible != LB_SHOW) {
1390 if (inst->visible == LB_HIDE) {
1391 DbgPrint("Ignore update event %s(HIDE)\n", inst->id);
1394 DbgPrint("Livebox(%s) is PAUSED. But content is updated.\n", inst->id);
1397 lb_type = package_lb_type(inst->info);
1398 if (lb_type == LB_TYPE_SCRIPT)
1399 id = fb_id(script_handler_fb(inst->lb.canvas.script));
1400 else if (lb_type == LB_TYPE_BUFFER)
1401 id = buffer_handler_id(inst->lb.canvas.buffer);
1406 content = inst->content;
1411 title = inst->title;
1415 packet = packet_create_noack("lb_updated", "sssiidss",
1416 package_name(inst->info), inst->id, id,
1417 inst->lb.width, inst->lb.height, inst->lb.priority, content, title);
1419 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1423 (void)CLIENT_SEND_EVENT(inst, packet);
1426 HAPI void instance_pd_updated_by_instance(struct inst_info *inst, const char *descfile)
1428 struct packet *packet;
1431 if (inst->client && inst->visible != LB_SHOW) {
1432 DbgPrint("Livebox is hidden. ignore update event\n");
1436 if (!inst->pd.need_to_send_close_event) {
1437 DbgPrint("PD is not created yet. Ignore update event - %s\n", descfile);
1439 if (inst->pd.pended_update_desc) {
1440 DbgFree(inst->pd.pended_update_desc);
1441 inst->pd.pended_update_desc = NULL;
1445 inst->pd.pended_update_desc = strdup(descfile);
1446 if (!inst->pd.pended_update_desc)
1447 ErrPrint("Heap: %s\n", strerror(errno));
1450 inst->pd.pended_update_cnt++;
1455 descfile = inst->id;
1457 switch (package_pd_type(inst->info)) {
1458 case PD_TYPE_SCRIPT:
1459 id = fb_id(script_handler_fb(inst->pd.canvas.script));
1461 case PD_TYPE_BUFFER:
1462 id = buffer_handler_id(inst->pd.canvas.buffer);
1470 packet = packet_create_noack("pd_updated", "ssssii",
1471 package_name(inst->info), inst->id, descfile, id,
1472 inst->pd.width, inst->pd.height);
1474 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1478 (void)CLIENT_SEND_EVENT(inst, packet);
1481 HAPI void instance_pd_updated(const char *pkgname, const char *id, const char *descfile)
1483 struct inst_info *inst;
1485 inst = package_find_instance_by_id(pkgname, id);
1489 instance_pd_updated_by_instance(inst, descfile);
1492 HAPI void instance_set_lb_info(struct inst_info *inst, int w, int h, double priority, const char *content, const char *title)
1494 char *_content = NULL;
1495 char *_title = NULL;
1497 if (content && strlen(content)) {
1498 _content = strdup(content);
1500 ErrPrint("Heap: %s\n", strerror(errno));
1503 if (title && strlen(title)) {
1504 _title = strdup(title);
1506 ErrPrint("Heap: %s\n", strerror(errno));
1510 DbgFree(inst->content);
1511 inst->content= _content;
1515 DbgFree(inst->title);
1516 inst->title = _title;
1519 if (priority >= 0.0f && priority <= 1.0f)
1520 inst->lb.priority = priority;
1523 inst->lb.height = h;
1526 HAPI void instance_set_pd_info(struct inst_info *inst, int w, int h)
1529 inst->pd.height = h;
1532 static void pinup_cb(struct slave_node *slave, const struct packet *packet, void *data)
1534 struct set_pinup_cbdata *cbdata = data;
1535 const char *content;
1536 struct packet *result;
1542 * Send pinup failed event to client.
1548 if (packet_get(packet, "is", &ret, &content) != 2) {
1551 * Send pinup failed event to client
1560 new_content = strdup(content);
1562 ErrPrint("Heap: %s\n", strerror(errno));
1565 * send pinup failed event to client
1571 cbdata->inst->is_pinned_up = cbdata->pinup;
1572 DbgFree(cbdata->inst->content);
1574 cbdata->inst->content = new_content;
1580 * Send PINUP Result to client.
1581 * Client should wait this event.
1583 result = packet_create_noack("pinup", "iisss", ret, cbdata->inst->is_pinned_up,
1584 package_name(cbdata->inst->info), cbdata->inst->id, cbdata->inst->content);
1586 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
1588 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
1590 instance_unref(cbdata->inst);
1594 HAPI int instance_set_pinup(struct inst_info *inst, int pinup)
1596 struct set_pinup_cbdata *cbdata;
1597 struct packet *packet;
1600 ErrPrint("Invalid instance handle\n");
1604 if (package_is_fault(inst->info)) {
1605 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1609 if (!package_pinup(inst->info))
1612 if (pinup == inst->is_pinned_up)
1615 cbdata = malloc(sizeof(*cbdata));
1619 cbdata->inst = instance_ref(inst);
1620 cbdata->pinup = pinup;
1622 packet = packet_create("pinup", "ssi", package_name(inst->info), inst->id, pinup);
1624 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1625 instance_unref(cbdata->inst);
1630 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, pinup_cb, cbdata, 0);
1633 HAPI int instance_freeze_updator(struct inst_info *inst)
1635 if (!inst->update_timer)
1638 DbgPrint("Freeze the update timer (%s)\n", inst->id);
1643 HAPI int instance_thaw_updator(struct inst_info *inst)
1645 if (!inst->update_timer)
1648 if (client_is_all_paused() || setting_is_lcd_off()) {
1649 DbgPrint("Skip thaw (%s)\n", inst->id);
1653 if (inst->visible == LB_HIDE_WITH_PAUSE) {
1654 DbgPrint("Live box is invisible (%s)\n", inst->id);
1658 DbgPrint("Thaw the update timer (%s)\n", inst->id);
1663 HAPI enum livebox_visible_state instance_visible_state(struct inst_info *inst)
1665 return inst->visible;
1668 HAPI int instance_set_visible_state(struct inst_info *inst, enum livebox_visible_state state)
1670 if (inst->visible == state) {
1671 DbgPrint("Visibility has no changed\n");
1678 if (inst->visible == LB_HIDE_WITH_PAUSE) {
1679 if (resume_livebox(inst) == 0)
1680 inst->visible = state;
1682 instance_thaw_updator(inst);
1684 inst->visible = state;
1688 case LB_HIDE_WITH_PAUSE:
1689 if (pause_livebox(inst) == 0)
1690 inst->visible = LB_HIDE_WITH_PAUSE;
1692 instance_freeze_updator(inst);
1702 static void resize_cb(struct slave_node *slave, const struct packet *packet, void *data)
1704 struct resize_cbdata *cbdata = data;
1708 ErrPrint("Invalid packet\n");
1709 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, -EFAULT);
1710 instance_unref(cbdata->inst);
1715 if (packet_get(packet, "i", &ret) != 1) {
1716 ErrPrint("Invalid parameter\n");
1717 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, -EINVAL);
1718 instance_unref(cbdata->inst);
1726 * else waiting the first update with new size
1729 DbgPrint("Livebox rejects the new size: %dx%d (%d)\n", cbdata->w, cbdata->h, ret);
1730 instance_send_resized_event(cbdata->inst, IS_LB, cbdata->inst->lb.width, cbdata->inst->lb.height, ret);
1733 instance_unref(cbdata->inst);
1737 HAPI int instance_resize(struct inst_info *inst, int w, int h)
1739 struct resize_cbdata *cbdata;
1740 struct packet *packet;
1744 ErrPrint("Invalid instance handle\n");
1748 if (package_is_fault(inst->info)) {
1749 ErrPrint("Fault package: %s\n", package_name(inst->info));
1753 cbdata = malloc(sizeof(*cbdata));
1755 ErrPrint("Heap: %s\n", strerror(errno));
1759 cbdata->inst = instance_ref(inst);
1763 /* NOTE: param is resued from here */
1764 packet = packet_create("resize", "ssii", package_name(inst->info), inst->id, w, h);
1766 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1767 instance_unref(cbdata->inst);
1772 ret = slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, resize_cb, cbdata, 0);
1776 static void set_period_cb(struct slave_node *slave, const struct packet *packet, void *data)
1779 struct period_cbdata *cbdata = data;
1780 struct packet *result;
1787 if (packet_get(packet, "i", &ret) != 1) {
1793 cbdata->inst->period = cbdata->period;
1795 ErrPrint("Failed to set period %d\n", ret);
1798 result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->period, package_name(cbdata->inst->info), cbdata->inst->id);
1800 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
1802 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
1804 instance_unref(cbdata->inst);
1809 static Eina_Bool timer_updator_cb(void *data)
1811 struct period_cbdata *cbdata = data;
1812 struct inst_info *inst;
1814 struct packet *result;
1816 period = cbdata->period;
1817 inst = cbdata->inst;
1820 DbgPrint("Update period is changed to %lf from %lf\n", period, inst->period);
1822 inst->period = period;
1823 if (inst->update_timer) {
1824 if (inst->period == 0.0f) {
1825 ecore_timer_del(inst->update_timer);
1826 inst->update_timer = NULL;
1828 util_timer_interval_set(inst->update_timer, inst->period);
1830 } else if (inst->period > 0.0f) {
1831 inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst);
1832 if (!inst->update_timer)
1833 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
1835 timer_freeze(inst); /* Freeze the update timer as default */
1838 result = packet_create_noack("period_changed", "idss", 0, inst->period, package_name(inst->info), inst->id);
1840 (void)CLIENT_SEND_EVENT(inst, result);
1842 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1844 instance_unref(inst);
1845 return ECORE_CALLBACK_CANCEL;
1848 HAPI int instance_set_period(struct inst_info *inst, double period)
1850 struct packet *packet;
1851 struct period_cbdata *cbdata;
1854 ErrPrint("Invalid instance handle\n");
1858 if (package_is_fault(inst->info)) {
1859 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1863 if (period < 0.0f) { /* Use the default period */
1864 period = package_period(inst->info);
1865 } else if (period > 0.0f && period < MINIMUM_PERIOD) {
1866 period = MINIMUM_PERIOD; /* defined at conf.h */
1869 cbdata = malloc(sizeof(*cbdata));
1871 ErrPrint("Heap: %s\n", strerror(errno));
1875 cbdata->period = period;
1876 cbdata->inst = instance_ref(inst);
1878 if (package_secured(inst->info)) {
1881 * Secured livebox doesn't need to send its update period to the slave.
1882 * Slave has no local timer for updating liveboxes
1884 * So update its timer at here.
1886 if (!ecore_timer_add(DELAY_TIME, timer_updator_cb, cbdata))
1887 timer_updator_cb(cbdata);
1891 packet = packet_create("set_period", "ssd", package_name(inst->info), inst->id, period);
1893 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1894 instance_unref(cbdata->inst);
1899 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, set_period_cb, cbdata, 0);
1902 HAPI int instance_clicked(struct inst_info *inst, const char *event, double timestamp, double x, double y)
1904 struct packet *packet;
1907 ErrPrint("Invalid instance handle\n");
1911 if (package_is_fault(inst->info)) {
1912 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1916 /* NOTE: param is resued from here */
1917 packet = packet_create_noack("clicked", "sssddd", package_name(inst->info), inst->id, event, timestamp, x, y);
1919 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1923 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
1926 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)
1928 const char *pkgname;
1930 struct slave_node *slave;
1931 struct packet *packet;
1934 pkgname = package_name(instance_package(inst));
1935 id = instance_id(inst);
1936 if (!pkgname || !id) {
1937 ErrPrint("Invalid instance\n");
1941 slave = package_slave(instance_package(inst));
1943 ErrPrint("Slave is not valid\n");
1947 packet = packet_create_noack("script", "ssssddddddi",
1953 ErrPrint("Failed to create param\n");
1957 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
1961 HAPI int instance_text_signal_emit(struct inst_info *inst, const char *emission, const char *source, double sx, double sy, double ex, double ey)
1963 struct packet *packet;
1966 ErrPrint("Invalid instance handle\n");
1970 if (package_is_fault(inst->info)) {
1971 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1975 packet = packet_create_noack("text_signal", "ssssdddd", package_name(inst->info), inst->id, emission, source, sx, sy, ex, ey);
1977 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1981 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
1984 static void change_group_cb(struct slave_node *slave, const struct packet *packet, void *data)
1986 struct change_group_cbdata *cbdata = data;
1987 struct packet *result;
1991 DbgFree(cbdata->cluster);
1992 DbgFree(cbdata->category);
1997 if (packet_get(packet, "i", &ret) != 1) {
1998 ErrPrint("Invalid packet\n");
1999 DbgFree(cbdata->cluster);
2000 DbgFree(cbdata->category);
2006 DbgFree(cbdata->inst->cluster);
2007 cbdata->inst->cluster = cbdata->cluster;
2009 DbgFree(cbdata->inst->category);
2010 cbdata->inst->category = cbdata->category;
2012 DbgFree(cbdata->cluster);
2013 DbgFree(cbdata->category);
2017 result = packet_create_noack("group_changed", "ssiss",
2018 package_name(cbdata->inst->info), cbdata->inst->id, ret,
2019 cbdata->inst->cluster, cbdata->inst->category);
2021 ErrPrint("Failed to build a packet %s\n", package_name(cbdata->inst->info));
2023 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2025 instance_unref(cbdata->inst);
2029 HAPI int instance_change_group(struct inst_info *inst, const char *cluster, const char *category)
2031 struct packet *packet;
2032 struct change_group_cbdata *cbdata;
2035 ErrPrint("Invalid instance handle\n");
2039 if (package_is_fault(inst->info)) {
2040 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2044 cbdata = malloc(sizeof(*cbdata));
2046 ErrPrint("Heap: %s\n", strerror(errno));
2050 cbdata->cluster = strdup(cluster);
2051 if (!cbdata->cluster) {
2052 ErrPrint("Heap: %s\n", strerror(errno));
2057 cbdata->category = strdup(category);
2058 if (!cbdata->category) {
2059 ErrPrint("Heap: %s\n", strerror(errno));
2060 DbgFree(cbdata->cluster);
2065 cbdata->inst = instance_ref(inst);
2067 packet = packet_create("change_group","ssss", package_name(inst->info), inst->id, cluster, category);
2069 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2070 instance_unref(cbdata->inst);
2071 DbgFree(cbdata->category);
2072 DbgFree(cbdata->cluster);
2077 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, change_group_cb, cbdata, 0);
2080 HAPI const char * const instance_auto_launch(const struct inst_info *inst)
2082 return inst->lb.auto_launch;
2085 HAPI const int const instance_priority(const struct inst_info *inst)
2087 return inst->lb.priority;
2090 HAPI const struct client_node *const instance_client(const struct inst_info *inst)
2092 return inst->client;
2095 HAPI const double const instance_period(const struct inst_info *inst)
2097 return inst->period;
2100 HAPI const int const instance_lb_width(const struct inst_info *inst)
2102 return inst->lb.width;
2105 HAPI const int const instance_lb_height(const struct inst_info *inst)
2107 return inst->lb.height;
2110 HAPI const int const instance_pd_width(const struct inst_info *inst)
2112 return inst->pd.width;
2115 HAPI const int const instance_pd_height(const struct inst_info *inst)
2117 return inst->pd.height;
2120 HAPI struct pkg_info *const instance_package(const struct inst_info *inst)
2125 HAPI struct script_info *const instance_lb_script(const struct inst_info *inst)
2127 return (package_lb_type(inst->info) == LB_TYPE_SCRIPT) ? inst->lb.canvas.script : NULL;
2130 HAPI struct script_info *const instance_pd_script(const struct inst_info *inst)
2132 return (package_pd_type(inst->info) == PD_TYPE_SCRIPT) ? inst->pd.canvas.script : NULL;
2135 HAPI struct buffer_info *const instance_lb_buffer(const struct inst_info *inst)
2137 return (package_lb_type(inst->info) == LB_TYPE_BUFFER) ? inst->lb.canvas.buffer : NULL;
2140 HAPI struct buffer_info *const instance_pd_buffer(const struct inst_info *inst)
2142 return (package_pd_type(inst->info) == PD_TYPE_BUFFER) ? inst->pd.canvas.buffer : NULL;
2145 HAPI const char *const instance_id(const struct inst_info *inst)
2150 HAPI const char *const instance_content(const struct inst_info *inst)
2152 return inst->content;
2155 HAPI const char *const instance_category(const struct inst_info *inst)
2157 return inst->category;
2160 HAPI const char *const instance_cluster(const struct inst_info *inst)
2162 return inst->cluster;
2165 HAPI const char * const instance_title(const struct inst_info *inst)
2170 HAPI const double const instance_timestamp(const struct inst_info *inst)
2172 return inst->timestamp;
2175 HAPI const enum instance_state const instance_state(const struct inst_info *inst)
2180 HAPI int instance_destroyed(struct inst_info *inst)
2182 switch (inst->state) {
2184 case INST_REQUEST_TO_ACTIVATE:
2187 * No other clients know the existence of this instance,
2188 * only who added this knows it.
2189 * So send deleted event to only it.
2191 DbgPrint("Send deleted event - unicast - %p\n", inst->client);
2192 instance_unicast_deleted_event(inst, NULL);
2193 instance_state_reset(inst);
2194 instance_destroy(inst);
2196 case INST_REQUEST_TO_REACTIVATE:
2197 case INST_REQUEST_TO_DESTROY:
2198 case INST_ACTIVATED:
2199 DbgPrint("Send deleted event - multicast\n");
2200 instance_broadcast_deleted_event(inst);
2201 instance_state_reset(inst);
2202 instance_destroy(inst);
2203 case INST_DESTROYED:
2213 * Invoked when a slave is activated
2215 HAPI int instance_recover_state(struct inst_info *inst)
2219 if (inst->changing_state) {
2220 DbgPrint("Doesn't need to recover the state\n");
2224 switch (inst->state) {
2225 case INST_ACTIVATED:
2226 case INST_REQUEST_TO_REACTIVATE:
2227 case INST_REQUEST_TO_DESTROY:
2228 switch (inst->requested_state) {
2229 case INST_ACTIVATED:
2230 DbgPrint("Req. to RE-ACTIVATED (%s)\n", package_name(inst->info));
2231 instance_state_reset(inst);
2232 instance_reactivate(inst);
2235 case INST_DESTROYED:
2236 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2237 instance_state_reset(inst);
2238 instance_destroy(inst);
2245 case INST_REQUEST_TO_ACTIVATE:
2246 switch (inst->requested_state) {
2247 case INST_ACTIVATED:
2249 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2250 instance_state_reset(inst);
2251 if (instance_activate(inst) < 0) {
2252 DbgPrint("Failed to reactivate the instance\n");
2253 instance_broadcast_deleted_event(inst);
2254 instance_state_reset(inst);
2255 instance_destroy(inst);
2260 case INST_DESTROYED:
2261 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2262 instance_state_reset(inst);
2263 instance_destroy(inst);
2270 case INST_DESTROYED:
2279 * Invoked when a slave is deactivated
2281 HAPI int instance_need_slave(struct inst_info *inst)
2285 if (inst->client && client_is_faulted(inst->client)) {
2288 * In this case, the client is faulted(disconnected)
2289 * when the client is deactivated, its liveboxes should be removed too.
2290 * So if the current inst is created by the faulted client,
2291 * remove it and don't try to recover its states
2294 DbgPrint("CLIENT FAULT: Req. to DESTROYED (%s)\n", package_name(inst->info));
2295 switch (inst->state) {
2297 case INST_ACTIVATED:
2298 case INST_REQUEST_TO_REACTIVATE:
2299 case INST_REQUEST_TO_DESTROY:
2300 case INST_REQUEST_TO_ACTIVATE:
2301 instance_state_reset(inst);
2302 instance_destroy(inst);
2304 case INST_DESTROYED:
2311 switch (inst->state) {
2312 case INST_ACTIVATED:
2313 case INST_REQUEST_TO_REACTIVATE:
2314 case INST_REQUEST_TO_DESTROY:
2315 switch (inst->requested_state) {
2317 case INST_ACTIVATED:
2318 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2321 case INST_DESTROYED:
2322 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2323 instance_state_reset(inst);
2324 instance_destroy(inst);
2331 case INST_REQUEST_TO_ACTIVATE:
2332 switch (inst->requested_state) {
2334 case INST_ACTIVATED:
2335 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2338 case INST_DESTROYED:
2339 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2340 instance_state_reset(inst);
2341 instance_destroy(inst);
2347 case INST_DESTROYED:
2355 HAPI void instance_slave_set_pd_pos(struct inst_info *inst, double x, double y)
2361 HAPI void instance_slave_get_pd_pos(struct inst_info *inst, double *x, double *y)
2369 HAPI int instance_slave_open_pd(struct inst_info *inst, struct client_node *client)
2371 const char *pkgname;
2373 struct packet *packet;
2374 struct slave_node *slave;
2375 const struct pkg_info *info;
2379 client = inst->pd.owner;
2381 ErrPrint("Client is not valid\n");
2384 } else if (inst->pd.owner) {
2385 if (inst->pd.owner != client) {
2386 ErrPrint("Client is already owned\n");
2391 slave = package_slave(instance_package(inst));
2395 info = instance_package(inst);
2399 pkgname = package_name(info);
2400 id = instance_id(inst);
2402 if (!pkgname || !id)
2405 packet = packet_create_noack("pd_show", "ssiidd", pkgname, id, instance_pd_width(inst), instance_pd_height(inst), inst->pd.x, inst->pd.y);
2407 ErrPrint("Failed to create a packet\n");
2411 slave_freeze_ttl(slave);
2413 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2417 * If a client is disconnected, the slave has to close the PD
2418 * So the pd_buffer_close_cb/pd_script_close_cb will catch the disconnection event
2419 * then it will send the close request to the slave
2421 if (package_pd_type(info) == PD_TYPE_BUFFER) {
2423 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) < 0) {
2424 instance_unref(inst);
2426 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
2428 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) < 0) {
2429 instance_unref(inst);
2433 inst->pd.owner = client;
2437 HAPI int instance_slave_close_pd(struct inst_info *inst, struct client_node *client)
2439 const char *pkgname;
2441 struct packet *packet;
2442 struct slave_node *slave;
2443 struct pkg_info *info;
2446 if (inst->pd.owner != client) {
2447 ErrPrint("PD owner is not matched\n");
2451 slave = package_slave(instance_package(inst));
2455 info = instance_package(inst);
2459 pkgname = package_name(info);
2460 id = instance_id(inst);
2462 if (!pkgname || !id)
2465 packet = packet_create_noack("pd_hide", "ss", pkgname, id);
2467 ErrPrint("Failed to create a packet\n");
2471 slave_thaw_ttl(slave);
2473 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2474 release_resource_for_closing_pd(info, inst, client);
2475 inst->pd.owner = NULL;
2479 HAPI int instance_client_pd_created(struct inst_info *inst, int status)
2481 struct packet *packet;
2485 if (inst->pd.need_to_send_close_event) {
2486 DbgPrint("PD is already created\n");
2490 switch (package_pd_type(inst->info)) {
2491 case PD_TYPE_SCRIPT:
2492 buf_id = fb_id(script_handler_fb(inst->pd.canvas.script));
2494 case PD_TYPE_BUFFER:
2495 buf_id = buffer_handler_id(inst->pd.canvas.buffer);
2503 inst->pd.need_to_send_close_event = 1;
2505 packet = packet_create_noack("pd_created", "sssiii",
2506 package_name(inst->info), inst->id, buf_id,
2507 inst->pd.width, inst->pd.height, status);
2509 ErrPrint("Failed to create a packet\n");
2513 ret = CLIENT_SEND_EVENT(inst, packet);
2515 if (inst->pd.pended_update_cnt) {
2516 DbgPrint("Apply pended desc(%d) - %s\n", inst->pd.pended_update_cnt, inst->pd.pended_update_desc);
2517 instance_pd_updated_by_instance(inst, inst->pd.pended_update_desc);
2518 inst->pd.pended_update_cnt = 0;
2519 DbgFree(inst->pd.pended_update_desc);
2520 inst->pd.pended_update_desc = NULL;
2526 HAPI int instance_client_pd_destroyed(struct inst_info *inst, int status)
2528 if (!inst->pd.need_to_send_close_event) {
2529 DbgPrint("PD is not created\n");
2533 inst->pd.need_to_send_close_event = 0;
2535 return send_pd_destroyed_to_client(inst, status);
2538 HAPI int instance_add_client(struct inst_info *inst, struct client_node *client)
2540 if (inst->client == client) {
2541 ErrPrint("Owner cannot be the viewer\n");
2545 DbgPrint("%d is added to the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
2546 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst) < 0) {
2547 ErrPrint("Failed to add a deactivate callback\n");
2552 inst->client_list = eina_list_append(inst->client_list, client);
2556 HAPI int instance_del_client(struct inst_info *inst, struct client_node *client)
2558 if (inst->client == client) {
2559 ErrPrint("Owner is not in the viewer list\n");
2563 client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst);
2564 viewer_deactivated_cb(client, inst);
2568 HAPI int instance_has_client(struct inst_info *inst, struct client_node *client)
2570 return !!eina_list_data_find(inst->client_list, client);
2573 HAPI void *instance_client_list(struct inst_info *inst)
2575 return inst->client_list;
2578 HAPI void instance_init(void)
2580 if (!strcasecmp(PROVIDER_METHOD, "shm"))
2581 s_info.env_buf_type = BUFFER_TYPE_SHM;
2582 else if (!strcasecmp(PROVIDER_METHOD, "pixmap"))
2583 s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
2586 HAPI void instance_fini(void)