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;
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);
148 if (inst->sleep_at == 0.0f)
151 pending = ecore_timer_pending_get(inst->update_timer);
153 if (gettimeofday(&tv, NULL) < 0) {
154 ErrPrint("Failed to get timeofday: %s\n", strerror(errno));
157 compensate = 60.0f - ((double)(tv.tv_sec % 60) + ((double)tv.tv_usec / 1000000.0f));
158 sleep_time = (double)tv.tv_sec + ((double)tv.tv_usec / 1000000.0f) - inst->sleep_at;
160 ecore_timer_delay(inst->update_timer, compensate - pending);
161 DbgPrint("Compensate: %lf\n", compensate - pending);
163 if (sleep_time > pending) {
164 DbgPrint("Update time elapsed\n");
165 (void)update_timer_cb(inst);
168 inst->sleep_at = 0.0f;
171 static inline void timer_freeze(struct inst_info *inst)
174 ecore_timer_freeze(inst->update_timer);
176 if (ecore_timer_interval_get(inst->update_timer) <= 1.0f)
179 gettimeofday(&tv, NULL);
180 inst->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
184 static int viewer_deactivated_cb(struct client_node *client, void *data)
186 struct inst_info *inst = data;
188 DbgPrint("%d is deleted from the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
189 if (!eina_list_data_find(inst->client_list, client)) {
190 DbgPrint("Not found\n");
194 inst->client_list = eina_list_remove(inst->client_list, client);
195 if (!inst->client_list && !inst->client) {
196 DbgPrint("Has no clients\n");
197 instance_destroy(inst);
200 instance_unref(inst);
201 return -1; /*!< Remove this callback from the cb list */
204 static inline int pause_livebox(struct inst_info *inst)
206 struct packet *packet;
208 packet = packet_create_noack("lb_pause", "ss", package_name(inst->info), inst->id);
210 ErrPrint("Failed to create a new packet\n");
214 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
217 /*! \TODO Wake up the freeze'd timer */
218 static inline int resume_livebox(struct inst_info *inst)
220 struct packet *packet;
222 packet = packet_create_noack("lb_resume", "ss", package_name(inst->info), inst->id);
224 ErrPrint("Failed to create a new packet\n");
228 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
231 static inline int instance_recover_visible_state(struct inst_info *inst)
235 switch (inst->visible) {
238 instance_thaw_updator(inst);
242 case LB_HIDE_WITH_PAUSE:
243 ret = pause_livebox(inst);
245 instance_freeze_updator(inst);
252 DbgPrint("Visible state is recovered to %d\n", ret);
256 HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_node *client)
258 struct packet *packet;
259 enum lb_type lb_type;
260 enum pd_type pd_type;
265 client = inst->client;
270 lb_type = package_lb_type(inst->info);
271 pd_type = package_pd_type(inst->info);
273 if (lb_type == LB_TYPE_SCRIPT)
274 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
275 else if (lb_type == LB_TYPE_BUFFER)
276 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
280 if (pd_type == PD_TYPE_SCRIPT)
281 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
282 else if (pd_type == PD_TYPE_BUFFER)
283 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
287 packet = packet_create_noack("created", "dsssiiiissssidiiiiidsi",
289 package_name(inst->info), inst->id, inst->content,
290 inst->lb.width, inst->lb.height,
291 inst->pd.width, inst->pd.height,
292 inst->cluster, inst->category,
294 inst->lb.auto_launch,
296 package_size_list(inst->info),
298 package_pinup(inst->info),
300 inst->period, inst->title,
303 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
307 return client_rpc_async_request(client, packet);
310 static int update_client_list(struct client_node *client, void *data)
312 struct inst_info *inst = data;
313 if (!instance_has_client(inst, client)) {
314 instance_add_client(inst, client);
319 static int instance_broadcast_created_event(struct inst_info *inst)
321 struct packet *packet;
322 enum lb_type lb_type;
323 enum pd_type pd_type;
327 lb_type = package_lb_type(inst->info);
328 pd_type = package_pd_type(inst->info);
330 if (lb_type == LB_TYPE_SCRIPT)
331 lb_file = fb_id(script_handler_fb(inst->lb.canvas.script));
332 else if (lb_type == LB_TYPE_BUFFER)
333 lb_file = buffer_handler_id(inst->lb.canvas.buffer);
337 if (pd_type == PD_TYPE_SCRIPT)
338 pd_file = fb_id(script_handler_fb(inst->pd.canvas.script));
339 else if (pd_type == PD_TYPE_BUFFER)
340 pd_file = buffer_handler_id(inst->pd.canvas.buffer);
345 client_browse_list(inst->cluster, inst->category, update_client_list, inst);
347 packet = packet_create_noack("created", "dsssiiiissssidiiiiidsi",
349 package_name(inst->info), inst->id, inst->content,
350 inst->lb.width, inst->lb.height,
351 inst->pd.width, inst->pd.height,
352 inst->cluster, inst->category,
354 inst->lb.auto_launch,
356 package_size_list(inst->info),
358 package_pinup(inst->info),
360 inst->period, inst->title,
363 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
367 return CLIENT_SEND_EVENT(inst, packet);
370 HAPI int instance_unicast_deleted_event(struct inst_info *inst, struct client_node *client)
372 struct packet *packet;
375 client = inst->client;
380 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
382 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
386 return client_rpc_async_request(client, packet);
389 static int instance_broadcast_deleted_event(struct inst_info *inst)
391 struct packet *packet;
392 struct client_node *client;
397 packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
399 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
403 ret = CLIENT_SEND_EVENT(inst, packet);
405 EINA_LIST_FOREACH_SAFE(inst->client_list, l, n, client) {
406 instance_del_client(inst, client);
412 static int client_deactivated_cb(struct client_node *client, void *data)
414 struct inst_info *inst = data;
415 instance_destroy(inst);
419 static int send_pd_destroyed_to_client(struct inst_info *inst, int status)
421 struct packet *packet;
423 packet = packet_create_noack("pd_destroyed", "ssi", package_name(inst->info), inst->id, status);
425 ErrPrint("Failed to create a packet\n");
429 return CLIENT_SEND_EVENT(inst, packet);
432 static inline void destroy_instance(struct inst_info *inst)
434 struct pkg_info *pkg;
435 enum lb_type lb_type;
436 enum pd_type pd_type;
437 struct slave_node *slave;
441 lb_type = package_lb_type(pkg);
442 pd_type = package_pd_type(pkg);
443 slave = package_slave(inst->info);
445 DbgPrint("Instance is destroyed (%p), slave(%p)\n", inst, slave);
447 if (inst->pd.need_to_send_close_event)
448 send_pd_destroyed_to_client(inst, 0);
450 if (lb_type == LB_TYPE_SCRIPT) {
451 script_handler_unload(inst->lb.canvas.script, 0);
452 script_handler_destroy(inst->lb.canvas.script);
453 } else if (lb_type == LB_TYPE_BUFFER) {
454 buffer_handler_unload(inst->lb.canvas.buffer);
455 buffer_handler_destroy(inst->lb.canvas.buffer);
458 if (pd_type == PD_TYPE_SCRIPT) {
459 script_handler_unload(inst->pd.canvas.script, 1);
460 script_handler_destroy(inst->pd.canvas.script);
461 } else if (pd_type == PD_TYPE_BUFFER) {
462 buffer_handler_unload(inst->pd.canvas.buffer);
463 buffer_handler_destroy(inst->pd.canvas.buffer);
467 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
468 client_unref(inst->client);
471 if (inst->update_timer)
472 ecore_timer_del(inst->update_timer);
474 DbgFree(inst->category);
475 DbgFree(inst->cluster);
476 DbgFree(inst->content);
477 DbgFree(inst->title);
478 util_unlink(inst->id);
480 package_del_instance(inst->info, inst);
483 slave = slave_unload_instance(slave);
486 static Eina_Bool update_timer_cb(void *data)
488 struct inst_info *inst = (struct inst_info *)data;
490 DbgPrint("Update instance %s (%s) %s/%s\n", package_name(inst->info), inst->id, inst->cluster, inst->category);
491 slave_rpc_request_update(package_name(inst->info), inst->id, inst->cluster, inst->category);
492 return ECORE_CALLBACK_RENEW;
495 static inline int fork_package(struct inst_info *inst, const char *pkgname)
497 struct pkg_info *info;
500 info = package_find(pkgname);
502 ErrPrint("%s is not found\n", pkgname);
506 len = strlen(SCHEMA_FILE "%s%s_%d_%lf.png") + strlen(IMAGE_PATH) + strlen(package_name(info)) + 50;
507 inst->id = malloc(len);
509 ErrPrint("Heap: %s\n", strerror(errno));
513 snprintf(inst->id, len, SCHEMA_FILE "%s%s_%d_%lf.png", IMAGE_PATH, package_name(info), client_pid(inst->client), inst->timestamp);
514 inst->lb.auto_launch = package_auto_launch(info);
516 inst->pd.width = package_pd_width(info);
517 inst->pd.height = package_pd_height(info);
519 inst->timeout = package_timeout(info);
520 inst->period = package_period(info);
524 if (package_secured(info)) {
525 DbgPrint("Register the update timer for secured livebox [%s]\n", package_name(info));
526 inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst);
527 if (!inst->update_timer)
528 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
530 timer_freeze(inst); /* Freeze the update timer as default */
536 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)
538 struct inst_info *inst;
540 inst = calloc(1, sizeof(*inst));
542 ErrPrint("Heap: %s\n", strerror(errno));
546 inst->timestamp = timestamp;
547 inst->lb.width = width;
548 inst->lb.height = height;
550 inst->content = strdup(content);
551 if (!inst->content) {
552 ErrPrint("Heap: %s\n", strerror(errno));
557 inst->cluster = strdup(cluster);
558 if (!inst->cluster) {
559 ErrPrint("Heap: %s\n", strerror(errno));
560 DbgFree(inst->content);
565 inst->category = strdup(category);
566 if (!inst->category) {
567 ErrPrint("Heap: %s\n", strerror(errno));
568 DbgFree(inst->cluster);
569 DbgFree(inst->content);
574 inst->title = strdup(DEFAULT_TITLE); /*!< Use the DEFAULT Title "" */
576 ErrPrint("Heap: %s\n", strerror(errno));
577 DbgFree(inst->category);
578 DbgFree(inst->cluster);
579 DbgFree(inst->content);
585 inst->client = client_ref(client);
586 client_event_callback_add(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
589 if (fork_package(inst, pkgname) < 0) {
590 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
591 client_unref(inst->client);
592 DbgFree(inst->title);
593 DbgFree(inst->category);
594 DbgFree(inst->cluster);
595 DbgFree(inst->content);
600 inst->state = INST_INIT;
601 inst->requested_state = INST_INIT;
604 if (package_add_instance(inst->info, inst) < 0) {
605 instance_state_reset(inst);
606 instance_destroy(inst);
610 slave_load_instance(package_slave(inst->info));
612 if (instance_activate(inst) < 0) {
613 instance_state_reset(inst);
614 instance_destroy(inst);
621 HAPI struct inst_info *instance_ref(struct inst_info *inst)
630 HAPI struct inst_info *instance_unref(struct inst_info *inst)
635 if (inst->refcnt == 0) {
636 ErrPrint("Instance refcnt is not valid\n");
641 if (inst->refcnt == 0) {
642 destroy_instance(inst);
649 static void deactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
651 struct inst_info *inst = data;
652 struct pkg_info *info;
657 * In this callback, we cannot trust the "client" information.
658 * It could be cleared before reach to here.
662 DbgPrint("Consuming a request of a dead process\n");
665 * The instance_reload will care this.
666 * And it will be called from the slave activate callback.
668 inst->changing_state = 0;
669 instance_unref(inst);
673 if (packet_get(packet, "i", &ret) != 1) {
674 ErrPrint("Invalid argument\n");
675 inst->changing_state = 0;
676 instance_unref(inst);
680 if (inst->state == INST_DESTROYED) {
684 * Do nothing at here anymore.
686 inst->changing_state = 0;
687 instance_unref(inst);
695 * Successfully unloaded
697 switch (inst->requested_state) {
699 DbgPrint("REQ: ACTIVATED\n");
700 instance_state_reset(inst);
701 instance_reactivate(inst);
705 instance_broadcast_deleted_event(inst);
706 instance_state_reset(inst);
707 instance_destroy(inst);
708 DbgPrint("== %s\n", package_name(info));
710 /*!< Unable to reach here */
718 * Slave has no instance of this package.
723 * This instance's previous state is only can be the INST_ACTIVATED.
724 * So we should care the slave_unload_instance from here.
725 * And we should send notification to clients, about this is deleted.
729 * Slave has no instance of this.
730 * In this case, ignore the requested_state
731 * Because, this instance is already met a problem.
736 * Failed to unload this instance.
737 * This is not possible, slave will always return -ENOENT, -EINVAL, or 0.
738 * but care this exceptional case.
740 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(inst->info), ret);
742 instance_broadcast_deleted_event(inst);
743 instance_state_reset(inst);
744 instance_destroy(inst);
748 inst->changing_state = 0;
749 instance_unref(inst);
752 static void reactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
754 struct inst_info *inst = data;
755 struct pkg_info *info;
756 enum lb_type lb_type;
757 enum pd_type pd_type;
764 DbgPrint("Consuming a request of a dead process\n");
767 * instance_reload function will care this.
768 * and it will be called from the slave_activate callback
773 if (packet_get(packet, "issi", &ret, &content, &title, &is_pinned_up) != 4) {
774 ErrPrint("Invalid parameter\n");
778 if (strlen(content)) {
781 tmp = strdup(content);
783 ErrPrint("Heap: %s\n", strerror(errno));
787 DbgFree(inst->content);
790 DbgPrint("Update content info %s\n", tmp);
798 ErrPrint("Heap: %s\n", strerror(errno));
802 DbgFree(inst->title);
805 DbgPrint("Update title info %s\n", tmp);
808 if (inst->state == INST_DESTROYED) {
812 * Do nothing at here anymore.
818 case 0: /*!< normally created */
819 inst->state = INST_ACTIVATED;
820 switch (inst->requested_state) {
822 instance_destroy(inst);
825 inst->is_pinned_up = is_pinned_up;
827 lb_type = package_lb_type(info);
828 pd_type = package_pd_type(info);
832 * Optimization point.
833 * In case of the BUFFER type,
834 * the slave will request the buffer to render its contents.
835 * so the buffer will be automatcially recreated when it gots the
836 * buffer request packet.
837 * so load a buffer from here is not neccessary.
838 * I should to revise it and concrete the concept.
839 * Just leave it only for now.
842 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script) {
843 script_handler_load(inst->lb.canvas.script, 0);
844 } else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer) {
845 buffer_handler_load(inst->lb.canvas.buffer);
848 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script && inst->pd.is_opened_for_reactivate) {
851 instance_slave_get_pd_pos(inst, &x, &y);
855 * We should to send a request to open a PD to slave.
856 * if we didn't send it, the slave will not recognize the state of a PD.
857 * We have to keep the view of PD seamless even if the livebox is reactivated.
858 * To do that, send open request from here.
860 ret = instance_slave_open_pd(inst, NULL);
864 * In this case, master already loads the PD script.
865 * So just send the pd,show event to the slave again.
867 ret = instance_signal_emit(inst,
868 "pd,show", util_uri_to_path(instance_id(inst)),
869 0.0, 0.0, 0.0, 0.0, x, y, 0);
870 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer && inst->pd.is_opened_for_reactivate) {
873 buffer_handler_load(inst->pd.canvas.buffer);
874 instance_slave_get_pd_pos(inst, &x, &y);
878 * We should to send a request to open a PD to slave.
879 * if we didn't send it, the slave will not recognize the state of a PD.
880 * We have to keep the view of PD seamless even if the livebox is reactivated.
881 * To do that, send open request from here.
883 ret = instance_slave_open_pd(inst, NULL);
887 * In this case, just send the pd,show event for keeping the compatibility
889 ret = instance_signal_emit(inst,
890 "pd,show", util_uri_to_path(instance_id(inst)),
891 0.0, 0.0, 0.0, 0.0, x, y, 0);
896 * After create an instance again,
897 * Send resize request to the livebox.
898 * instance_resize(inst, inst->lb.width, inst->lb.height);
900 * renew request will resize the livebox while creating it again
905 * This function will check the visiblity of a livebox and
906 * make decision whether it thaw the update timer or not.
908 instance_recover_visible_state(inst);
915 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(info), ret);
916 instance_broadcast_deleted_event(inst);
917 instance_state_reset(inst);
918 instance_destroy(inst);
923 inst->changing_state = 0;
924 instance_unref(inst);
927 static void activate_cb(struct slave_node *slave, const struct packet *packet, void *data)
929 struct inst_info *inst = data;
939 DbgPrint("Consuming a request of a dead process\n");
942 * instance_reload will care this
943 * it will be called from the slave_activate callback
948 if (packet_get(packet, "iiidssi", &ret, &w, &h, &priority, &content, &title, &is_pinned_up) != 7) {
949 ErrPrint("Invalid parameter\n");
953 if (inst->state == INST_DESTROYED) {
957 * Do nothing at here anymore.
963 case 1: /*!< need to create */
964 if (util_free_space(IMAGE_PATH) > MINIMUM_SPACE) {
965 struct inst_info *new_inst;
966 new_inst = instance_create(inst->client, util_timestamp(), package_name(inst->info),
967 inst->content, inst->cluster, inst->category,
970 ErrPrint("Failed to create a new instance\n");
972 ErrPrint("Not enough space\n");
974 case 0: /*!< normally created */
977 * Anyway this instance is loaded to the slave,
978 * so just increase the loaded instance counter
979 * After that, do reset jobs.
981 inst->state = INST_ACTIVATED;
983 instance_set_lb_info(inst, w, h, priority, content, title);
985 switch (inst->requested_state) {
987 instance_unicast_deleted_event(inst, NULL);
988 instance_state_reset(inst);
989 instance_destroy(inst);
995 * LB should be created at the create time
997 inst->is_pinned_up = is_pinned_up;
998 if (package_lb_type(inst->info) == LB_TYPE_SCRIPT) {
999 if (inst->lb.width == 0 && inst->lb.height == 0)
1000 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1002 inst->lb.canvas.script = script_handler_create(inst,
1003 package_lb_path(inst->info),
1004 package_lb_group(inst->info),
1005 inst->lb.width, inst->lb.height);
1007 if (!inst->lb.canvas.script)
1008 ErrPrint("Failed to create LB\n");
1010 script_handler_load(inst->lb.canvas.script, 0);
1011 } else if (package_lb_type(inst->info) == LB_TYPE_BUFFER) {
1012 instance_create_lb_buffer(inst);
1015 if (package_pd_type(inst->info) == PD_TYPE_SCRIPT) {
1016 if (inst->pd.width == 0 && inst->pd.height == 0) {
1017 inst->pd.width = package_pd_width(inst->info);
1018 inst->pd.height = package_pd_height(inst->info);
1021 inst->pd.canvas.script = script_handler_create(inst,
1022 package_pd_path(inst->info),
1023 package_pd_group(inst->info),
1024 inst->pd.width, inst->pd.height);
1026 if (!inst->pd.canvas.script)
1027 ErrPrint("Failed to create PD\n");
1028 } else if (package_pd_type(inst->info) == PD_TYPE_BUFFER) {
1029 instance_create_pd_buffer(inst);
1032 instance_broadcast_created_event(inst);
1034 instance_thaw_updator(inst);
1039 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(inst->info), ret);
1040 instance_unicast_deleted_event(inst, NULL);
1041 instance_state_reset(inst);
1042 instance_destroy(inst);
1047 inst->changing_state = 0;
1048 instance_unref(inst);
1051 HAPI int instance_create_pd_buffer(struct inst_info *inst)
1053 if (inst->pd.width == 0 && inst->pd.height == 0) {
1054 inst->pd.width = package_pd_width(inst->info);
1055 inst->pd.height = package_pd_height(inst->info);
1058 if (!inst->pd.canvas.buffer) {
1059 inst->pd.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->pd.width, inst->pd.height, sizeof(int));
1060 if (!inst->pd.canvas.buffer)
1061 ErrPrint("Failed to create PD Buffer\n");
1064 return !!inst->pd.canvas.buffer;
1067 HAPI int instance_create_lb_buffer(struct inst_info *inst)
1069 if (inst->lb.width == 0 && inst->lb.height == 0)
1070 livebox_service_get_size(LB_SIZE_TYPE_1x1, &inst->lb.width, &inst->lb.height);
1072 if (!inst->lb.canvas.buffer) {
1075 * Slave doesn't call the acquire_buffer.
1076 * In this case, create the buffer from here.
1078 inst->lb.canvas.buffer = buffer_handler_create(inst, s_info.env_buf_type, inst->lb.width, inst->lb.height, sizeof(int));
1079 if (!inst->lb.canvas.buffer)
1080 ErrPrint("Failed to create LB\n");
1083 return !!inst->lb.canvas.buffer;
1086 HAPI int instance_destroy(struct inst_info *inst)
1088 struct packet *packet;
1091 ErrPrint("Invalid instance handle\n");
1095 switch (inst->state) {
1096 case INST_REQUEST_TO_ACTIVATE:
1097 case INST_REQUEST_TO_DESTROY:
1098 case INST_REQUEST_TO_REACTIVATE:
1099 inst->requested_state = INST_DESTROYED;
1102 inst->state = INST_DESTROYED;
1103 inst->requested_state = INST_DESTROYED;
1104 instance_unref(inst);
1106 case INST_DESTROYED:
1107 inst->requested_state = INST_DESTROYED;
1113 packet = packet_create("delete", "ss", package_name(inst->info), inst->id);
1115 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1119 inst->requested_state = INST_DESTROYED;
1120 inst->state = INST_REQUEST_TO_DESTROY;
1121 inst->changing_state = 1;
1122 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, deactivate_cb, instance_ref(inst), 0);
1125 /* Client Deactivated Callback */
1126 static int pd_buffer_close_cb(struct client_node *client, void *inst)
1130 ret = instance_slave_close_pd(inst, client);
1131 DbgPrint("Forcely close the PD ret: %d\n", ret);
1132 return -1; /* Delete this callback */
1135 /* Client Deactivated Callback */
1136 static int pd_script_close_cb(struct client_node *client, void *inst)
1140 ret = instance_slave_close_pd(inst, client);
1141 DbgPrint("Forcely close the PD ret: %d\n", ret);
1143 ret = script_handler_unload(instance_pd_script(inst), 1);
1144 return -1; /* Delete this callback */
1147 static inline void release_resource_for_closing_pd(struct pkg_info *info, struct inst_info *inst, struct client_node *client)
1150 client = inst->pd.owner;
1157 * Clean up the resources
1159 if (package_pd_type(info) == PD_TYPE_BUFFER) {
1160 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) == 0) {
1163 * Only if this function succeed to remove the pd_buffer_close_cb,
1164 * Decrease the reference count of this instance
1167 instance_unref(inst);
1168 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
1169 if (client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) == 0) {
1172 * Only if this function succeed to remove the script_close_cb,
1173 * Decrease the reference count of this instance
1176 instance_unref(inst);
1178 ErrPrint("Unknown PD type\n");
1183 HAPI int instance_state_reset(struct inst_info *inst)
1185 enum lb_type lb_type;
1186 enum pd_type pd_type;
1189 ErrPrint("Invalid instance handle\n");
1193 if (inst->state == INST_DESTROYED)
1196 lb_type = package_lb_type(inst->info);
1197 pd_type = package_pd_type(inst->info);
1199 if (lb_type == LB_TYPE_SCRIPT && inst->lb.canvas.script)
1200 script_handler_unload(inst->lb.canvas.script, 0);
1201 else if (lb_type == LB_TYPE_BUFFER && inst->lb.canvas.buffer)
1202 buffer_handler_unload(inst->lb.canvas.buffer);
1204 if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script) {
1205 inst->pd.is_opened_for_reactivate = script_handler_is_loaded(inst->pd.canvas.script);
1206 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1207 script_handler_unload(inst->pd.canvas.script, 1);
1208 } else if (pd_type == PD_TYPE_BUFFER && inst->pd.canvas.buffer) {
1209 inst->pd.is_opened_for_reactivate = buffer_handler_is_loaded(inst->pd.canvas.buffer);
1210 release_resource_for_closing_pd(instance_package(inst), inst, NULL);
1211 buffer_handler_unload(inst->pd.canvas.buffer);
1214 inst->state = INST_INIT;
1215 inst->requested_state = INST_INIT;
1219 HAPI int instance_reactivate(struct inst_info *inst)
1221 struct packet *packet;
1225 ErrPrint("Invalid instance handle\n");
1229 if (package_is_fault(inst->info)) {
1230 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1234 switch (inst->state) {
1235 case INST_REQUEST_TO_DESTROY:
1236 case INST_REQUEST_TO_ACTIVATE:
1237 case INST_REQUEST_TO_REACTIVATE:
1238 inst->requested_state = INST_ACTIVATED;
1240 case INST_DESTROYED:
1241 case INST_ACTIVATED:
1248 packet = packet_create("renew", "sssiidssiis",
1249 package_name(inst->info),
1253 !!package_lb_path(inst->info),
1257 inst->lb.width, inst->lb.height,
1258 package_abi(inst->info));
1260 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1264 ret = slave_activate(package_slave(inst->info));
1265 if (ret < 0 && ret != -EALREADY) {
1268 * If the master failed to launch the slave,
1269 * Do not send any requests to the slave.
1271 ErrPrint("Failed to launch the slave\n");
1272 packet_destroy(packet);
1276 inst->requested_state = INST_ACTIVATED;
1277 inst->state = INST_REQUEST_TO_REACTIVATE;
1278 inst->changing_state = 1;
1280 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, reactivate_cb, instance_ref(inst), 1);
1283 HAPI int instance_activate(struct inst_info *inst)
1285 struct packet *packet;
1289 ErrPrint("Invalid instance handle\n");
1293 if (package_is_fault(inst->info)) {
1294 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1298 switch (inst->state) {
1299 case INST_REQUEST_TO_REACTIVATE:
1300 case INST_REQUEST_TO_ACTIVATE:
1301 case INST_REQUEST_TO_DESTROY:
1302 inst->requested_state = INST_ACTIVATED;
1304 case INST_ACTIVATED:
1305 case INST_DESTROYED:
1312 packet = packet_create("new", "sssiidssisii",
1313 package_name(inst->info),
1317 !!package_lb_path(inst->info),
1322 package_abi(inst->info),
1326 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1330 ret = slave_activate(package_slave(inst->info));
1331 if (ret < 0 && ret != -EALREADY) {
1334 * If the master failed to launch the slave,
1335 * Do not send any requests to the slave.
1337 ErrPrint("Failed to launch the slave\n");
1338 packet_destroy(packet);
1342 inst->state = INST_REQUEST_TO_ACTIVATE;
1343 inst->requested_state = INST_ACTIVATED;
1344 inst->changing_state = 1;
1348 * Try to activate a slave if it is not activated
1350 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, activate_cb, instance_ref(inst), 1);
1353 HAPI void instance_lb_updated(const char *pkgname, const char *id)
1355 struct inst_info *inst;
1357 inst = package_find_instance_by_id(pkgname, id);
1361 instance_lb_updated_by_instance(inst);
1364 HAPI void instance_lb_updated_by_instance(struct inst_info *inst)
1366 struct packet *packet;
1368 enum lb_type lb_type;
1370 const char *content;
1372 if (inst->client && inst->visible != LB_SHOW) {
1373 if (inst->visible == LB_HIDE) {
1374 DbgPrint("Ignore update event %s(HIDE)\n", inst->id);
1377 DbgPrint("Livebox(%s) is PAUSED. But content is updated.\n", inst->id);
1380 lb_type = package_lb_type(inst->info);
1381 if (lb_type == LB_TYPE_SCRIPT)
1382 id = fb_id(script_handler_fb(inst->lb.canvas.script));
1383 else if (lb_type == LB_TYPE_BUFFER)
1384 id = buffer_handler_id(inst->lb.canvas.buffer);
1389 content = inst->content;
1394 title = inst->title;
1398 packet = packet_create_noack("lb_updated", "sssiidss",
1399 package_name(inst->info), inst->id, id,
1400 inst->lb.width, inst->lb.height, inst->lb.priority, content, title);
1402 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1406 (void)CLIENT_SEND_EVENT(inst, packet);
1409 HAPI void instance_pd_updated_by_instance(struct inst_info *inst, const char *descfile)
1411 struct packet *packet;
1414 if (inst->client && inst->visible != LB_SHOW) {
1415 DbgPrint("Livebox is hidden. ignore update event\n");
1419 if (!inst->pd.need_to_send_close_event) {
1420 DbgPrint("PD is not created yet. Ignore update event - %s\n", descfile);
1422 if (inst->pd.pended_update_desc) {
1423 DbgFree(inst->pd.pended_update_desc);
1424 inst->pd.pended_update_desc = NULL;
1428 inst->pd.pended_update_desc = strdup(descfile);
1429 if (!inst->pd.pended_update_desc)
1430 ErrPrint("Heap: %s\n", strerror(errno));
1433 inst->pd.pended_update_cnt++;
1438 descfile = inst->id;
1440 switch (package_pd_type(inst->info)) {
1441 case PD_TYPE_SCRIPT:
1442 id = fb_id(script_handler_fb(inst->pd.canvas.script));
1444 case PD_TYPE_BUFFER:
1445 id = buffer_handler_id(inst->pd.canvas.buffer);
1453 packet = packet_create_noack("pd_updated", "ssssii",
1454 package_name(inst->info), inst->id, descfile, id,
1455 inst->pd.width, inst->pd.height);
1457 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1461 (void)CLIENT_SEND_EVENT(inst, packet);
1464 HAPI void instance_pd_updated(const char *pkgname, const char *id, const char *descfile)
1466 struct inst_info *inst;
1468 inst = package_find_instance_by_id(pkgname, id);
1472 instance_pd_updated_by_instance(inst, descfile);
1475 HAPI void instance_set_lb_info(struct inst_info *inst, int w, int h, double priority, const char *content, const char *title)
1477 char *_content = NULL;
1478 char *_title = NULL;
1480 if (content && strlen(content)) {
1481 _content = strdup(content);
1483 ErrPrint("Heap: %s\n", strerror(errno));
1486 if (title && strlen(title)) {
1487 _title = strdup(title);
1489 ErrPrint("Heap: %s\n", strerror(errno));
1493 inst->lb.height = h;
1496 DbgFree(inst->content);
1497 inst->content= _content;
1501 DbgFree(inst->title);
1502 inst->title = _title;
1505 if (priority >= 0.0f && priority <= 1.0f)
1506 inst->lb.priority = priority;
1509 HAPI void instance_set_pd_info(struct inst_info *inst, int w, int h)
1512 inst->pd.height = h;
1515 static void pinup_cb(struct slave_node *slave, const struct packet *packet, void *data)
1517 struct set_pinup_cbdata *cbdata = data;
1518 const char *content;
1519 struct packet *result;
1525 * Send pinup failed event to client.
1531 if (packet_get(packet, "is", &ret, &content) != 2) {
1534 * Send pinup failed event to client
1543 new_content = strdup(content);
1545 ErrPrint("Heap: %s\n", strerror(errno));
1548 * send pinup failed event to client
1554 cbdata->inst->is_pinned_up = cbdata->pinup;
1555 DbgFree(cbdata->inst->content);
1557 cbdata->inst->content = new_content;
1563 * Send PINUP Result to client.
1564 * Client should wait this event.
1566 result = packet_create_noack("pinup", "iisss", ret, cbdata->inst->is_pinned_up,
1567 package_name(cbdata->inst->info), cbdata->inst->id, cbdata->inst->content);
1569 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
1571 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
1573 instance_unref(cbdata->inst);
1577 HAPI int instance_set_pinup(struct inst_info *inst, int pinup)
1579 struct set_pinup_cbdata *cbdata;
1580 struct packet *packet;
1583 ErrPrint("Invalid instance handle\n");
1587 if (package_is_fault(inst->info)) {
1588 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1592 if (!package_pinup(inst->info))
1595 if (pinup == inst->is_pinned_up)
1598 cbdata = malloc(sizeof(*cbdata));
1602 cbdata->inst = instance_ref(inst);
1603 cbdata->pinup = pinup;
1605 packet = packet_create("pinup", "ssi", package_name(inst->info), inst->id, pinup);
1607 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1608 instance_unref(cbdata->inst);
1613 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, pinup_cb, cbdata, 0);
1616 HAPI int instance_freeze_updator(struct inst_info *inst)
1618 if (!inst->update_timer)
1621 DbgPrint("Freeze the update timer (%s)\n", inst->id);
1626 HAPI int instance_thaw_updator(struct inst_info *inst)
1628 if (!inst->update_timer)
1631 if (client_is_all_paused() || setting_is_lcd_off()) {
1632 DbgPrint("Skip thaw (%s)\n", inst->id);
1636 if (inst->visible == LB_HIDE_WITH_PAUSE) {
1637 DbgPrint("Live box is invisible (%s)\n", inst->id);
1641 DbgPrint("Thaw the update timer (%s)\n", inst->id);
1646 HAPI enum livebox_visible_state instance_visible_state(struct inst_info *inst)
1648 return inst->visible;
1651 HAPI int instance_set_visible_state(struct inst_info *inst, enum livebox_visible_state state)
1653 if (inst->visible == state) {
1654 DbgPrint("Visibility has no changed\n");
1661 if (inst->visible == LB_HIDE_WITH_PAUSE) {
1662 if (resume_livebox(inst) == 0)
1663 inst->visible = state;
1665 instance_thaw_updator(inst);
1667 inst->visible = state;
1671 case LB_HIDE_WITH_PAUSE:
1672 if (pause_livebox(inst) == 0)
1673 inst->visible = LB_HIDE_WITH_PAUSE;
1675 instance_freeze_updator(inst);
1685 static void resize_cb(struct slave_node *slave, const struct packet *packet, void *data)
1687 struct resize_cbdata *cbdata = data;
1691 instance_unref(cbdata->inst);
1696 if (packet_get(packet, "i", &ret) != 1) {
1697 ErrPrint("Invalid parameter\n");
1698 instance_unref(cbdata->inst);
1704 cbdata->inst->lb.width = cbdata->w;
1705 cbdata->inst->lb.height = cbdata->h;
1707 ErrPrint("Failed to change the size of a livebox (%d)\n", ret);
1710 instance_unref(cbdata->inst);
1714 HAPI int instance_resize(struct inst_info *inst, int w, int h)
1716 struct resize_cbdata *cbdata;
1717 struct packet *packet;
1721 ErrPrint("Invalid instance handle\n");
1725 if (package_is_fault(inst->info)) {
1726 ErrPrint("Fault package: %s\n", package_name(inst->info));
1730 cbdata = malloc(sizeof(*cbdata));
1732 ErrPrint("Heap: %s\n", strerror(errno));
1736 cbdata->inst = instance_ref(inst);
1740 /* NOTE: param is resued from here */
1741 packet = packet_create("resize", "ssii", package_name(inst->info), inst->id, w, h);
1743 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1744 instance_unref(cbdata->inst);
1749 ret = slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, resize_cb, cbdata, 0);
1753 static void set_period_cb(struct slave_node *slave, const struct packet *packet, void *data)
1756 struct period_cbdata *cbdata = data;
1757 struct packet *result;
1764 if (packet_get(packet, "i", &ret) != 1) {
1770 cbdata->inst->period = cbdata->period;
1772 ErrPrint("Failed to set period %d\n", ret);
1775 result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->period, package_name(cbdata->inst->info), cbdata->inst->id);
1777 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
1779 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
1781 instance_unref(cbdata->inst);
1786 static Eina_Bool timer_updator_cb(void *data)
1788 struct period_cbdata *cbdata = data;
1789 struct inst_info *inst;
1791 struct packet *result;
1793 period = cbdata->period;
1794 inst = cbdata->inst;
1797 DbgPrint("Update period is changed to %lf from %lf\n", period, inst->period);
1799 inst->period = period;
1800 if (inst->update_timer) {
1801 if (inst->period == 0.0f) {
1802 ecore_timer_del(inst->update_timer);
1803 inst->update_timer = NULL;
1805 util_timer_interval_set(inst->update_timer, inst->period);
1807 } else if (inst->period > 0.0f) {
1808 inst->update_timer = util_timer_add(inst->period, update_timer_cb, inst);
1809 if (!inst->update_timer)
1810 ErrPrint("Failed to add an update timer for instance %s\n", inst->id);
1812 timer_freeze(inst); /* Freeze the update timer as default */
1815 result = packet_create_noack("period_changed", "idss", 0, inst->period, package_name(inst->info), inst->id);
1817 (void)CLIENT_SEND_EVENT(inst, result);
1819 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1821 instance_unref(inst);
1822 return ECORE_CALLBACK_CANCEL;
1825 HAPI int instance_set_period(struct inst_info *inst, double period)
1827 struct packet *packet;
1828 struct period_cbdata *cbdata;
1831 ErrPrint("Invalid instance handle\n");
1835 if (package_is_fault(inst->info)) {
1836 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1840 if (period < 0.0f) { /* Use the default period */
1841 period = package_period(inst->info);
1842 } else if (period > 0.0f && period < MINIMUM_PERIOD) {
1843 period = MINIMUM_PERIOD; /* defined at conf.h */
1846 cbdata = malloc(sizeof(*cbdata));
1848 ErrPrint("Heap: %s\n", strerror(errno));
1852 cbdata->period = period;
1853 cbdata->inst = instance_ref(inst);
1855 if (package_secured(inst->info)) {
1858 * Secured livebox doesn't need to send its update period to the slave.
1859 * Slave has no local timer for updating liveboxes
1861 * So update its timer at here.
1863 if (!ecore_timer_add(DELAY_TIME, timer_updator_cb, cbdata))
1864 timer_updator_cb(cbdata);
1868 packet = packet_create("set_period", "ssd", package_name(inst->info), inst->id, period);
1870 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1871 instance_unref(cbdata->inst);
1876 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, set_period_cb, cbdata, 0);
1879 HAPI int instance_clicked(struct inst_info *inst, const char *event, double timestamp, double x, double y)
1881 struct packet *packet;
1884 ErrPrint("Invalid instance handle\n");
1888 if (package_is_fault(inst->info)) {
1889 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1893 /* NOTE: param is resued from here */
1894 packet = packet_create_noack("clicked", "sssddd", package_name(inst->info), inst->id, event, timestamp, x, y);
1896 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1900 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
1903 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)
1905 const char *pkgname;
1907 struct slave_node *slave;
1908 struct packet *packet;
1911 pkgname = package_name(instance_package(inst));
1912 id = instance_id(inst);
1913 if (!pkgname || !id) {
1914 ErrPrint("Invalid instance\n");
1918 slave = package_slave(instance_package(inst));
1920 ErrPrint("Slave is not valid\n");
1924 packet = packet_create_noack("script", "ssssddddddi",
1930 ErrPrint("Failed to create param\n");
1934 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
1938 HAPI int instance_text_signal_emit(struct inst_info *inst, const char *emission, const char *source, double sx, double sy, double ex, double ey)
1940 struct packet *packet;
1943 ErrPrint("Invalid instance handle\n");
1947 if (package_is_fault(inst->info)) {
1948 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1952 packet = packet_create_noack("text_signal", "ssssdddd", package_name(inst->info), inst->id, emission, source, sx, sy, ex, ey);
1954 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1958 return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
1961 static void change_group_cb(struct slave_node *slave, const struct packet *packet, void *data)
1963 struct change_group_cbdata *cbdata = data;
1964 struct packet *result;
1968 DbgFree(cbdata->cluster);
1969 DbgFree(cbdata->category);
1974 if (packet_get(packet, "i", &ret) != 1) {
1975 ErrPrint("Invalid packet\n");
1976 DbgFree(cbdata->cluster);
1977 DbgFree(cbdata->category);
1983 DbgFree(cbdata->inst->cluster);
1984 cbdata->inst->cluster = cbdata->cluster;
1986 DbgFree(cbdata->inst->category);
1987 cbdata->inst->category = cbdata->category;
1989 DbgFree(cbdata->cluster);
1990 DbgFree(cbdata->category);
1994 result = packet_create_noack("group_changed", "ssiss",
1995 package_name(cbdata->inst->info), cbdata->inst->id, ret,
1996 cbdata->inst->cluster, cbdata->inst->category);
1998 ErrPrint("Failed to build a packet %s\n", package_name(cbdata->inst->info));
2000 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2002 instance_unref(cbdata->inst);
2006 HAPI int instance_change_group(struct inst_info *inst, const char *cluster, const char *category)
2008 struct packet *packet;
2009 struct change_group_cbdata *cbdata;
2012 ErrPrint("Invalid instance handle\n");
2016 if (package_is_fault(inst->info)) {
2017 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2021 cbdata = malloc(sizeof(*cbdata));
2023 ErrPrint("Heap: %s\n", strerror(errno));
2027 cbdata->cluster = strdup(cluster);
2028 if (!cbdata->cluster) {
2029 ErrPrint("Heap: %s\n", strerror(errno));
2034 cbdata->category = strdup(category);
2035 if (!cbdata->category) {
2036 ErrPrint("Heap: %s\n", strerror(errno));
2037 DbgFree(cbdata->cluster);
2042 cbdata->inst = instance_ref(inst);
2044 packet = packet_create("change_group","ssss", package_name(inst->info), inst->id, cluster, category);
2046 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
2047 instance_unref(cbdata->inst);
2048 DbgFree(cbdata->category);
2049 DbgFree(cbdata->cluster);
2054 return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, change_group_cb, cbdata, 0);
2057 HAPI const int const instance_auto_launch(const struct inst_info *inst)
2059 return inst->lb.auto_launch;
2062 HAPI const int const instance_priority(const struct inst_info *inst)
2064 return inst->lb.priority;
2067 HAPI const struct client_node *const instance_client(const struct inst_info *inst)
2069 return inst->client;
2072 HAPI const double const instance_period(const struct inst_info *inst)
2074 return inst->period;
2077 HAPI const int const instance_lb_width(const struct inst_info *inst)
2079 return inst->lb.width;
2082 HAPI const int const instance_lb_height(const struct inst_info *inst)
2084 return inst->lb.height;
2087 HAPI const int const instance_pd_width(const struct inst_info *inst)
2089 return inst->pd.width;
2092 HAPI const int const instance_pd_height(const struct inst_info *inst)
2094 return inst->pd.height;
2097 HAPI struct pkg_info *const instance_package(const struct inst_info *inst)
2102 HAPI struct script_info *const instance_lb_script(const struct inst_info *inst)
2104 return (package_lb_type(inst->info) == LB_TYPE_SCRIPT) ? inst->lb.canvas.script : NULL;
2107 HAPI struct script_info *const instance_pd_script(const struct inst_info *inst)
2109 return (package_pd_type(inst->info) == PD_TYPE_SCRIPT) ? inst->pd.canvas.script : NULL;
2112 HAPI struct buffer_info *const instance_lb_buffer(const struct inst_info *inst)
2114 return (package_lb_type(inst->info) == LB_TYPE_BUFFER) ? inst->lb.canvas.buffer : NULL;
2117 HAPI struct buffer_info *const instance_pd_buffer(const struct inst_info *inst)
2119 return (package_pd_type(inst->info) == PD_TYPE_BUFFER) ? inst->pd.canvas.buffer : NULL;
2122 HAPI const char *const instance_id(const struct inst_info *inst)
2127 HAPI const char *const instance_content(const struct inst_info *inst)
2129 return inst->content;
2132 HAPI const char *const instance_category(const struct inst_info *inst)
2134 return inst->category;
2137 HAPI const char *const instance_cluster(const struct inst_info *inst)
2139 return inst->cluster;
2142 HAPI const char * const instance_title(const struct inst_info *inst)
2147 HAPI const double const instance_timestamp(const struct inst_info *inst)
2149 return inst->timestamp;
2152 HAPI const enum instance_state const instance_state(const struct inst_info *inst)
2157 HAPI int instance_destroyed(struct inst_info *inst)
2159 switch (inst->state) {
2161 case INST_REQUEST_TO_ACTIVATE:
2164 * No other clients know the existence of this instance,
2165 * only who added this knows it.
2166 * So send deleted event to only it.
2168 DbgPrint("Send deleted event - unicast - %p\n", inst->client);
2169 instance_unicast_deleted_event(inst, NULL);
2170 instance_state_reset(inst);
2171 instance_destroy(inst);
2173 case INST_REQUEST_TO_REACTIVATE:
2174 case INST_REQUEST_TO_DESTROY:
2175 case INST_ACTIVATED:
2176 DbgPrint("Send deleted event - multicast\n");
2177 instance_broadcast_deleted_event(inst);
2178 instance_state_reset(inst);
2179 instance_destroy(inst);
2180 case INST_DESTROYED:
2190 * Invoked when a slave is activated
2192 HAPI int instance_recover_state(struct inst_info *inst)
2194 struct pkg_info *info;
2197 if (inst->changing_state) {
2198 DbgPrint("Doesn't need to recover the state\n");
2202 switch (inst->state) {
2203 case INST_ACTIVATED:
2204 case INST_REQUEST_TO_REACTIVATE:
2205 case INST_REQUEST_TO_DESTROY:
2206 switch (inst->requested_state) {
2207 case INST_ACTIVATED:
2208 DbgPrint("Req. to RE-ACTIVATED (%s)\n", package_name(inst->info));
2209 instance_state_reset(inst);
2210 instance_reactivate(inst);
2213 case INST_DESTROYED:
2214 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2216 instance_state_reset(inst);
2217 instance_destroy(inst);
2224 case INST_REQUEST_TO_ACTIVATE:
2225 switch (inst->requested_state) {
2226 case INST_ACTIVATED:
2228 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2229 instance_state_reset(inst);
2230 if (instance_activate(inst) < 0) {
2231 DbgPrint("Failed to reactivate the instance\n");
2232 instance_broadcast_deleted_event(inst);
2233 instance_state_reset(inst);
2234 instance_destroy(inst);
2239 case INST_DESTROYED:
2240 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2241 instance_state_reset(inst);
2242 instance_destroy(inst);
2249 case INST_DESTROYED:
2258 * Invoked when a slave is deactivated
2260 HAPI int instance_need_slave(struct inst_info *inst)
2263 struct pkg_info *info;
2265 if (inst->client && client_is_faulted(inst->client)) {
2270 * In this case, the client is faulted(disconnected)
2271 * when the client is deactivated, its liveboxes should be removed too.
2272 * So if the current inst is created by the faulted client,
2273 * remove it and don't try to recover its states
2276 DbgPrint("CLIENT FAULT: Req. to DESTROYED (%s)\n", package_name(info));
2277 switch (inst->state) {
2279 case INST_ACTIVATED:
2280 case INST_REQUEST_TO_REACTIVATE:
2281 case INST_REQUEST_TO_DESTROY:
2282 case INST_REQUEST_TO_ACTIVATE:
2283 instance_state_reset(inst);
2284 instance_destroy(inst);
2286 case INST_DESTROYED:
2293 switch (inst->state) {
2294 case INST_ACTIVATED:
2295 case INST_REQUEST_TO_REACTIVATE:
2296 case INST_REQUEST_TO_DESTROY:
2297 switch (inst->requested_state) {
2299 case INST_ACTIVATED:
2300 DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2303 case INST_DESTROYED:
2304 DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2306 instance_state_reset(inst);
2307 instance_destroy(inst);
2314 case INST_REQUEST_TO_ACTIVATE:
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);
2330 case INST_DESTROYED:
2338 HAPI void instance_slave_set_pd_pos(struct inst_info *inst, double x, double y)
2344 HAPI void instance_slave_get_pd_pos(struct inst_info *inst, double *x, double *y)
2352 HAPI int instance_slave_open_pd(struct inst_info *inst, struct client_node *client)
2354 const char *pkgname;
2356 struct packet *packet;
2357 struct slave_node *slave;
2358 const struct pkg_info *info;
2362 client = inst->pd.owner;
2364 ErrPrint("Client is not valid\n");
2367 } else if (inst->pd.owner) {
2368 if (inst->pd.owner != client) {
2369 ErrPrint("Client is already owned\n");
2374 slave = package_slave(instance_package(inst));
2378 info = instance_package(inst);
2382 pkgname = package_name(info);
2383 id = instance_id(inst);
2385 if (!pkgname || !id)
2388 packet = packet_create_noack("pd_show", "ssiidd", pkgname, id, instance_pd_width(inst), instance_pd_height(inst), inst->pd.x, inst->pd.y);
2390 ErrPrint("Failed to create a packet\n");
2394 slave_freeze_ttl(slave);
2396 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2400 * If a client is disconnected, the slave has to close the PD
2401 * So the pd_buffer_close_cb/pd_script_close_cb will catch the disconnection event
2402 * then it will send the close request to the slave
2404 if (package_pd_type(info) == PD_TYPE_BUFFER) {
2406 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) < 0) {
2407 instance_unref(inst);
2409 } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
2411 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) < 0) {
2412 instance_unref(inst);
2416 inst->pd.owner = client;
2420 HAPI int instance_slave_close_pd(struct inst_info *inst, struct client_node *client)
2422 const char *pkgname;
2424 struct packet *packet;
2425 struct slave_node *slave;
2426 struct pkg_info *info;
2429 if (inst->pd.owner != client) {
2430 ErrPrint("PD owner is not matched\n");
2434 slave = package_slave(instance_package(inst));
2438 info = instance_package(inst);
2442 pkgname = package_name(info);
2443 id = instance_id(inst);
2445 if (!pkgname || !id)
2448 packet = packet_create_noack("pd_hide", "ss", pkgname, id);
2450 ErrPrint("Failed to create a packet\n");
2454 slave_thaw_ttl(slave);
2456 ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2457 release_resource_for_closing_pd(info, inst, client);
2458 inst->pd.owner = NULL;
2462 HAPI int instance_client_pd_created(struct inst_info *inst, int status)
2464 struct packet *packet;
2468 if (inst->pd.need_to_send_close_event) {
2469 DbgPrint("PD is already created\n");
2473 switch (package_pd_type(inst->info)) {
2474 case PD_TYPE_SCRIPT:
2475 buf_id = fb_id(script_handler_fb(inst->pd.canvas.script));
2477 case PD_TYPE_BUFFER:
2478 buf_id = buffer_handler_id(inst->pd.canvas.buffer);
2486 inst->pd.need_to_send_close_event = 1;
2488 packet = packet_create_noack("pd_created", "sssiii",
2489 package_name(inst->info), inst->id, buf_id,
2490 inst->pd.width, inst->pd.height, status);
2492 ErrPrint("Failed to create a packet\n");
2496 ret = CLIENT_SEND_EVENT(inst, packet);
2498 if (inst->pd.pended_update_cnt) {
2499 DbgPrint("Apply pended desc(%d) - %s\n", inst->pd.pended_update_cnt, inst->pd.pended_update_desc);
2500 instance_pd_updated_by_instance(inst, inst->pd.pended_update_desc);
2501 inst->pd.pended_update_cnt = 0;
2502 DbgFree(inst->pd.pended_update_desc);
2503 inst->pd.pended_update_desc = NULL;
2509 HAPI int instance_client_pd_destroyed(struct inst_info *inst, int status)
2511 if (!inst->pd.need_to_send_close_event) {
2512 DbgPrint("PD is not created\n");
2516 inst->pd.need_to_send_close_event = 0;
2518 return send_pd_destroyed_to_client(inst, status);
2521 HAPI int instance_add_client(struct inst_info *inst, struct client_node *client)
2523 if (inst->client == client) {
2524 ErrPrint("Owner cannot be the viewer\n");
2528 DbgPrint("%d is added to the list of viewer of %s(%s)\n", client_pid(client), package_name(instance_package(inst)), instance_id(inst));
2529 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst) < 0) {
2530 ErrPrint("Failed to add a deactivate callback\n");
2535 inst->client_list = eina_list_append(inst->client_list, client);
2539 HAPI int instance_del_client(struct inst_info *inst, struct client_node *client)
2541 if (inst->client == client) {
2542 ErrPrint("Owner is not in the viewer list\n");
2546 client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst);
2547 viewer_deactivated_cb(client, inst);
2551 HAPI int instance_has_client(struct inst_info *inst, struct client_node *client)
2553 return !!eina_list_data_find(inst->client_list, client);
2556 HAPI void *instance_client_list(struct inst_info *inst)
2558 return inst->client_list;
2561 HAPI void instance_init(void)
2563 if (!strcasecmp(PROVIDER_METHOD, "shm"))
2564 s_info.env_buf_type = BUFFER_TYPE_SHM;
2565 else if (!strcasecmp(PROVIDER_METHOD, "pixmap"))
2566 s_info.env_buf_type = BUFFER_TYPE_PIXMAP;
2569 HAPI void instance_fini(void)