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