Remove code of the deprecated feature
[platform/framework/web/data-provider-master.git] / src / instance.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
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
7  *
8  * http://www.tizenopensource.org/license
9  *
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.
15  */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <errno.h>
20
21 #include <dlog.h>
22 #include <Ecore_Evas.h>
23 #include <Eina.h>
24 #include <gio/gio.h>
25 #include <Ecore.h>
26
27 #include <packet.h>
28 #include <com-core_packet.h>
29 #include <livebox-service.h>
30
31 #include "conf.h"
32 #include "util.h"
33 #include "debug.h"
34 #include "slave_life.h"
35 #include "slave_rpc.h"
36 #include "client_life.h"
37 #include "instance.h"
38 #include "client_rpc.h"
39 #include "package.h"
40 #include "script_handler.h"
41 #include "buffer_handler.h"
42 #include "fb.h"
43 #include "setting.h"
44
45 int errno;
46
47 static struct info {
48         enum buffer_type env_buf_type;
49 } s_info = {
50         .env_buf_type = BUFFER_TYPE_FILE,
51 };
52
53 struct set_pinup_cbdata {
54         struct inst_info *inst;
55         int pinup;
56 };
57
58 struct resize_cbdata {
59         struct inst_info *inst;
60         int w;
61         int h;
62 };
63
64 struct change_group_cbdata {
65         struct inst_info *inst;
66         char *cluster;
67         char *category;
68 };
69
70 struct period_cbdata {
71         struct inst_info *inst;
72         double period;
73 };
74
75 struct inst_info {
76         struct pkg_info *info;
77
78         enum instance_state state; /*!< Represents current state */
79         enum instance_state requested_state; /*!< Only ACTIVATED | DESTROYED is acceptable */
80         int changing_state;
81
82         char *id;
83         double timestamp;
84
85         char *content;
86         char *cluster;
87         char *category;
88         char *title;
89         int is_pinned_up;
90         double sleep_at;
91
92         enum livebox_visible_state visible;
93
94         struct {
95                 int width;
96                 int height;
97                 double priority;
98
99                 union {
100                         struct script_info *script;
101                         struct buffer_info *buffer;
102                 } canvas;
103
104                 int auto_launch;
105         } lb;
106
107         struct {
108                 int width;
109                 int height;
110                 double x;
111                 double y;
112
113                 union {
114                         struct script_info *script;
115                         struct buffer_info *buffer;
116                 } canvas;
117
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;
123         } pd;
124
125         int timeout;
126         double period;
127
128         struct client_node *client; /*!< Owner - creator */
129         Eina_List *client_list; /*!< Viewer list */
130         int refcnt;
131
132         Ecore_Timer *update_timer; /*!< Only used for secured livebox */
133 };
134
135 #define CLIENT_SEND_EVENT(instance, packet)     ((instance)->client ? client_rpc_async_request((instance)->client, (packet)) : client_broadcast((instance), (packet)))
136
137 static Eina_Bool update_timer_cb(void *data);
138
139 static inline void timer_thaw(struct inst_info *inst)
140 {
141         struct timeval tv;
142         double pending;
143         double compensate;
144         double sleep_time;
145
146         ecore_timer_thaw(inst->update_timer);
147
148         if (inst->sleep_at == 0.0f)
149                 return;
150
151         pending = ecore_timer_pending_get(inst->update_timer);
152
153         if (gettimeofday(&tv, NULL) < 0) {
154                 ErrPrint("Failed to get timeofday: %s\n", strerror(errno));
155                 return;
156         }
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;
159
160         ecore_timer_delay(inst->update_timer, compensate - pending);
161         DbgPrint("Compensate: %lf\n", compensate - pending);
162
163         if (sleep_time > pending) {
164                 DbgPrint("Update time elapsed\n");
165                 (void)update_timer_cb(inst);
166         }
167
168         inst->sleep_at = 0.0f;
169 }
170
171 static inline void timer_freeze(struct inst_info *inst)
172 {
173         struct timeval tv;
174         ecore_timer_freeze(inst->update_timer);
175
176         if (ecore_timer_interval_get(inst->update_timer) <= 1.0f)
177                 return;
178
179         gettimeofday(&tv, NULL);
180         inst->sleep_at = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
181 }
182
183
184 static int viewer_deactivated_cb(struct client_node *client, void *data)
185 {
186         struct inst_info *inst = data;
187
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");
191                 return -ENOENT;
192         }
193
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);
198         }
199
200         instance_unref(inst);
201         return -1; /*!< Remove this callback from the cb list */
202 }
203
204 static inline int pause_livebox(struct inst_info *inst)
205 {
206         struct packet *packet;
207
208         packet = packet_create_noack("lb_pause", "ss", package_name(inst->info), inst->id);
209         if (!packet) {
210                 ErrPrint("Failed to create a new packet\n");
211                 return -EFAULT;
212         }
213
214         return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
215 }
216
217 /*! \TODO Wake up the freeze'd timer */
218 static inline int resume_livebox(struct inst_info *inst)
219 {
220         struct packet *packet;
221
222         packet = packet_create_noack("lb_resume", "ss", package_name(inst->info), inst->id);
223         if (!packet) {
224                 ErrPrint("Failed to create a new packet\n");
225                 return -EFAULT;
226         }
227
228         return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
229 }
230
231 static inline int instance_recover_visible_state(struct inst_info *inst)
232 {
233         int ret;
234
235         switch (inst->visible) {
236         case LB_SHOW:
237         case LB_HIDE:
238                 instance_thaw_updator(inst);
239
240                 ret = 0;
241                 break;
242         case LB_HIDE_WITH_PAUSE:
243                 ret = pause_livebox(inst);
244
245                 instance_freeze_updator(inst);
246                 break;
247         default:
248                 ret = -EINVAL;
249                 break;
250         }
251
252         DbgPrint("Visible state is recovered to %d\n", ret);
253         return ret;
254 }
255
256 HAPI int instance_unicast_created_event(struct inst_info *inst, struct client_node *client)
257 {
258         struct packet *packet;
259         enum lb_type lb_type;
260         enum pd_type pd_type;
261         const char *lb_file;
262         const char *pd_file;
263
264         if (!client) {
265                 client = inst->client;
266                 if (!client)
267                         return 0;
268         }
269
270         lb_type = package_lb_type(inst->info);
271         pd_type = package_pd_type(inst->info);
272
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);
277         else
278                 lb_file = "";
279
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);
284         else
285                 pd_file = "";
286
287         packet = packet_create_noack("created", "dsssiiiissssidiiiiidsi",
288                         inst->timestamp,
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,
293                         lb_file, pd_file,
294                         inst->lb.auto_launch,
295                         inst->lb.priority,
296                         package_size_list(inst->info),
297                         !!inst->client,
298                         package_pinup(inst->info),
299                         lb_type, pd_type,
300                         inst->period, inst->title,
301                         inst->is_pinned_up);
302         if (!packet) {
303                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
304                 return -EFAULT;
305         }
306
307         return client_rpc_async_request(client, packet);
308 }
309
310 static int update_client_list(struct client_node *client, void *data)
311 {
312         struct inst_info *inst = data;
313         if (!instance_has_client(inst, client)) {
314                 instance_add_client(inst, client);
315         }
316         return 0;
317 }
318
319 static int instance_broadcast_created_event(struct inst_info *inst)
320 {
321         struct packet *packet;
322         enum lb_type lb_type;
323         enum pd_type pd_type;
324         const char *lb_file;
325         const char *pd_file;
326
327         lb_type = package_lb_type(inst->info);
328         pd_type = package_pd_type(inst->info);
329
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);
334         else
335                 lb_file = "";
336
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);
341         else
342                 pd_file = "";
343
344         if (!inst->client)
345                 client_browse_list(inst->cluster, inst->category, update_client_list, inst);
346
347         packet = packet_create_noack("created", "dsssiiiissssidiiiiidsi", 
348                         inst->timestamp,
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,
353                         lb_file, pd_file,
354                         inst->lb.auto_launch,
355                         inst->lb.priority,
356                         package_size_list(inst->info),
357                         !!inst->client,
358                         package_pinup(inst->info),
359                         lb_type, pd_type,
360                         inst->period, inst->title,
361                         inst->is_pinned_up);
362         if (!packet) {
363                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
364                 return -EFAULT;
365         }
366
367         return CLIENT_SEND_EVENT(inst, packet);
368 }
369
370 HAPI int instance_unicast_deleted_event(struct inst_info *inst, struct client_node *client)
371 {
372         struct packet *packet;
373
374         if (!client) {
375                 client = inst->client;
376                 if (!client)
377                         return -EINVAL;
378         }
379
380         packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
381         if (!packet) {
382                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
383                 return -EFAULT;
384         }
385                 
386         return client_rpc_async_request(client, packet);
387 }
388
389 static int instance_broadcast_deleted_event(struct inst_info *inst)
390 {
391         struct packet *packet;
392         struct client_node *client;
393         Eina_List *l;
394         Eina_List *n;
395         int ret;
396
397         packet = packet_create_noack("deleted", "ssd", package_name(inst->info), inst->id, inst->timestamp);
398         if (!packet) {
399                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
400                 return -EFAULT;
401         }
402                 
403         ret = CLIENT_SEND_EVENT(inst, packet);
404
405         EINA_LIST_FOREACH_SAFE(inst->client_list, l, n, client) {
406                 instance_del_client(inst, client);
407         }
408
409         return ret;
410 }
411
412 static int client_deactivated_cb(struct client_node *client, void *data)
413 {
414         struct inst_info *inst = data;
415         instance_destroy(inst);
416         return 0;
417 }
418
419 static int send_pd_destroyed_to_client(struct inst_info *inst, int status)
420 {
421         struct packet *packet;
422
423         packet = packet_create_noack("pd_destroyed", "ssi", package_name(inst->info), inst->id, status);
424         if (!packet) {
425                 ErrPrint("Failed to create a packet\n");
426                 return -EFAULT;
427         }
428
429         return CLIENT_SEND_EVENT(inst, packet);
430 }
431
432 static inline void destroy_instance(struct inst_info *inst)
433 {
434         struct pkg_info *pkg;
435         enum lb_type lb_type;
436         enum pd_type pd_type;
437         struct slave_node *slave;
438
439         pkg = inst->info;
440
441         lb_type = package_lb_type(pkg);
442         pd_type = package_pd_type(pkg);
443         slave = package_slave(inst->info);
444
445         DbgPrint("Instance is destroyed (%p), slave(%p)\n", inst, slave);
446
447         if (inst->pd.need_to_send_close_event)
448                 send_pd_destroyed_to_client(inst, 0);
449
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);
456         }
457
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);
464         }
465
466         if (inst->client) {
467                 client_event_callback_del(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
468                 client_unref(inst->client);
469         }
470
471         if (inst->update_timer)
472                 ecore_timer_del(inst->update_timer);
473
474         DbgFree(inst->category);
475         DbgFree(inst->cluster);
476         DbgFree(inst->content);
477         DbgFree(inst->title);
478         util_unlink(inst->id);
479         DbgFree(inst->id);
480         package_del_instance(inst->info, inst);
481         DbgFree(inst);
482
483         slave = slave_unload_instance(slave);
484 }
485
486 static Eina_Bool update_timer_cb(void *data)
487 {
488         struct inst_info *inst = (struct inst_info *)data;
489
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;
493 }
494
495 static inline int fork_package(struct inst_info *inst, const char *pkgname)
496 {
497         struct pkg_info *info;
498         int len;
499
500         info = package_find(pkgname);
501         if (!info) {
502                 ErrPrint("%s is not found\n", pkgname);
503                 return -ENOENT;
504         }
505
506         len = strlen(SCHEMA_FILE "%s%s_%d_%lf.png") + strlen(IMAGE_PATH) + strlen(package_name(info)) + 50;
507         inst->id = malloc(len);
508         if (!inst->id) {
509                 ErrPrint("Heap: %s\n", strerror(errno));
510                 return -ENOMEM;
511         }
512
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);
515
516         inst->pd.width = package_pd_width(info);
517         inst->pd.height = package_pd_height(info);
518
519         inst->timeout = package_timeout(info);
520         inst->period = package_period(info);
521
522         inst->info = info;
523
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);
529                 else
530                         timer_freeze(inst); /* Freeze the update timer as default */
531         }
532
533         return 0;
534 }
535
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)
537 {
538         struct inst_info *inst;
539
540         inst = calloc(1, sizeof(*inst));
541         if (!inst) {
542                 ErrPrint("Heap: %s\n", strerror(errno));
543                 return NULL;
544         }
545
546         inst->timestamp = timestamp;
547         inst->lb.width = width;
548         inst->lb.height = height;
549
550         inst->content = strdup(content);
551         if (!inst->content) {
552                 ErrPrint("Heap: %s\n", strerror(errno));
553                 DbgFree(inst);
554                 return NULL;
555         }
556
557         inst->cluster = strdup(cluster);
558         if (!inst->cluster) {
559                 ErrPrint("Heap: %s\n", strerror(errno));
560                 DbgFree(inst->content);
561                 DbgFree(inst);
562                 return NULL;
563         }
564
565         inst->category = strdup(category);
566         if (!inst->category) {
567                 ErrPrint("Heap: %s\n", strerror(errno));
568                 DbgFree(inst->cluster);
569                 DbgFree(inst->content);
570                 DbgFree(inst);
571                 return NULL;
572         }
573
574         inst->title = strdup(DEFAULT_TITLE); /*!< Use the DEFAULT Title "" */
575         if (!inst->title) {
576                 ErrPrint("Heap: %s\n", strerror(errno));
577                 DbgFree(inst->category);
578                 DbgFree(inst->cluster);
579                 DbgFree(inst->content);
580                 DbgFree(inst);
581                 return NULL;
582         }
583
584         if (client) {
585                 inst->client = client_ref(client);
586                 client_event_callback_add(inst->client, CLIENT_EVENT_DEACTIVATE, client_deactivated_cb, inst);
587         }
588
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);
596                 DbgFree(inst);
597                 return NULL;
598         }
599
600         inst->state = INST_INIT;
601         inst->requested_state = INST_INIT;
602         instance_ref(inst);
603
604         if (package_add_instance(inst->info, inst) < 0) {
605                 instance_state_reset(inst);
606                 instance_destroy(inst);
607                 return NULL;
608         }
609
610         slave_load_instance(package_slave(inst->info));
611
612         if (instance_activate(inst) < 0) {
613                 instance_state_reset(inst);
614                 instance_destroy(inst);
615                 inst = NULL;
616         }
617
618         return inst;
619 }
620
621 HAPI struct inst_info *instance_ref(struct inst_info *inst)
622 {
623         if (!inst)
624                 return NULL;
625
626         inst->refcnt++;
627         return inst;
628 }
629
630 HAPI struct inst_info *instance_unref(struct inst_info *inst)
631 {
632         if (!inst)
633                 return NULL;
634
635         if (inst->refcnt == 0) {
636                 ErrPrint("Instance refcnt is not valid\n");
637                 return NULL;
638         }
639
640         inst->refcnt--;
641         if (inst->refcnt == 0) {
642                 destroy_instance(inst);
643                 inst = NULL;
644         }
645
646         return inst;
647 }
648
649 static void deactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
650 {
651         struct inst_info *inst = data;
652         struct pkg_info *info;
653         int ret;
654
655         /*!
656          * \note
657          * In this callback, we cannot trust the "client" information.
658          * It could be cleared before reach to here.
659          */
660
661         if (!packet) {
662                 DbgPrint("Consuming a request of a dead process\n");
663                 /*!
664                  * \note
665                  * The instance_reload will care this.
666                  * And it will be called from the slave activate callback.
667                  */
668                 inst->changing_state = 0;
669                 instance_unref(inst);
670                 return;
671         }
672
673         if (packet_get(packet, "i", &ret) != 1) {
674                 ErrPrint("Invalid argument\n");
675                 inst->changing_state = 0;
676                 instance_unref(inst);
677                 return;
678         }
679
680         if (inst->state == INST_DESTROYED) {
681                 /*!
682                  * \note
683                  * Already destroyed.
684                  * Do nothing at here anymore.
685                  */
686                 inst->changing_state = 0;
687                 instance_unref(inst);
688                 return;
689         }
690
691         switch (ret) {
692         case 0:
693                 /*!
694                  * \note
695                  * Successfully unloaded
696                  */
697                 switch (inst->requested_state) {
698                 case INST_ACTIVATED:
699                         DbgPrint("REQ: ACTIVATED\n");
700                         instance_state_reset(inst);
701                         instance_reactivate(inst);
702                         break;
703                 case INST_DESTROYED:
704                         info = inst->info;
705                         instance_broadcast_deleted_event(inst);
706                         instance_state_reset(inst);
707                         instance_destroy(inst);
708                         DbgPrint("== %s\n", package_name(info));
709                 default:
710                         /*!< Unable to reach here */
711                         break;
712                 }
713
714                 break;
715         case -EINVAL:
716                 /*!
717                  * \note
718                  * Slave has no instance of this package.
719                  */
720         case -ENOENT:
721                 /*!
722                  * \note
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.
726                  */
727                 /*!
728                  * \note
729                  * Slave has no instance of this.
730                  * In this case, ignore the requested_state
731                  * Because, this instance is already met a problem.
732                  */
733         default:
734                 /*!
735                  * \note
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.
739                  */
740                 DbgPrint("[%s] instance destroying ret(%d)\n", package_name(inst->info), ret);
741                 info = inst->info;
742                 instance_broadcast_deleted_event(inst);
743                 instance_state_reset(inst);
744                 instance_destroy(inst);
745                 break;
746         }
747
748         inst->changing_state = 0;
749         instance_unref(inst);
750 }
751
752 static void reactivate_cb(struct slave_node *slave, const struct packet *packet, void *data)
753 {
754         struct inst_info *inst = data;
755         struct pkg_info *info;
756         enum lb_type lb_type;
757         enum pd_type pd_type;
758         int ret;
759         const char *content;
760         const char *title;
761         int is_pinned_up;
762
763         if (!packet) {
764                 DbgPrint("Consuming a request of a dead process\n");
765                 /*!
766                  * \note
767                  * instance_reload function will care this.
768                  * and it will be called from the slave_activate callback
769                  */
770                 goto out;
771         }
772
773         if (packet_get(packet, "issi", &ret, &content, &title, &is_pinned_up) != 4) {
774                 ErrPrint("Invalid parameter\n");
775                 goto out;
776         }
777
778         if (strlen(content)) {
779                 char *tmp;
780
781                 tmp = strdup(content);
782                 if (!tmp) {
783                         ErrPrint("Heap: %s\n", strerror(errno));
784                         goto out;
785                 }
786
787                 DbgFree(inst->content);
788                 inst->content = tmp;
789
790                 DbgPrint("Update content info %s\n", tmp);
791         }
792
793         if (strlen(title)) {
794                 char *tmp;
795
796                 tmp = strdup(title);
797                 if (!tmp) {
798                         ErrPrint("Heap: %s\n", strerror(errno));
799                         goto out;
800                 }
801
802                 DbgFree(inst->title);
803                 inst->title = tmp;
804
805                 DbgPrint("Update title info %s\n", tmp);
806         }
807
808         if (inst->state == INST_DESTROYED) {
809                 /*!
810                  * \note
811                  * Already destroyed.
812                  * Do nothing at here anymore.
813                  */
814                 goto out;
815         }
816
817         switch (ret) {
818         case 0: /*!< normally created */
819                 inst->state = INST_ACTIVATED;
820                 switch (inst->requested_state) {
821                 case INST_DESTROYED:
822                         instance_destroy(inst);
823                         break;
824                 case INST_ACTIVATED:
825                         inst->is_pinned_up = is_pinned_up;
826                         info = inst->info;
827                         lb_type = package_lb_type(info);
828                         pd_type = package_pd_type(info);
829
830                         /*!
831                          * \note
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.
840                          */
841
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);
846                         }
847
848                         if (pd_type == PD_TYPE_SCRIPT && inst->pd.canvas.script && inst->pd.is_opened_for_reactivate) {
849                                 double x, y;
850
851                                 instance_slave_get_pd_pos(inst, &x, &y);
852
853                                 /*!
854                                  * \note
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.
859                                  */
860                                 ret = instance_slave_open_pd(inst, NULL);
861
862                                 /*!
863                                  * \note
864                                  * In this case, master already loads the PD script.
865                                  * So just send the pd,show event to the slave again.
866                                  */
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) {
871                                 double x, y;
872
873                                 buffer_handler_load(inst->pd.canvas.buffer);
874                                 instance_slave_get_pd_pos(inst, &x, &y);
875
876                                 /*!
877                                  * \note
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.
882                                  */
883                                 ret = instance_slave_open_pd(inst, NULL);
884
885                                 /*!
886                                  * \note
887                                  * In this case, just send the pd,show event for keeping the compatibility
888                                  */
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);
892                         }
893
894                         /*!
895                          * \note
896                          * After create an instance again,
897                          * Send resize request to the livebox.
898                          * instance_resize(inst, inst->lb.width, inst->lb.height);
899                          *
900                          * renew request will resize the livebox while creating it again
901                          */
902
903                         /*!
904                          * \note
905                          * This function will check the visiblity of a livebox and
906                          * make decision whether it thaw the update timer or not.
907                          */
908                         instance_recover_visible_state(inst);
909                 default:
910                         break;
911                 }
912                 break;
913         default:
914                 info = inst->info;
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);
919                 break;
920         }
921
922 out:
923         inst->changing_state = 0;
924         instance_unref(inst);
925 }
926
927 static void activate_cb(struct slave_node *slave, const struct packet *packet, void *data)
928 {
929         struct inst_info *inst = data;
930         int ret;
931         int w;
932         int h;
933         double priority;
934         char *content;
935         char *title;
936         int is_pinned_up;
937
938         if (!packet) {
939                 DbgPrint("Consuming a request of a dead process\n");
940                 /*!
941                  * \note
942                  * instance_reload will care this
943                  * it will be called from the slave_activate callback
944                  */
945                 goto out;
946         }
947
948         if (packet_get(packet, "iiidssi", &ret, &w, &h, &priority, &content, &title, &is_pinned_up) != 7) {
949                 ErrPrint("Invalid parameter\n");
950                 goto out;
951         }
952
953         if (inst->state == INST_DESTROYED) {
954                 /*!
955                  * \note
956                  * Already destroyed.
957                  * Do nothing at here anymore.
958                  */
959                 goto out;
960         }
961
962         switch (ret) {
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,
968                                                         inst->period, 0, 0);
969                         if (!new_inst)
970                                 ErrPrint("Failed to create a new instance\n");
971                 } else {
972                         ErrPrint("Not enough space\n");
973                 }
974         case 0: /*!< normally created */
975                 /*!
976                  * \note
977                  * Anyway this instance is loaded to the slave,
978                  * so just increase the loaded instance counter
979                  * After that, do reset jobs.
980                  */
981                 inst->state = INST_ACTIVATED;
982
983                 instance_set_lb_info(inst, w, h, priority, content, title);
984
985                 switch (inst->requested_state) {
986                 case INST_DESTROYED:
987                         instance_unicast_deleted_event(inst, NULL);
988                         instance_state_reset(inst);
989                         instance_destroy(inst);
990                         break;
991                 case INST_ACTIVATED:
992                 default:
993                         /*!
994                          * \note
995                          * LB should be created at the create time
996                          */
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);
1001
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);
1006
1007                                 if (!inst->lb.canvas.script)
1008                                         ErrPrint("Failed to create LB\n");
1009                                 else
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);
1013                         }
1014
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);
1019                                 }
1020
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);
1025
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);
1030                         }
1031
1032                         instance_broadcast_created_event(inst);
1033
1034                         instance_thaw_updator(inst);
1035                         break;
1036                 }
1037                 break;
1038         default:
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);
1043                 break;
1044         }
1045
1046 out:
1047         inst->changing_state = 0;
1048         instance_unref(inst);
1049 }
1050
1051 HAPI int instance_create_pd_buffer(struct inst_info *inst)
1052 {
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);
1056         }
1057
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");
1062         }
1063
1064         return !!inst->pd.canvas.buffer;
1065 }
1066
1067 HAPI int instance_create_lb_buffer(struct inst_info *inst)
1068 {
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);
1071
1072         if (!inst->lb.canvas.buffer) {
1073                 /*!
1074                  * \note
1075                  * Slave doesn't call the acquire_buffer.
1076                  * In this case, create the buffer from here.
1077                  */
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");
1081         }
1082
1083         return !!inst->lb.canvas.buffer;
1084 }
1085
1086 HAPI int instance_destroy(struct inst_info *inst)
1087 {
1088         struct packet *packet;
1089
1090         if (!inst) {
1091                 ErrPrint("Invalid instance handle\n");
1092                 return -EINVAL;
1093         }
1094
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;
1100                 return 0;
1101         case INST_INIT:
1102                 inst->state = INST_DESTROYED;
1103                 inst->requested_state = INST_DESTROYED;
1104                 instance_unref(inst);
1105                 return 0;
1106         case INST_DESTROYED:
1107                 inst->requested_state = INST_DESTROYED;
1108                 return 0;
1109         default:
1110                 break;
1111         }
1112
1113         packet = packet_create("delete", "ss", package_name(inst->info), inst->id);
1114         if (!packet) {
1115                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1116                 return -EFAULT;
1117         }
1118
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);
1123 }
1124
1125 /* Client Deactivated Callback */
1126 static int pd_buffer_close_cb(struct client_node *client, void *inst)
1127 {
1128         int ret;
1129
1130         ret = instance_slave_close_pd(inst, client);
1131         DbgPrint("Forcely close the PD ret: %d\n", ret);
1132         return -1; /* Delete this callback */
1133 }
1134
1135 /* Client Deactivated Callback */
1136 static int pd_script_close_cb(struct client_node *client, void *inst)
1137 {
1138         int ret;
1139
1140         ret = instance_slave_close_pd(inst, client);
1141         DbgPrint("Forcely close the PD ret: %d\n", ret);
1142
1143         ret = script_handler_unload(instance_pd_script(inst), 1);
1144         return -1; /* Delete this callback */
1145 }
1146
1147 static inline void release_resource_for_closing_pd(struct pkg_info *info, struct inst_info *inst, struct client_node *client)
1148 {
1149         if (!client) {
1150                 client = inst->pd.owner;
1151                 if (!client)
1152                         return;
1153         }
1154
1155         /*!
1156          * \note
1157          * Clean up the resources
1158          */
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) {
1161                         /*!
1162                          * \note
1163                          * Only if this function succeed to remove the pd_buffer_close_cb,
1164                          * Decrease the reference count of this instance
1165                          */
1166                 }
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) {
1170                         /*!
1171                          * \note
1172                          * Only if this function succeed to remove the script_close_cb,
1173                          * Decrease the reference count of this instance
1174                          */
1175                 }
1176                 instance_unref(inst);
1177         } else {
1178                 ErrPrint("Unknown PD type\n");
1179         }
1180
1181 }
1182
1183 HAPI int instance_state_reset(struct inst_info *inst)
1184 {
1185         enum lb_type lb_type;
1186         enum pd_type pd_type;
1187
1188         if (!inst) {
1189                 ErrPrint("Invalid instance handle\n");
1190                 return -EINVAL;
1191         }
1192
1193         if (inst->state == INST_DESTROYED)
1194                 return 0;
1195
1196         lb_type = package_lb_type(inst->info);
1197         pd_type = package_pd_type(inst->info);
1198
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);
1203
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);
1212         }
1213
1214         inst->state = INST_INIT;
1215         inst->requested_state = INST_INIT;
1216         return 0;
1217 }
1218
1219 HAPI int instance_reactivate(struct inst_info *inst)
1220 {
1221         struct packet *packet;
1222         int ret;
1223
1224         if (!inst) {
1225                 ErrPrint("Invalid instance handle\n");
1226                 return -EINVAL;
1227         }
1228
1229         if (package_is_fault(inst->info)) {
1230                 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1231                 return -EFAULT;
1232         }
1233
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;
1239                 return 0;
1240         case INST_DESTROYED:
1241         case INST_ACTIVATED:
1242                 return 0;
1243         case INST_INIT:
1244         default:
1245                 break;
1246         }
1247
1248         packet = packet_create("renew", "sssiidssiis",
1249                         package_name(inst->info),
1250                         inst->id,
1251                         inst->content,
1252                         inst->timeout,
1253                         !!package_lb_path(inst->info),
1254                         inst->period,
1255                         inst->cluster,
1256                         inst->category,
1257                         inst->lb.width, inst->lb.height,
1258                         package_abi(inst->info));
1259         if (!packet) {
1260                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1261                 return -EFAULT;
1262         }
1263
1264         ret = slave_activate(package_slave(inst->info));
1265         if (ret < 0 && ret != -EALREADY) {
1266                 /*!
1267                  * \note
1268                  * If the master failed to launch the slave,
1269                  * Do not send any requests to the slave.
1270                  */
1271                 ErrPrint("Failed to launch the slave\n");
1272                 packet_destroy(packet);
1273                 return ret;
1274         }
1275
1276         inst->requested_state = INST_ACTIVATED;
1277         inst->state = INST_REQUEST_TO_REACTIVATE;
1278         inst->changing_state = 1;
1279
1280         return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, reactivate_cb, instance_ref(inst), 1);
1281 }
1282
1283 HAPI int instance_activate(struct inst_info *inst)
1284 {
1285         struct packet *packet;
1286         int ret;
1287
1288         if (!inst) {
1289                 ErrPrint("Invalid instance handle\n");
1290                 return -EINVAL;
1291         }
1292
1293         if (package_is_fault(inst->info)) {
1294                 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1295                 return -EFAULT;
1296         }
1297
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;
1303                 return 0;
1304         case INST_ACTIVATED:
1305         case INST_DESTROYED:
1306                 return 0;
1307         case INST_INIT:
1308         default:
1309                 break;
1310         }
1311
1312         packet = packet_create("new", "sssiidssisii",
1313                         package_name(inst->info),
1314                         inst->id,
1315                         inst->content,
1316                         inst->timeout,
1317                         !!package_lb_path(inst->info),
1318                         inst->period,
1319                         inst->cluster,
1320                         inst->category,
1321                         !!inst->client,
1322                         package_abi(inst->info),
1323                         inst->lb.width,
1324                         inst->lb.height);
1325         if (!packet) {
1326                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1327                 return -EFAULT;
1328         }
1329
1330         ret = slave_activate(package_slave(inst->info));
1331         if (ret < 0 && ret != -EALREADY) {
1332                 /*!
1333                  * \note
1334                  * If the master failed to launch the slave,
1335                  * Do not send any requests to the slave.
1336                  */
1337                 ErrPrint("Failed to launch the slave\n");
1338                 packet_destroy(packet);
1339                 return ret;
1340         }
1341
1342         inst->state = INST_REQUEST_TO_ACTIVATE;
1343         inst->requested_state = INST_ACTIVATED;
1344         inst->changing_state = 1;
1345
1346         /*!
1347          * \note
1348          * Try to activate a slave if it is not activated
1349          */
1350         return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, activate_cb, instance_ref(inst), 1);
1351 }
1352
1353 HAPI void instance_lb_updated(const char *pkgname, const char *id)
1354 {
1355         struct inst_info *inst;
1356
1357         inst = package_find_instance_by_id(pkgname, id);
1358         if (!inst)
1359                 return;
1360
1361         instance_lb_updated_by_instance(inst);
1362 }
1363
1364 HAPI void instance_lb_updated_by_instance(struct inst_info *inst)
1365 {
1366         struct packet *packet;
1367         const char *id;
1368         enum lb_type lb_type;
1369         const char *title;
1370         const char *content;
1371
1372         if (inst->client && inst->visible != LB_SHOW) {
1373                 if (inst->visible == LB_HIDE) {
1374                         DbgPrint("Ignore update event %s(HIDE)\n", inst->id);
1375                         return;
1376                 }
1377                 DbgPrint("Livebox(%s) is PAUSED. But content is updated.\n", inst->id);
1378         }
1379
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);
1385         else
1386                 id = "";
1387
1388         if (inst->content)
1389                 content = inst->content;
1390         else
1391                 content = "";
1392
1393         if (inst->title)
1394                 title = inst->title;
1395         else
1396                 title = "";
1397
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);
1401         if (!packet) {
1402                 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1403                 return;
1404         }
1405
1406         (void)CLIENT_SEND_EVENT(inst, packet);
1407 }
1408
1409 HAPI void instance_pd_updated_by_instance(struct inst_info *inst, const char *descfile)
1410 {
1411         struct packet *packet;
1412         const char *id;
1413
1414         if (inst->client && inst->visible != LB_SHOW) {
1415                 DbgPrint("Livebox is hidden. ignore update event\n");
1416                 return;
1417         }
1418
1419         if (!inst->pd.need_to_send_close_event) {
1420                 DbgPrint("PD is not created yet. Ignore update event - %s\n", descfile);
1421
1422                 if (inst->pd.pended_update_desc) {
1423                         DbgFree(inst->pd.pended_update_desc);
1424                         inst->pd.pended_update_desc = NULL;
1425                 }
1426
1427                 if (descfile) {
1428                         inst->pd.pended_update_desc = strdup(descfile);
1429                         if (!inst->pd.pended_update_desc)
1430                                 ErrPrint("Heap: %s\n", strerror(errno));
1431                 }
1432
1433                 inst->pd.pended_update_cnt++;
1434                 return;
1435         }
1436
1437         if (!descfile)
1438                 descfile = inst->id;
1439
1440         switch (package_pd_type(inst->info)) {
1441         case PD_TYPE_SCRIPT:
1442                 id = fb_id(script_handler_fb(inst->pd.canvas.script));
1443                 break;
1444         case PD_TYPE_BUFFER:
1445                 id = buffer_handler_id(inst->pd.canvas.buffer);
1446                 break;
1447         case PD_TYPE_TEXT:
1448         default:
1449                 id = "";
1450                 break;
1451         }
1452
1453         packet = packet_create_noack("pd_updated", "ssssii",
1454                         package_name(inst->info), inst->id, descfile, id,
1455                         inst->pd.width, inst->pd.height);
1456         if (!packet) {
1457                 ErrPrint("Failed to create param (%s - %s)\n", package_name(inst->info), inst->id);
1458                 return;
1459         }
1460
1461         (void)CLIENT_SEND_EVENT(inst, packet);
1462 }
1463
1464 HAPI void instance_pd_updated(const char *pkgname, const char *id, const char *descfile)
1465 {
1466         struct inst_info *inst;
1467
1468         inst = package_find_instance_by_id(pkgname, id);
1469         if (!inst)
1470                 return;
1471
1472         instance_pd_updated_by_instance(inst, descfile);
1473 }
1474
1475 HAPI void instance_set_lb_info(struct inst_info *inst, int w, int h, double priority, const char *content, const char *title)
1476 {
1477         char *_content = NULL;
1478         char *_title = NULL;
1479
1480         if (content && strlen(content)) {
1481                 _content = strdup(content);
1482                 if (!_content)
1483                         ErrPrint("Heap: %s\n", strerror(errno));
1484         }
1485
1486         if (title && strlen(title)) {
1487                 _title = strdup(title);
1488                 if (!_title)
1489                         ErrPrint("Heap: %s\n", strerror(errno));
1490         }
1491
1492         inst->lb.width = w;
1493         inst->lb.height = h;
1494
1495         if (_content) {
1496                 DbgFree(inst->content);
1497                 inst->content= _content;
1498         }
1499
1500         if (_title) {
1501                 DbgFree(inst->title);
1502                 inst->title = _title;
1503         }
1504
1505         if (priority >= 0.0f && priority <= 1.0f)
1506                 inst->lb.priority = priority;
1507 }
1508
1509 HAPI void instance_set_pd_info(struct inst_info *inst, int w, int h)
1510 {
1511         inst->pd.width = w;
1512         inst->pd.height = h;
1513 }
1514
1515 static void pinup_cb(struct slave_node *slave, const struct packet *packet, void *data)
1516 {
1517         struct set_pinup_cbdata *cbdata = data;
1518         const char *content;
1519         struct packet *result;
1520         int ret;
1521
1522         if (!packet) {
1523                 /*!
1524                  * \todo
1525                  * Send pinup failed event to client.
1526                  */
1527                 ret = -EINVAL;
1528                 goto out;
1529         }
1530
1531         if (packet_get(packet, "is", &ret, &content) != 2) {
1532                 /*!
1533                  * \todo
1534                  * Send pinup failed event to client
1535                  */
1536                 ret = -EINVAL;
1537                 goto out;
1538         }
1539
1540         if (ret == 0) {
1541                 char *new_content;
1542
1543                 new_content = strdup(content);
1544                 if (!new_content) {
1545                         ErrPrint("Heap: %s\n", strerror(errno));
1546                         /*!
1547                          * \note
1548                          * send pinup failed event to client
1549                          */
1550                         ret = -ENOMEM;
1551                         goto out;
1552                 }
1553         
1554                 cbdata->inst->is_pinned_up = cbdata->pinup;
1555                 DbgFree(cbdata->inst->content);
1556
1557                 cbdata->inst->content = new_content;
1558         }
1559
1560 out:
1561         /*!
1562          * \node
1563          * Send PINUP Result to client.
1564          * Client should wait this event.
1565          */
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);
1568         if (result)
1569                 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
1570         else
1571                 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
1572
1573         instance_unref(cbdata->inst);
1574         DbgFree(cbdata);
1575 }
1576
1577 HAPI int instance_set_pinup(struct inst_info *inst, int pinup)
1578 {
1579         struct set_pinup_cbdata *cbdata;
1580         struct packet *packet;
1581
1582         if (!inst) {
1583                 ErrPrint("Invalid instance handle\n");
1584                 return -EINVAL;
1585         }
1586
1587         if (package_is_fault(inst->info)) {
1588                 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1589                 return -EFAULT;
1590         }
1591
1592         if (!package_pinup(inst->info))
1593                 return -EINVAL;
1594
1595         if (pinup == inst->is_pinned_up)
1596                 return -EINVAL;
1597
1598         cbdata = malloc(sizeof(*cbdata));
1599         if (!cbdata)
1600                 return -ENOMEM;
1601
1602         cbdata->inst = instance_ref(inst);
1603         cbdata->pinup = pinup;
1604
1605         packet = packet_create("pinup", "ssi", package_name(inst->info), inst->id, pinup);
1606         if (!packet) {
1607                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1608                 instance_unref(cbdata->inst);
1609                 DbgFree(cbdata);
1610                 return -EFAULT;
1611         }
1612
1613         return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, pinup_cb, cbdata, 0);
1614 }
1615
1616 HAPI int instance_freeze_updator(struct inst_info *inst)
1617 {
1618         if (!inst->update_timer)
1619                 return -EINVAL;
1620
1621         DbgPrint("Freeze the update timer (%s)\n", inst->id);
1622         timer_freeze(inst);
1623         return 0;
1624 }
1625
1626 HAPI int instance_thaw_updator(struct inst_info *inst)
1627 {
1628         if (!inst->update_timer)
1629                 return -EINVAL;
1630
1631         if (client_is_all_paused() || setting_is_lcd_off()) {
1632                 DbgPrint("Skip thaw (%s)\n", inst->id);
1633                 return -EINVAL;
1634         }
1635
1636         if (inst->visible == LB_HIDE_WITH_PAUSE) {
1637                 DbgPrint("Live box is invisible (%s)\n", inst->id);
1638                 return -EINVAL;
1639         }
1640
1641         DbgPrint("Thaw the update timer (%s)\n", inst->id);
1642         timer_thaw(inst);
1643         return 0;
1644 }
1645
1646 HAPI enum livebox_visible_state instance_visible_state(struct inst_info *inst)
1647 {
1648         return inst->visible;
1649 }
1650
1651 HAPI int instance_set_visible_state(struct inst_info *inst, enum livebox_visible_state state)
1652 {
1653         if (inst->visible == state) {
1654                 DbgPrint("Visibility has no changed\n");
1655                 return 0;
1656         }
1657
1658         switch (state) {
1659         case LB_SHOW:
1660         case LB_HIDE:
1661                 if (inst->visible == LB_HIDE_WITH_PAUSE) {
1662                         if (resume_livebox(inst) == 0)
1663                                 inst->visible = state;
1664
1665                         instance_thaw_updator(inst);
1666                 } else {
1667                         inst->visible = state;
1668                 }
1669                 break;
1670
1671         case LB_HIDE_WITH_PAUSE:
1672                 if (pause_livebox(inst) == 0)
1673                         inst->visible = LB_HIDE_WITH_PAUSE;
1674
1675                 instance_freeze_updator(inst);
1676                 break;
1677
1678         default:
1679                 return -EINVAL;
1680         }
1681
1682         return 0;
1683 }
1684
1685 static void resize_cb(struct slave_node *slave, const struct packet *packet, void *data)
1686 {
1687         struct resize_cbdata *cbdata = data;
1688         int ret;
1689
1690         if (!packet) {
1691                 instance_unref(cbdata->inst);
1692                 DbgFree(cbdata);
1693                 return;
1694         }
1695
1696         if (packet_get(packet, "i", &ret) != 1) {
1697                 ErrPrint("Invalid parameter\n");
1698                 instance_unref(cbdata->inst);
1699                 DbgFree(cbdata);
1700                 return;
1701         }
1702
1703         if (ret == 0) {
1704                 cbdata->inst->lb.width = cbdata->w;
1705                 cbdata->inst->lb.height = cbdata->h;
1706         } else {
1707                 ErrPrint("Failed to change the size of a livebox (%d)\n", ret);
1708         }
1709
1710         instance_unref(cbdata->inst);
1711         DbgFree(cbdata);
1712 }
1713
1714 HAPI int instance_resize(struct inst_info *inst, int w, int h)
1715 {
1716         struct resize_cbdata *cbdata;
1717         struct packet *packet;
1718         int ret;
1719
1720         if (!inst) {
1721                 ErrPrint("Invalid instance handle\n");
1722                 return -EINVAL;
1723         }
1724
1725         if (package_is_fault(inst->info)) {
1726                 ErrPrint("Fault package: %s\n", package_name(inst->info));
1727                 return -EFAULT;
1728         }
1729
1730         cbdata = malloc(sizeof(*cbdata));
1731         if (!cbdata) {
1732                 ErrPrint("Heap: %s\n", strerror(errno));
1733                 return -ENOMEM;
1734         }
1735
1736         cbdata->inst = instance_ref(inst);
1737         cbdata->w = w;
1738         cbdata->h = h;
1739
1740         /* NOTE: param is resued from here */
1741         packet = packet_create("resize", "ssii", package_name(inst->info), inst->id, w, h);
1742         if (!packet) {
1743                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1744                 instance_unref(cbdata->inst);
1745                 DbgFree(cbdata);
1746                 return -EFAULT;
1747         }
1748
1749         ret = slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, resize_cb, cbdata, 0);
1750         return ret;
1751 }
1752
1753 static void set_period_cb(struct slave_node *slave, const struct packet *packet, void *data)
1754 {
1755         int ret;
1756         struct period_cbdata *cbdata = data;
1757         struct packet *result;
1758
1759         if (!packet) {
1760                 ret = -EFAULT;
1761                 goto out;
1762         }
1763
1764         if (packet_get(packet, "i", &ret) != 1) {
1765                 ret = -EINVAL;
1766                 goto out;
1767         }
1768
1769         if (ret == 0)
1770                 cbdata->inst->period = cbdata->period;
1771         else
1772                 ErrPrint("Failed to set period %d\n", ret);
1773
1774 out:
1775         result = packet_create_noack("period_changed", "idss", ret, cbdata->inst->period, package_name(cbdata->inst->info), cbdata->inst->id);
1776         if (result)
1777                 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
1778         else
1779                 ErrPrint("Failed to build a packet for %s\n", package_name(cbdata->inst->info));
1780
1781         instance_unref(cbdata->inst);
1782         DbgFree(cbdata);
1783         return;
1784 }
1785
1786 static Eina_Bool timer_updator_cb(void *data)
1787 {
1788         struct period_cbdata *cbdata = data;
1789         struct inst_info *inst;
1790         double period;
1791         struct packet *result;
1792
1793         period = cbdata->period;
1794         inst = cbdata->inst;
1795         DbgFree(cbdata);
1796
1797         DbgPrint("Update period is changed to %lf from %lf\n", period, inst->period);
1798
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;
1804                 } else {
1805                         util_timer_interval_set(inst->update_timer, inst->period);
1806                 }
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);
1811                 else
1812                         timer_freeze(inst); /* Freeze the update timer as default */
1813         }
1814
1815         result = packet_create_noack("period_changed", "idss", 0, inst->period, package_name(inst->info), inst->id);
1816         if (result)
1817                 (void)CLIENT_SEND_EVENT(inst, result);
1818         else
1819                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1820
1821         instance_unref(inst);
1822         return ECORE_CALLBACK_CANCEL;
1823 }
1824
1825 HAPI int instance_set_period(struct inst_info *inst, double period)
1826 {
1827         struct packet *packet;
1828         struct period_cbdata *cbdata;
1829
1830         if (!inst) {
1831                 ErrPrint("Invalid instance handle\n");
1832                 return -EINVAL;
1833         }
1834
1835         if (package_is_fault(inst->info)) {
1836                 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1837                 return -EFAULT;
1838         }
1839
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 */
1844         }
1845
1846         cbdata = malloc(sizeof(*cbdata));
1847         if (!cbdata) {
1848                 ErrPrint("Heap: %s\n", strerror(errno));
1849                 return -ENOMEM;
1850         }
1851
1852         cbdata->period = period;
1853         cbdata->inst = instance_ref(inst);
1854
1855         if (package_secured(inst->info)) {
1856                 /*!
1857                  * \note
1858                  * Secured livebox doesn't need to send its update period to the slave.
1859                  * Slave has no local timer for updating liveboxes
1860                  *
1861                  * So update its timer at here.
1862                  */
1863                 if (!ecore_timer_add(DELAY_TIME, timer_updator_cb, cbdata))
1864                         timer_updator_cb(cbdata);
1865                 return 0;
1866         }
1867
1868         packet = packet_create("set_period", "ssd", package_name(inst->info), inst->id, period);
1869         if (!packet) {
1870                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1871                 instance_unref(cbdata->inst);
1872                 DbgFree(cbdata);
1873                 return -EFAULT;
1874         }
1875
1876         return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, set_period_cb, cbdata, 0);
1877 }
1878
1879 HAPI int instance_clicked(struct inst_info *inst, const char *event, double timestamp, double x, double y)
1880 {
1881         struct packet *packet;
1882
1883         if (!inst) {
1884                 ErrPrint("Invalid instance handle\n");
1885                 return -EINVAL;
1886         }
1887
1888         if (package_is_fault(inst->info)) {
1889                 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1890                 return -EFAULT;
1891         }
1892
1893         /* NOTE: param is resued from here */
1894         packet = packet_create_noack("clicked", "sssddd", package_name(inst->info), inst->id, event, timestamp, x, y);
1895         if (!packet) {
1896                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1897                 return -EFAULT;
1898         }
1899
1900         return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
1901 }
1902
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)
1904 {
1905         const char *pkgname;
1906         const char *id;
1907         struct slave_node *slave;
1908         struct packet *packet;
1909         int ret;
1910
1911         pkgname = package_name(instance_package(inst));
1912         id = instance_id(inst);
1913         if (!pkgname || !id) {
1914                 ErrPrint("Invalid instance\n");
1915                 return -EINVAL;
1916         }
1917
1918         slave = package_slave(instance_package(inst));
1919         if (!slave) {
1920                 ErrPrint("Slave is not valid\n");
1921                 return -EINVAL;
1922         }
1923
1924         packet = packet_create_noack("script", "ssssddddddi",
1925                         pkgname, id,
1926                         signal, part,
1927                         sx, sy, ex, ey,
1928                         x, y, down);
1929         if (!packet) {
1930                 ErrPrint("Failed to create param\n");
1931                 return -EFAULT;
1932         }
1933
1934         ret = slave_rpc_request_only(slave, pkgname, packet, 0); 
1935         return ret;
1936 }
1937
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)
1939 {
1940         struct packet *packet;
1941
1942         if (!inst) {
1943                 ErrPrint("Invalid instance handle\n");
1944                 return -EINVAL;
1945         }
1946
1947         if (package_is_fault(inst->info)) {
1948                 DbgPrint("Fault package [%s]\n", package_name(inst->info));
1949                 return -EFAULT;
1950         }
1951
1952         packet = packet_create_noack("text_signal", "ssssdddd", package_name(inst->info), inst->id, emission, source, sx, sy, ex, ey);
1953         if (!packet) {
1954                 ErrPrint("Failed to build a packet for %s\n", package_name(inst->info));
1955                 return -EFAULT;
1956         }
1957
1958         return slave_rpc_request_only(package_slave(inst->info), package_name(inst->info), packet, 0);
1959 }
1960
1961 static void change_group_cb(struct slave_node *slave, const struct packet *packet, void *data)
1962 {
1963         struct change_group_cbdata *cbdata = data;
1964         struct packet *result;
1965         int ret;
1966
1967         if (!packet) {
1968                 DbgFree(cbdata->cluster);
1969                 DbgFree(cbdata->category);
1970                 ret = -EFAULT;
1971                 goto out;
1972         }
1973
1974         if (packet_get(packet, "i", &ret) != 1) {
1975                 ErrPrint("Invalid packet\n");
1976                 DbgFree(cbdata->cluster);
1977                 DbgFree(cbdata->category);
1978                 ret = -EINVAL;
1979                 goto out;
1980         }
1981
1982         if (ret == 0) {
1983                 DbgFree(cbdata->inst->cluster);
1984                 cbdata->inst->cluster = cbdata->cluster;
1985
1986                 DbgFree(cbdata->inst->category);
1987                 cbdata->inst->category = cbdata->category;
1988         } else {
1989                 DbgFree(cbdata->cluster);
1990                 DbgFree(cbdata->category);
1991         }
1992
1993 out:
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);
1997         if (!result)
1998                 ErrPrint("Failed to build a packet %s\n", package_name(cbdata->inst->info));
1999         else
2000                 (void)CLIENT_SEND_EVENT(cbdata->inst, result);
2001
2002         instance_unref(cbdata->inst);
2003         DbgFree(cbdata);
2004 }
2005
2006 HAPI int instance_change_group(struct inst_info *inst, const char *cluster, const char *category)
2007 {
2008         struct packet *packet;
2009         struct change_group_cbdata *cbdata;
2010
2011         if (!inst) {
2012                 ErrPrint("Invalid instance handle\n");
2013                 return -EINVAL;
2014         }
2015
2016         if (package_is_fault(inst->info)) {
2017                 DbgPrint("Fault package [%s]\n", package_name(inst->info));
2018                 return -EFAULT;
2019         }
2020
2021         cbdata = malloc(sizeof(*cbdata));
2022         if (!cbdata) {
2023                 ErrPrint("Heap: %s\n", strerror(errno));
2024                 return -ENOMEM;
2025         }
2026
2027         cbdata->cluster = strdup(cluster);
2028         if (!cbdata->cluster) {
2029                 ErrPrint("Heap: %s\n", strerror(errno));
2030                 DbgFree(cbdata);
2031                 return -ENOMEM;
2032         }
2033
2034         cbdata->category = strdup(category);
2035         if (!cbdata->category) {
2036                 ErrPrint("Heap: %s\n", strerror(errno));
2037                 DbgFree(cbdata->cluster);
2038                 DbgFree(cbdata);
2039                 return -ENOMEM;
2040         }
2041
2042         cbdata->inst = instance_ref(inst);
2043
2044         packet = packet_create("change_group","ssss", package_name(inst->info), inst->id, cluster, category);
2045         if (!packet) {
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);
2050                 DbgFree(cbdata);
2051                 return -EFAULT;
2052         }
2053
2054         return slave_rpc_async_request(package_slave(inst->info), package_name(inst->info), packet, change_group_cb, cbdata, 0);
2055 }
2056
2057 HAPI const int const instance_auto_launch(const struct inst_info *inst)
2058 {
2059         return inst->lb.auto_launch;
2060 }
2061
2062 HAPI const int const instance_priority(const struct inst_info *inst)
2063 {
2064         return inst->lb.priority;
2065 }
2066
2067 HAPI const struct client_node *const instance_client(const struct inst_info *inst)
2068 {
2069         return inst->client;
2070 }
2071
2072 HAPI const double const instance_period(const struct inst_info *inst)
2073 {
2074         return inst->period;
2075 }
2076
2077 HAPI const int const instance_lb_width(const struct inst_info *inst)
2078 {
2079         return inst->lb.width;
2080 }
2081
2082 HAPI const int const instance_lb_height(const struct inst_info *inst)
2083 {
2084         return inst->lb.height;
2085 }
2086
2087 HAPI const int const instance_pd_width(const struct inst_info *inst)
2088 {
2089         return inst->pd.width;
2090 }
2091
2092 HAPI const int const instance_pd_height(const struct inst_info *inst)
2093 {
2094         return inst->pd.height;
2095 }
2096
2097 HAPI struct pkg_info *const instance_package(const struct inst_info *inst)
2098 {
2099         return inst->info;
2100 }
2101
2102 HAPI struct script_info *const instance_lb_script(const struct inst_info *inst)
2103 {
2104         return (package_lb_type(inst->info) == LB_TYPE_SCRIPT) ? inst->lb.canvas.script : NULL;
2105 }
2106
2107 HAPI struct script_info *const instance_pd_script(const struct inst_info *inst)
2108 {
2109         return (package_pd_type(inst->info) == PD_TYPE_SCRIPT) ? inst->pd.canvas.script : NULL;
2110 }
2111
2112 HAPI struct buffer_info *const instance_lb_buffer(const struct inst_info *inst)
2113 {
2114         return (package_lb_type(inst->info) == LB_TYPE_BUFFER) ? inst->lb.canvas.buffer : NULL;
2115 }
2116
2117 HAPI struct buffer_info *const instance_pd_buffer(const struct inst_info *inst)
2118 {
2119         return (package_pd_type(inst->info) == PD_TYPE_BUFFER) ? inst->pd.canvas.buffer : NULL;
2120 }
2121
2122 HAPI const char *const instance_id(const struct inst_info *inst)
2123 {
2124         return inst->id;
2125 }
2126
2127 HAPI const char *const instance_content(const struct inst_info *inst)
2128 {
2129         return inst->content;
2130 }
2131
2132 HAPI const char *const instance_category(const struct inst_info *inst)
2133 {
2134         return inst->category;
2135 }
2136
2137 HAPI const char *const instance_cluster(const struct inst_info *inst)
2138 {
2139         return inst->cluster;
2140 }
2141
2142 HAPI const char * const instance_title(const struct inst_info *inst)
2143 {
2144         return inst->title;
2145 }
2146
2147 HAPI const double const instance_timestamp(const struct inst_info *inst)
2148 {
2149         return inst->timestamp;
2150 }
2151
2152 HAPI const enum instance_state const instance_state(const struct inst_info *inst)
2153 {
2154         return inst->state;
2155 }
2156
2157 HAPI int instance_destroyed(struct inst_info *inst)
2158 {
2159         switch (inst->state) {
2160         case INST_INIT:
2161         case INST_REQUEST_TO_ACTIVATE:
2162                 /*!
2163                  * \note
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.
2167                  */
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);
2172                 break;
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:
2181                 break;
2182         default:
2183                 return -EINVAL;
2184         }
2185
2186         return 0;
2187 }
2188
2189 /*!
2190  * Invoked when a slave is activated
2191  */
2192 HAPI int instance_recover_state(struct inst_info *inst)
2193 {
2194         struct pkg_info *info;
2195         int ret = 0;
2196
2197         if (inst->changing_state) {
2198                 DbgPrint("Doesn't need to recover the state\n");
2199                 return 0;
2200         }
2201
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);
2211                         ret = 1;
2212                         break;
2213                 case INST_DESTROYED:
2214                         DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2215                         info = inst->info;
2216                         instance_state_reset(inst);
2217                         instance_destroy(inst);
2218                         break;
2219                 default:
2220                         break;
2221                 }
2222                 break;
2223         case INST_INIT:
2224         case INST_REQUEST_TO_ACTIVATE:
2225                 switch (inst->requested_state) {
2226                 case INST_ACTIVATED:
2227                 case INST_INIT:
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);
2235                         } else {
2236                                 ret = 1;
2237                         }
2238                         break;
2239                 case INST_DESTROYED:
2240                         DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2241                         instance_state_reset(inst);
2242                         instance_destroy(inst);
2243                         ret = 1;
2244                         break;
2245                 default:
2246                         break;
2247                 }
2248                 break;
2249         case INST_DESTROYED:
2250         default:
2251                 break;
2252         }
2253
2254         return ret;
2255 }
2256
2257 /*!
2258  * Invoked when a slave is deactivated
2259  */
2260 HAPI int instance_need_slave(struct inst_info *inst)
2261 {
2262         int ret = 0;
2263         struct pkg_info *info;
2264
2265         if (inst->client && client_is_faulted(inst->client)) {
2266                 info = inst->info;
2267
2268                 /*!
2269                  * \note
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
2274                  */
2275
2276                 DbgPrint("CLIENT FAULT: Req. to DESTROYED (%s)\n", package_name(info));
2277                 switch (inst->state) {
2278                 case INST_INIT:
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);
2285                         break;
2286                 case INST_DESTROYED:
2287                         break;
2288                 }
2289
2290                 return 0;
2291         }
2292
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) {
2298                 case INST_INIT:
2299                 case INST_ACTIVATED:
2300                         DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2301                         ret = 1;
2302                         break;
2303                 case INST_DESTROYED:
2304                         DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2305                         info = inst->info;
2306                         instance_state_reset(inst);
2307                         instance_destroy(inst);
2308                         break;
2309                 default:
2310                         break;
2311                 }
2312                 break;
2313         case INST_INIT:
2314         case INST_REQUEST_TO_ACTIVATE:
2315                 switch (inst->requested_state) {
2316                 case INST_INIT:
2317                 case INST_ACTIVATED:
2318                         DbgPrint("Req. to ACTIVATED (%s)\n", package_name(inst->info));
2319                         ret = 1;
2320                         break;
2321                 case INST_DESTROYED:
2322                         DbgPrint("Req. to DESTROYED (%s)\n", package_name(inst->info));
2323                         instance_state_reset(inst);
2324                         instance_destroy(inst);
2325                         break;
2326                 default:
2327                         break;
2328                 }
2329                 break;
2330         case INST_DESTROYED:
2331         default:
2332                 break;
2333         }
2334
2335         return ret;
2336 }
2337
2338 HAPI void instance_slave_set_pd_pos(struct inst_info *inst, double x, double y)
2339 {
2340         inst->pd.x = x;
2341         inst->pd.y = y;
2342 }
2343
2344 HAPI void instance_slave_get_pd_pos(struct inst_info *inst, double *x, double *y)
2345 {
2346         if (x)
2347                 *x = inst->pd.x;
2348         if (y)
2349                 *y = inst->pd.y;
2350 }
2351
2352 HAPI int instance_slave_open_pd(struct inst_info *inst, struct client_node *client)
2353 {
2354         const char *pkgname;
2355         const char *id;
2356         struct packet *packet;
2357         struct slave_node *slave;
2358         const struct pkg_info *info;
2359         int ret;
2360
2361         if (!client) {
2362                 client = inst->pd.owner;
2363                 if (!client) {
2364                         ErrPrint("Client is not valid\n");
2365                         return -EINVAL;
2366                 }
2367         } else if (inst->pd.owner) {
2368                 if (inst->pd.owner != client) {
2369                         ErrPrint("Client is already owned\n");
2370                         return -EBUSY;
2371                 }
2372         }
2373
2374         slave = package_slave(instance_package(inst));
2375         if (!slave)
2376                 return -EFAULT;
2377
2378         info = instance_package(inst);
2379         if (!info)
2380                 return -EINVAL;
2381
2382         pkgname = package_name(info);
2383         id = instance_id(inst);
2384
2385         if (!pkgname || !id)
2386                 return -EINVAL;
2387
2388         packet = packet_create_noack("pd_show", "ssiidd", pkgname, id, instance_pd_width(inst), instance_pd_height(inst), inst->pd.x, inst->pd.y);
2389         if (!packet) {
2390                 ErrPrint("Failed to create a packet\n");
2391                 return -EFAULT;
2392         }
2393
2394         slave_freeze_ttl(slave);
2395
2396         ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2397
2398         /*!
2399          * \note
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
2403          */
2404         if (package_pd_type(info) == PD_TYPE_BUFFER) {
2405                 instance_ref(inst);
2406                 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_buffer_close_cb, inst) < 0) {
2407                         instance_unref(inst);
2408                 }
2409         } else if (package_pd_type(info) == PD_TYPE_SCRIPT) {
2410                 instance_ref(inst);
2411                 if (client_event_callback_add(client, CLIENT_EVENT_DEACTIVATE, pd_script_close_cb, inst) < 0) {
2412                         instance_unref(inst);
2413                 }
2414         }
2415
2416         inst->pd.owner = client;
2417         return ret;
2418 }
2419
2420 HAPI int instance_slave_close_pd(struct inst_info *inst, struct client_node *client)
2421 {
2422         const char *pkgname;
2423         const char *id;
2424         struct packet *packet;
2425         struct slave_node *slave;
2426         struct pkg_info *info;
2427         int ret;
2428
2429         if (inst->pd.owner != client) {
2430                 ErrPrint("PD owner is not matched\n");
2431                 return -EINVAL;
2432         }
2433
2434         slave = package_slave(instance_package(inst));
2435         if (!slave)
2436                 return -EFAULT;
2437
2438         info = instance_package(inst);
2439         if (!info)
2440                 return -EINVAL;
2441
2442         pkgname = package_name(info);
2443         id = instance_id(inst);
2444
2445         if (!pkgname || !id)
2446                 return -EINVAL;
2447
2448         packet = packet_create_noack("pd_hide", "ss", pkgname, id);
2449         if (!packet) {
2450                 ErrPrint("Failed to create a packet\n");
2451                 return -EFAULT;
2452         }
2453
2454         slave_thaw_ttl(slave);
2455
2456         ret = slave_rpc_request_only(slave, pkgname, packet, 0);
2457         release_resource_for_closing_pd(info, inst, client);
2458         inst->pd.owner = NULL;
2459         return ret;
2460 }
2461
2462 HAPI int instance_client_pd_created(struct inst_info *inst, int status)
2463 {
2464         struct packet *packet;
2465         const char *buf_id;
2466         int ret;
2467
2468         if (inst->pd.need_to_send_close_event) {
2469                 DbgPrint("PD is already created\n");
2470                 return -EINVAL;
2471         }
2472
2473         switch (package_pd_type(inst->info)) {
2474         case PD_TYPE_SCRIPT:
2475                 buf_id = fb_id(script_handler_fb(inst->pd.canvas.script));
2476                 break;
2477         case PD_TYPE_BUFFER:
2478                 buf_id = buffer_handler_id(inst->pd.canvas.buffer);
2479                 break;
2480         case PD_TYPE_TEXT:
2481         default:
2482                 buf_id = "";
2483                 break;
2484         }
2485
2486         inst->pd.need_to_send_close_event = 1;
2487
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);
2491         if (!packet) {
2492                 ErrPrint("Failed to create a packet\n");
2493                 return -EFAULT;
2494         }
2495
2496         ret = CLIENT_SEND_EVENT(inst, packet);
2497
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;
2504         }
2505
2506         return ret;
2507 }
2508
2509 HAPI int instance_client_pd_destroyed(struct inst_info *inst, int status)
2510 {
2511         if (!inst->pd.need_to_send_close_event) {
2512                 DbgPrint("PD is not created\n");
2513                 return -EINVAL;
2514         }
2515
2516         inst->pd.need_to_send_close_event = 0;
2517
2518         return send_pd_destroyed_to_client(inst, status);
2519 }
2520
2521 HAPI int instance_add_client(struct inst_info *inst, struct client_node *client)
2522 {
2523         if (inst->client == client) {
2524                 ErrPrint("Owner cannot be the viewer\n");
2525                 return -EINVAL;
2526         }
2527
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");
2531                 return -EFAULT;
2532         }
2533
2534         instance_ref(inst);
2535         inst->client_list = eina_list_append(inst->client_list, client);
2536         return 0;
2537 }
2538
2539 HAPI int instance_del_client(struct inst_info *inst, struct client_node *client)
2540 {
2541         if (inst->client == client) {
2542                 ErrPrint("Owner is not in the viewer list\n");
2543                 return -EINVAL;
2544         }
2545
2546         client_event_callback_del(client, CLIENT_EVENT_DEACTIVATE, viewer_deactivated_cb, inst);
2547         viewer_deactivated_cb(client, inst);
2548         return 0;
2549 }
2550
2551 HAPI int instance_has_client(struct inst_info *inst, struct client_node *client)
2552 {
2553         return !!eina_list_data_find(inst->client_list, client);
2554 }
2555
2556 HAPI void *instance_client_list(struct inst_info *inst)
2557 {
2558         return inst->client_list;
2559 }
2560
2561 HAPI void instance_init(void)
2562 {
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;
2567 }
2568
2569 HAPI void instance_fini(void)
2570 {
2571 }
2572
2573 /* End of a file */