a139f7a2a055948f2122d318ad3b8f612e1d7aae
[platform/framework/web/livebox-viewer.git] / src / livebox.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.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 <errno.h>
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
21 #include <math.h>
22 #include <unistd.h>
23
24 #include <aul.h>
25 #include <dlog.h>
26
27 #include <com-core_packet.h>
28 #include <packet.h>
29 #include <livebox-service.h>
30 #include <livebox-errno.h>
31
32 #include "debug.h"
33 #include "fb.h"
34 #include "livebox.h"
35 #include "livebox_internal.h"
36 #include "dlist.h"
37 #include "util.h"
38 #include "master_rpc.h"
39 #include "client.h"
40 #include "critical_log.h"
41
42 #define EAPI __attribute__((visibility("default")))
43 #define MINIMUM_EVENT   s_info.event_filter
44
45 #if defined(FLOG)
46 FILE *__file_log_fp;
47 #endif
48
49 static struct info {
50         struct dlist *livebox_list;
51         struct dlist *event_list;
52         struct dlist *fault_list;
53         int init_count;
54         int prevent_overwrite;
55         double event_filter;
56 } s_info = {
57         .livebox_list = NULL,
58         .event_list = NULL,
59         .fault_list = NULL,
60         .init_count = 0,
61         .prevent_overwrite = 0,
62         .event_filter = 0.01f,
63 };
64
65 struct cb_info {
66         ret_cb_t cb;
67         void *data;
68 };
69
70 struct event_info {
71         int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data);
72         void *user_data;
73 };
74
75 struct fault_info {
76         int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data);
77         void *user_data;
78 };
79
80 static inline void default_create_cb(struct livebox *handler, int ret, void *data)
81 {
82         DbgPrint("Default created event handler: %d\n", ret);
83 }
84
85 static inline void default_delete_cb(struct livebox *handler, int ret, void *data)
86 {
87         DbgPrint("Default deleted event handler: %d\n", ret);
88 }
89
90 static inline void default_pinup_cb(struct livebox *handler, int ret, void *data)
91 {
92         DbgPrint("Default pinup event handler: %d\n", ret);
93 }
94
95 static inline void default_group_changed_cb(struct livebox *handler, int ret, void *data)
96 {
97         DbgPrint("Default group changed event handler: %d\n", ret);
98 }
99
100 static inline void default_period_changed_cb(struct livebox *handler, int ret, void *data)
101 {
102         DbgPrint("Default period changed event handler: %d\n", ret);
103 }
104
105 static inline void default_pd_created_cb(struct livebox *handler, int ret, void *data)
106 {
107         DbgPrint("Default PD created event handler: %d\n", ret);
108 }
109
110 static inline void default_pd_destroyed_cb(struct livebox *handler, int ret, void *data)
111 {
112         DbgPrint("Default PD destroyed event handler: %d\n", ret);
113 }
114
115 static inline void default_lb_size_changed_cb(struct livebox *handler, int ret, void *data)
116 {
117         DbgPrint("Default LB size changed event handler: %d\n", ret);
118 }
119
120 static inline void default_update_mode_cb(struct livebox *handler, int ret, void *data)
121 {
122         DbgPrint("Default update mode set event handler: %d\n", ret);
123 }
124
125 static inline void default_access_event_cb(struct livebox *handler, int ret, void *data)
126 {
127         DbgPrint("Default access event handler: %d\n", ret);
128 }
129
130 static inline __attribute__((always_inline)) struct cb_info *create_cb_info(ret_cb_t cb, void *data)
131 {
132         struct cb_info *info;
133
134         info = malloc(sizeof(*info));
135         if (!info) {
136                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
137                 return NULL;
138         }
139
140         info->cb = cb;
141         info->data = data;
142         return info;
143 }
144
145 static inline void destroy_cb_info(struct cb_info *info)
146 {
147         free(info);
148 }
149
150 static void update_mode_cb(struct livebox *handler, const struct packet *result, void *data)
151 {
152         int ret;
153
154         if (!result) {
155                 ret = LB_STATUS_ERROR_FAULT;
156                 goto errout;
157         } else if (packet_get(result, "i", &ret) != 1) {
158                 ErrPrint("Invalid argument\n");
159                 ret = LB_STATUS_ERROR_INVALID;
160                 goto errout;
161         }
162
163         if (ret < 0) {
164                 ErrPrint("Resize request is failed: %d\n", ret);
165                 goto errout;
166         }
167
168         return;
169
170 errout:
171         handler->update_mode_cb(handler, ret, handler->update_mode_cbdata);
172         handler->update_mode_cb = NULL;
173         handler->update_mode_cbdata = NULL;
174         return;
175 }
176
177 static void resize_cb(struct livebox *handler, const struct packet *result, void *data)
178 {
179         int ret;
180
181         if (!result) {
182                 ret = LB_STATUS_ERROR_FAULT;
183                 goto errout;
184         } else if (packet_get(result, "i", &ret) != 1) {
185                 ErrPrint("Invalid argument\n");
186                 ret = LB_STATUS_ERROR_INVALID;
187                 goto errout;
188         }
189
190         /*!
191          * \note
192          * In case of resize request,
193          * The livebox handler will not have resized value right after this callback,
194          * It can only get the new size when it makes updates.
195          *
196          * So the user can only get the resized value(result) from the first update event
197          * after this request.
198          */
199         if (ret < 0) {
200                 ErrPrint("Resize request is failed: %d\n", ret);
201                 goto errout;
202         }
203
204         return;
205
206 errout:
207         handler->size_changed_cb(handler, ret, handler->size_cbdata);
208         handler->size_changed_cb = NULL;
209         handler->size_cbdata = NULL;
210 }
211
212 static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data)
213 {
214         int ret;
215         void *cbdata;
216         struct cb_info *info = data;
217         ret_cb_t cb;
218
219         cbdata = info->data;
220         cb = info->cb;
221         destroy_cb_info(info);
222
223         if (!result) {
224                 ret = LB_STATUS_ERROR_FAULT;
225         } else if (packet_get(result, "i", &ret) != 1) {
226                 ErrPrint("Invalid argument\n");
227                 ret = LB_STATUS_ERROR_INVALID;
228         }
229
230         if (cb) {
231                 cb(handler, ret, cbdata);
232         }
233         return;
234 }
235
236 static void set_group_ret_cb(struct livebox *handler, const struct packet *result, void *data)
237 {
238         int ret;
239
240         if (!result) {
241                 ret = LB_STATUS_ERROR_FAULT;
242                 goto errout;
243         } else if (packet_get(result, "i", &ret) != 1) {
244                 ErrPrint("Invalid argument\n");
245                 ret = LB_STATUS_ERROR_INVALID;
246                 goto errout;
247         }
248
249         if (ret < 0) {
250                 goto errout;
251         }
252
253         return;
254
255 errout:
256         handler->group_changed_cb(handler, ret, handler->group_cbdata);
257         handler->group_changed_cb = NULL;
258         handler->group_cbdata = NULL;
259 }
260
261 static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data)
262 {
263         int ret;
264
265         if (!result) {
266                 ret = LB_STATUS_ERROR_FAULT;
267                 goto errout;
268         } else if (packet_get(result, "i", &ret) != 1) {
269                 ErrPrint("Invalid argument\n");
270                 ret = LB_STATUS_ERROR_INVALID;
271                 goto errout;
272         }
273
274         if (ret < 0) {
275                 goto errout;
276         }
277
278         return;
279
280 errout:
281         handler->period_changed_cb(handler, ret, handler->period_cbdata);
282         handler->period_changed_cb = NULL;
283         handler->period_cbdata = NULL;
284 }
285
286 static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data)
287 {
288         struct cb_info *info = data;
289         int ret;
290         ret_cb_t cb;
291         void *cbdata;
292
293         cb = info->cb;
294         cbdata = info->data;
295         destroy_cb_info(info);
296
297         if (!result) {
298                 ErrPrint("Connection lost?\n");
299                 ret = LB_STATUS_ERROR_FAULT;
300         } else if (packet_get(result, "i", &ret) != 1) {
301                 ErrPrint("Invalid argument\n");
302                 ret = LB_STATUS_ERROR_INVALID;
303         }
304
305         if (ret == 0) {
306                 handler->deleted_cb = cb;
307                 handler->deleted_cbdata = cbdata;
308         } else if (cb) {
309                 cb(handler, ret, cbdata);
310         }
311
312         /*!
313          * \note
314          * Do not call the deleted callback from here.
315          * master will send the "deleted" event.
316          * Then invoke this callback.
317          *
318          * if (handler->deleted_cb)
319          *      handler->deleted_cb(handler, ret, handler->deleted_cbdata);
320          */
321 }
322
323 static void new_ret_cb(struct livebox *handler, const struct packet *result, void *data)
324 {
325         int ret;
326         struct cb_info *info = data;
327         ret_cb_t cb;
328         void *cbdata;
329
330         cb = info->cb;
331         cbdata = info->data;
332         destroy_cb_info(info);
333
334         if (!result) {
335                 ret = LB_STATUS_ERROR_FAULT;
336         } else if (packet_get(result, "i", &ret) != 1) {
337                 ret = LB_STATUS_ERROR_INVALID;
338         }
339
340         if (ret >= 0) {
341                 handler->created_cb = cb;
342                 handler->created_cbdata = cbdata;
343
344                 /*!
345                  * \note
346                  * Don't go anymore ;)
347                  */
348                 return;
349         } else if (cb) {
350                 /*!
351                  * \note
352                  * It means the current instance is not created,
353                  * so user has to know about this.
354                  * notice it to user using "deleted" event.
355                  */
356                 cb(handler, ret, cbdata);
357         }
358
359         lb_unref(handler);
360 }
361
362 static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data)
363 {
364         int ret;
365
366         if (!result) {
367                 ret = LB_STATUS_ERROR_FAULT;
368                 goto errout;
369         } else if (packet_get(result, "i", &ret) != 1) {
370                 ret = LB_STATUS_ERROR_INVALID;
371                 goto errout;
372         }
373
374         if (ret < 0) {
375                 ErrPrint("Failed to create a PD[%d]\n", ret);
376                 goto errout;
377         }
378
379         return;
380
381 errout:
382         handler->pd_created_cb(handler, ret, handler->pd_created_cbdata);
383         handler->pd_created_cb = NULL;
384         handler->pd_created_cbdata = NULL;
385 }
386
387 static void activated_cb(struct livebox *handler, const struct packet *result, void *data)
388 {
389         int ret;
390         struct cb_info *info = data;
391         void *cbdata;
392         ret_cb_t cb;
393         const char *pkgname = "";
394
395         cbdata = info->data;
396         cb = info->cb;
397         destroy_cb_info(info);
398
399         if (!result) {
400                 ret = LB_STATUS_ERROR_FAULT;
401         } else if (packet_get(result, "is", &ret, &pkgname) != 2) {
402                 ret = LB_STATUS_ERROR_INVALID;
403         }
404
405         if (cb) {
406                 cb(handler, ret, cbdata);
407         }
408 }
409
410 static void pd_destroy_cb(struct livebox *handler, const struct packet *result, void *data)
411 {
412         int ret;
413         ret_cb_t cb;
414         void *cbdata;
415         struct cb_info *info = data;
416
417         cbdata = info->data;
418         cb = info->cb;
419         destroy_cb_info(info);
420
421         if (!result) {
422                 ErrPrint("Result is NIL (may connection lost)\n");
423                 ret = LB_STATUS_ERROR_FAULT;
424         } else if (packet_get(result, "i", &ret) != 1) {
425                 ErrPrint("Invalid parameter\n");
426                 ret = LB_STATUS_ERROR_INVALID;
427         }
428
429         if (ret == 0) {
430                 handler->pd_destroyed_cb = cb;
431                 handler->pd_destroyed_cbdata = cbdata;
432         } else if (cb) {
433                 handler->is_pd_created = 0;
434                 cb(handler, ret, cbdata);
435         }
436 }
437
438 static void delete_cluster_cb(struct livebox *handler, const struct packet *result, void *data)
439 {
440         struct cb_info *info = data;
441         int ret;
442         ret_cb_t cb;
443         void *cbdata;
444
445         cb = info->cb;
446         cbdata = info->data;
447         destroy_cb_info(info);
448
449         if (!result) {
450                 ret = LB_STATUS_ERROR_FAULT;
451         } else if (packet_get(result, "i", &ret) != 1) {
452                 ret = LB_STATUS_ERROR_INVALID;
453         }
454
455         if (cb) {
456                 cb(handler, ret, cbdata);
457         }
458 }
459
460 static void delete_category_cb(struct livebox *handler, const struct packet *result, void *data)
461 {
462         struct cb_info *info = data;
463         int ret;
464         ret_cb_t cb;
465         void *cbdata;
466
467         cb = info->cb;
468         cbdata = info->data;
469         destroy_cb_info(info);
470
471         if (!result) {
472                 ret = LB_STATUS_ERROR_FAULT;
473         } else if (packet_get(result, "i", &ret) != 1) {
474                 ret = LB_STATUS_ERROR_INVALID;
475         }
476
477         if (cb) {
478                 cb(handler, ret, cbdata);
479         }
480 }
481
482 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
483 {
484         int pixmap;
485         int ret = LB_STATUS_ERROR_INVALID;
486         ret_cb_t cb;
487         void *cbdata;
488         struct cb_info *info = data;
489
490         cb = info->cb;
491         cbdata = info->data;
492         destroy_cb_info(info);
493
494         if (!result) {
495                 pixmap = 0; /* PIXMAP 0 means error */
496         } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
497                 pixmap = 0;
498         }
499
500         if (ret == LB_STATUS_ERROR_BUSY) {
501                 ret = livebox_acquire_lb_pixmap(handler, cb, cbdata);
502                 DbgPrint("Busy, Try again: %d\n", ret);
503                 /* Try again */
504         } else {
505                 if (cb) {
506                         cb(handler, pixmap, cbdata);
507                 }
508         }
509 }
510
511 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
512 {
513         int pixmap;
514         int ret;
515         ret_cb_t cb;
516         void *cbdata;
517         struct cb_info *info = data;
518
519         cb = info->cb;
520         cbdata = info->data;
521         destroy_cb_info(info);
522
523         if (!result) {
524                 pixmap = 0; /* PIXMAP 0 means error */
525                 ret = LB_STATUS_ERROR_FAULT;
526         } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
527                 pixmap = 0;
528                 ret = LB_STATUS_ERROR_INVALID;
529         }
530
531         if (ret == LB_STATUS_ERROR_BUSY) {
532                 ret = livebox_acquire_pd_pixmap(handler, cb, cbdata);
533                 DbgPrint("Busy, Try again: %d\n", ret);
534                 /* Try again */
535         } else {
536                 if (cb) {
537                         DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap);
538                         cb(handler, pixmap, cbdata);
539                 }
540         }
541 }
542
543 static void pinup_done_cb(struct livebox *handler, const struct packet *result, void *data)
544 {
545         int ret;
546
547         if (!result) {
548                 ret = LB_STATUS_ERROR_FAULT;
549                 goto errout;
550         } else if (packet_get(result, "i", &ret) != 1) {
551                 goto errout;
552         }
553
554         if (ret < 0) {
555                 goto errout;
556         }
557
558         return;
559
560 errout:
561         handler->pinup_cb(handler, ret, handler->pinup_cbdata);
562         handler->pinup_cb = NULL;
563         handler->pinup_cbdata = NULL;
564 }
565
566 static void access_ret_cb(struct livebox *handler, const struct packet *result, void *data)
567 {
568         int ret;
569
570         if (!result) {
571                 ret = LB_STATUS_ERROR_FAULT;
572                 return;
573         }
574
575         if (packet_get(result, "i", &ret) != 1) {
576                 ret = LB_STATUS_ERROR_INVALID;
577                 return;
578         }
579
580         if (ret != LB_STATUS_SUCCESS) {
581                 goto errout;
582         }
583
584         return;
585
586 errout:
587         handler->access_event_cb(handler, ret, handler->access_event_cbdata);
588         handler->access_event_cb = NULL;
589         handler->access_event_cbdata = NULL;
590         return;
591 }
592
593 static int send_access_event(struct livebox *handler, const char *event, int x, int y)
594 {
595         struct packet *packet;
596         double timestamp;
597
598         timestamp = util_timestamp();
599
600         packet = packet_create(event, "ssdii", handler->pkgname, handler->id, timestamp, x, y);
601         if (!packet) {
602                 ErrPrint("Failed to build packet\n");
603                 return LB_STATUS_ERROR_FAULT;
604         }
605
606         return master_rpc_async_request(handler, packet, 0, access_ret_cb, NULL);
607 }
608
609 static int send_mouse_event(struct livebox *handler, const char *event, int x, int y)
610 {
611         struct packet *packet;
612         double timestamp;
613
614         timestamp = util_timestamp();
615         packet = packet_create_noack(event, "ssdii", handler->pkgname, handler->id, timestamp, x, y);
616         if (!packet) {
617                 ErrPrint("Failed to build param\n");
618                 return LB_STATUS_ERROR_FAULT;
619         }
620
621         return master_rpc_request_only(handler, packet);
622 }
623
624 static void initialize_livebox(void *disp)
625 {
626 #if defined(FLOG)
627         char filename[BUFSIZ];
628         snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid());
629         __file_log_fp = fopen(filename, "w+t");
630         if (!__file_log_fp) {
631                 __file_log_fp = fdopen(1, "w+t");
632         }
633 #endif
634         critical_log_init("viewer");
635         livebox_service_init();
636         fb_init(disp);
637
638         client_init();
639
640         s_info.init_count++;
641 }
642
643 EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter)
644 {
645         if (s_info.init_count > 0) {
646                 s_info.init_count++;
647                 return LB_STATUS_SUCCESS;
648         }
649
650         /*!
651          * \note
652          * Some application doesn't want to use the environment value.
653          * So set them using arguments.
654          */
655         s_info.prevent_overwrite = prevent_overwrite;
656         MINIMUM_EVENT = event_filter;
657
658         initialize_livebox(disp);
659         return LB_STATUS_SUCCESS;
660 }
661
662 EAPI int livebox_init(void *disp)
663 {
664         const char *env;
665
666         if (s_info.init_count > 0) {
667                 s_info.init_count++;
668                 return LB_STATUS_SUCCESS;
669         }
670
671         env = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE");
672         if (env && !strcasecmp(env, "true")) {
673                 s_info.prevent_overwrite = 1;
674         }
675
676         env = getenv("PROVIDER_EVENT_FILTER");
677         if (env) {
678                 sscanf(env, "%lf", &MINIMUM_EVENT);
679         }
680
681         initialize_livebox(disp);
682         return LB_STATUS_SUCCESS;
683 }
684
685 EAPI int livebox_fini(void)
686 {
687         if (s_info.init_count <= 0) {
688                 ErrPrint("Doesn't initialized\n");
689                 return LB_STATUS_ERROR_INVALID;
690         }
691
692         s_info.init_count--;
693         if (s_info.init_count > 0) {
694                 ErrPrint("init count : %d\n", s_info.init_count);
695                 return LB_STATUS_SUCCESS;
696         }
697
698         client_fini();
699         fb_fini();
700         livebox_service_fini();
701         critical_log_fini();
702         return LB_STATUS_SUCCESS;
703 }
704
705 static inline char *lb_pkgname(const char *pkgname)
706 {
707         char *lb;
708
709         lb = livebox_service_pkgname(pkgname);
710         if (!lb) {
711                 if (util_validate_livebox_package(pkgname) == 0) {
712                         return strdup(pkgname);
713                 }
714         }
715
716         return lb;
717 }
718
719 /*!
720  * Just wrapping the livebox_add_with_size function.
721  */
722 EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, ret_cb_t cb, void *data)
723 {
724         return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data);
725 }
726
727 EAPI struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data)
728 {
729         struct livebox *handler;
730         struct packet *packet;
731         int ret;
732         int width = 0;
733         int height = 0;
734         struct cb_info *cbinfo;
735
736         if (!pkgname || !cluster || !category) {
737                 ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
738                                                                 pkgname, cluster, category);
739                 return NULL;
740         }
741
742         if (type != LB_SIZE_TYPE_UNKNOWN) {
743                 livebox_service_get_size(type, &width, &height);
744         }
745
746         handler = calloc(1, sizeof(*handler));
747         if (!handler) {
748                 ErrPrint("Error: %s\n", strerror(errno));
749                 return NULL;
750         }
751
752         handler->pkgname = lb_pkgname(pkgname);
753         if (!handler->pkgname) {
754                 free(handler);
755                 return NULL;
756         }
757
758         if (livebox_service_is_enabled(handler->pkgname) == 0) {
759                 DbgPrint("Livebox [%s](%s) is disabled package\n", handler->pkgname, pkgname);
760                 free(handler->pkgname);
761                 free(handler);
762                 return NULL;
763         }
764
765         if (content && strlen(content)) {
766                 handler->content = strdup(content);
767                 if (!handler->content) {
768                         ErrPrint("Error: %s\n", strerror(errno));
769                         free(handler->pkgname);
770                         free(handler);
771                         return NULL;
772                 }
773         } else {
774                 handler->content = livebox_service_content(handler->pkgname);
775         }
776
777         handler->cluster = strdup(cluster);
778         if (!handler->cluster) {
779                 ErrPrint("Error: %s\n", strerror(errno));
780                 free(handler->content);
781                 free(handler->pkgname);
782                 free(handler);
783                 return NULL;
784         }
785
786         handler->category = strdup(category);
787         if (!handler->category) {
788                 ErrPrint("Error: %s\n", strerror(errno));
789                 free(handler->cluster);
790                 free(handler->content);
791                 free(handler->pkgname);
792                 free(handler);
793                 return NULL;
794         }
795
796         if (!cb) {
797                 cb = default_create_cb;
798         }
799
800         /* Data provider will set this */
801         handler->lb.type = _LB_TYPE_FILE;
802         handler->pd.type = _PD_TYPE_SCRIPT;
803         handler->lb.period = period;
804
805         /* Used for handling the mouse event on a box */
806         handler->lb.mouse_event = livebox_service_mouse_event(handler->pkgname);
807
808         /* Cluster infomration is not determined yet */
809         handler->nr_of_sizes = 0x01;
810
811         handler->timestamp = util_timestamp();
812         handler->is_user = 1;
813         handler->visible = LB_SHOW;
814
815         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
816
817         packet = packet_create("new", "dssssdii", handler->timestamp, handler->pkgname, handler->content, cluster, category, period, width, height);
818         if (!packet) {
819                 ErrPrint("Failed to create a new packet\n");
820                 free(handler->category);
821                 free(handler->cluster);
822                 free(handler->content);
823                 free(handler->pkgname);
824                 free(handler);
825                 return NULL;
826         }
827
828         cbinfo = create_cb_info(cb, data);
829         if (!cbinfo) {
830                 ErrPrint("Failed to create a cbinfo\n");
831                 packet_destroy(packet);
832                 free(handler->category);
833                 free(handler->cluster);
834                 free(handler->content);
835                 free(handler->pkgname);
836                 free(handler);
837                 return NULL;
838         }
839
840         ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo);
841         if (ret < 0) {
842                 ErrPrint("Failed to send a new packet\n");
843                 destroy_cb_info(cbinfo);
844                 free(handler->category);
845                 free(handler->cluster);
846                 free(handler->content);
847                 free(handler->pkgname);
848                 free(handler);
849                 return NULL;
850         }
851
852         handler->state = CREATE;
853         return lb_ref(handler);
854 }
855
856 EAPI double livebox_period(struct livebox *handler)
857 {
858         if (!handler || handler->state != CREATE || !handler->id) {
859                 ErrPrint("Handler is not valid\n");
860                 return 0.0f;
861         }
862
863         return handler->lb.period;
864 }
865
866 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
867 {
868         struct packet *packet;
869         int ret;
870
871         if (!handler || handler->state != CREATE || !handler->id) {
872                 ErrPrint("Handler is not valid\n");
873                 return LB_STATUS_ERROR_INVALID;
874         }
875
876         if (handler->period_changed_cb) {
877                 ErrPrint("Previous request for changing period is not finished\n");
878                 return LB_STATUS_ERROR_BUSY;
879         }
880
881         if (!handler->is_user) {
882                 ErrPrint("CA Livebox is not able to change the period\n");
883                 return LB_STATUS_ERROR_PERMISSION;
884         }
885
886         if (handler->lb.period == period) {
887                 DbgPrint("No changes\n");
888                 return LB_STATUS_ERROR_ALREADY;
889         }
890
891         packet = packet_create("set_period", "ssd", handler->pkgname, handler->id, period);
892         if (!packet) {
893                 ErrPrint("Failed to build a packet %s\n", handler->pkgname);
894                 return LB_STATUS_ERROR_FAULT;
895         }
896
897         if (!cb) {
898                 cb = default_period_changed_cb;
899         }
900
901         ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
902         if (ret == LB_STATUS_SUCCESS) {
903                 handler->period_changed_cb = cb;
904                 handler->period_cbdata = data;
905         }
906
907         return ret;
908 }
909
910 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
911 {
912         if (!handler) {
913                 ErrPrint("Handler is NIL\n");
914                 return LB_STATUS_ERROR_INVALID;
915         }
916
917         if (handler->state != CREATE) {
918                 ErrPrint("Handler is already deleted\n");
919                 return LB_STATUS_ERROR_INVALID;
920         }
921
922         handler->state = DELETE;
923
924         if (!handler->id) {
925                 /*!
926                  * \note
927                  * The id is not determined yet.
928                  * It means a user didn't receive created event yet.
929                  * Then just stop to delete procedure from here.
930                  * Because the "created" event handler will release this.
931                  * By the way, if the user adds any callback for getting return status of this,
932                  * call it at here.
933                  */
934                 if (cb) {
935                         cb(handler, 0, data);
936                 }
937                 return LB_STATUS_SUCCESS;
938         }
939
940         if (!cb) {
941                 cb = default_delete_cb;
942         }
943
944         return lb_send_delete(handler, cb, data);
945 }
946
947 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
948 {
949         struct fault_info *info;
950
951         if (!cb) {
952                 return LB_STATUS_ERROR_INVALID;
953         }
954
955         info = malloc(sizeof(*info));
956         if (!info) {
957                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
958                 return LB_STATUS_ERROR_MEMORY;
959         }
960
961         info->handler = cb;
962         info->user_data = data;
963
964         s_info.fault_list = dlist_append(s_info.fault_list, info);
965         return LB_STATUS_SUCCESS;
966 }
967
968 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
969 {
970         struct fault_info *info;
971         struct dlist *l;
972
973         dlist_foreach(s_info.fault_list, l, info) {
974                 if (info->handler == cb) {
975                         void *data;
976
977                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
978                         data = info->user_data;
979                         free(info);
980
981                         return data;
982                 }
983         }
984
985         return NULL;
986 }
987
988 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
989 {
990         struct event_info *info;
991
992         if (!cb) {
993                 ErrPrint("Invalid argument cb is nil\n");
994                 return LB_STATUS_ERROR_INVALID;
995         }
996
997         info = malloc(sizeof(*info));
998         if (!info) {
999                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
1000                 return LB_STATUS_ERROR_MEMORY;
1001         }
1002
1003         info->handler = cb;
1004         info->user_data = data;
1005
1006         s_info.event_list = dlist_append(s_info.event_list, info);
1007         return LB_STATUS_SUCCESS;
1008 }
1009
1010 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
1011 {
1012         struct event_info *info;
1013         struct dlist *l;
1014
1015         dlist_foreach(s_info.event_list, l, info) {
1016                 if (info->handler == cb) {
1017                         void *data;
1018
1019                         s_info.event_list = dlist_remove(s_info.event_list, l);
1020                         data = info->user_data;
1021                         free(info);
1022
1023                         return data;
1024                 }
1025         }
1026
1027         return NULL;
1028 }
1029
1030 EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data)
1031 {
1032         struct packet *packet;
1033         int ret;
1034
1035         if (!handler) {
1036                 ErrPrint("Handler is NIL\n");
1037                 return LB_STATUS_ERROR_INVALID;
1038         }
1039
1040         if (handler->state != CREATE || !handler->id) {
1041                 return LB_STATUS_ERROR_INVALID;
1042         }
1043
1044         if (handler->update_mode_cb) {
1045                 ErrPrint("Previous update_mode cb is not finished yet\n");
1046                 return LB_STATUS_ERROR_BUSY;
1047         }
1048
1049         if (handler->is_active_update == active_update) {
1050                 return LB_STATUS_ERROR_ALREADY;
1051         }
1052
1053         if (!handler->is_user) {
1054                 return LB_STATUS_ERROR_PERMISSION;
1055         }
1056
1057         packet = packet_create("update_mode", "ssi", handler->pkgname, handler->id, active_update);
1058         if (!packet) {
1059                 return LB_STATUS_ERROR_FAULT;
1060         }
1061
1062         if (!cb) {
1063                 cb = default_update_mode_cb;
1064         }
1065
1066         ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL);
1067         if (ret == LB_STATUS_SUCCESS) {
1068                 handler->update_mode_cb = cb;
1069                 handler->update_mode_cbdata = data;
1070         }
1071
1072         return ret;
1073 }
1074
1075 EAPI int livebox_is_active_update(struct livebox *handler)
1076 {
1077         if (!handler) {
1078                 ErrPrint("Handler is NIL\n");
1079                 return LB_STATUS_ERROR_INVALID;
1080         }
1081
1082         if (handler->state != CREATE || !handler->id) {
1083                 return LB_STATUS_ERROR_INVALID;
1084         }
1085
1086         return handler->is_active_update;
1087 }
1088
1089 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
1090 {
1091         struct packet *packet;
1092         int w;
1093         int h;
1094         int ret;
1095
1096         if (!handler) {
1097                 ErrPrint("Handler is NIL\n");
1098                 return LB_STATUS_ERROR_INVALID;
1099         }
1100
1101         if (handler->state != CREATE || !handler->id) {
1102                 ErrPrint("Handler is not valid\n");
1103                 return LB_STATUS_ERROR_INVALID;
1104         }
1105
1106         if (handler->size_changed_cb) {
1107                 ErrPrint("Previous resize request is not finished yet\n");
1108                 return LB_STATUS_ERROR_BUSY;
1109         }
1110
1111         if (!handler->is_user) {
1112                 ErrPrint("CA Livebox is not able to be resized\n");
1113                 return LB_STATUS_ERROR_PERMISSION;
1114         }
1115
1116         if (livebox_service_get_size(type, &w, &h) != 0) {
1117                 ErrPrint("Invalid size type\n");
1118                 return LB_STATUS_ERROR_INVALID;
1119         }
1120
1121         if (handler->lb.width == w && handler->lb.height == h) {
1122                 DbgPrint("No changes\n");
1123                 return LB_STATUS_ERROR_ALREADY;
1124         }
1125
1126         packet = packet_create("resize", "ssii", handler->pkgname, handler->id, w, h);
1127         if (!packet) {
1128                 ErrPrint("Failed to build param\n");
1129                 return LB_STATUS_ERROR_FAULT;
1130         }
1131
1132         if (!cb) {
1133                 cb = default_lb_size_changed_cb;
1134         }
1135
1136         ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
1137         if (ret == LB_STATUS_SUCCESS) {
1138                 handler->size_changed_cb = cb;
1139                 handler->size_cbdata = data;
1140         }
1141
1142         return ret;
1143 }
1144
1145 EAPI int livebox_click(struct livebox *handler, double x, double y)
1146 {
1147         struct packet *packet;
1148         double timestamp;
1149         int ret;
1150
1151         timestamp = util_timestamp();
1152
1153         if (!handler) {
1154                 ErrPrint("Handler is NIL\n");
1155                 return LB_STATUS_ERROR_INVALID;
1156         }
1157
1158         if (handler->state != CREATE || !handler->id) {
1159                 ErrPrint("Handler is not valid\n");
1160                 return LB_STATUS_ERROR_INVALID;
1161         }
1162
1163         if (handler->lb.auto_launch) {
1164                 DbgPrint("AUTO_LAUNCH [%s]\n", handler->lb.auto_launch);
1165                 if (aul_launch_app(handler->lb.auto_launch, NULL) < 0) {
1166                         ErrPrint("Failed to launch app %s\n", handler->lb.auto_launch);
1167                 }
1168         }
1169
1170         packet = packet_create_noack("clicked", "sssddd", handler->pkgname, handler->id, "clicked", timestamp, x, y);
1171         if (!packet) {
1172                 ErrPrint("Failed to build param\n");
1173                 return LB_STATUS_ERROR_FAULT;
1174         }
1175
1176         DbgPrint("CLICKED: %lf\n", timestamp);
1177         ret = master_rpc_request_only(handler, packet);
1178
1179         if (!handler->lb.mouse_event && (handler->lb.type == _LB_TYPE_BUFFER || handler->lb.type == _LB_TYPE_SCRIPT)) {
1180                 int ret; /* Shadow variable */
1181                 ret = send_mouse_event(handler, "lb_mouse_down", x * handler->lb.width, y * handler->lb.height);
1182                 if (ret < 0) {
1183                         ErrPrint("Failed to send Down: %d\n", ret);
1184                 }
1185
1186                 ret = send_mouse_event(handler, "lb_mouse_move", x * handler->lb.width, y * handler->lb.height);
1187                 if (ret < 0) {
1188                         ErrPrint("Failed to send Move: %d\n", ret);
1189                 }
1190
1191                 ret = send_mouse_event(handler, "lb_mouse_up", x * handler->lb.width, y * handler->lb.height);
1192                 if (ret < 0) {
1193                         ErrPrint("Failed to send Up: %d\n", ret);
1194                 }
1195         }
1196
1197         return ret;
1198 }
1199
1200 EAPI int livebox_has_pd(struct livebox *handler)
1201 {
1202         if (!handler) {
1203                 ErrPrint("Handler is NIL\n");
1204                 return LB_STATUS_ERROR_INVALID;
1205         }
1206
1207         if (handler->state != CREATE || !handler->id) {
1208                 ErrPrint("Handler is not valid\n");
1209                 return LB_STATUS_ERROR_INVALID;
1210         }
1211
1212         return !!handler->pd.data.fb;
1213 }
1214
1215 EAPI int livebox_pd_is_created(struct livebox *handler)
1216 {
1217         if (!handler) {
1218                 ErrPrint("Handler is NIL\n");
1219                 return LB_STATUS_ERROR_INVALID;
1220         }
1221
1222         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1223                 ErrPrint("Handler is not valid\n");
1224                 return LB_STATUS_ERROR_INVALID;
1225         }
1226
1227         return handler->is_pd_created;
1228 }
1229
1230 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
1231 {
1232         return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
1233 }
1234
1235 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
1236 {
1237         struct packet *packet;
1238         int ret;
1239
1240         if (!handler) {
1241                 ErrPrint("Handler is NIL\n");
1242                 return LB_STATUS_ERROR_INVALID;
1243         }
1244
1245         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1246                 ErrPrint("Handler is not valid\n");
1247                 return LB_STATUS_ERROR_INVALID;
1248         }
1249
1250         if (handler->is_pd_created == 1) {
1251                 DbgPrint("PD already created\n");
1252                 return LB_STATUS_SUCCESS;
1253         }
1254
1255         if (handler->pd_created_cb) {
1256                 ErrPrint("Previous request is not completed yet\n");
1257                 return LB_STATUS_ERROR_BUSY;
1258         }
1259
1260         packet = packet_create("create_pd", "ssdd", handler->pkgname, handler->id, x, y);
1261         if (!packet) {
1262                 ErrPrint("Failed to build param\n");
1263                 return LB_STATUS_ERROR_FAULT;
1264         }
1265
1266         if (!cb) {
1267                 cb = default_pd_created_cb;
1268         }
1269
1270         DbgPrint("PERF_DBOX\n");
1271         ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
1272         if (ret == LB_STATUS_SUCCESS) {
1273                 handler->pd_created_cb = cb;
1274                 handler->pd_created_cbdata = data;
1275         }
1276
1277         return ret;
1278 }
1279
1280 EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
1281 {
1282         struct packet *packet;
1283
1284         if (!handler) {
1285                 ErrPrint("Handler is NIL\n");
1286                 return LB_STATUS_ERROR_INVALID;
1287         }
1288
1289         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1290                 ErrPrint("Handler is not valid\n");
1291                 return LB_STATUS_ERROR_INVALID;
1292         }
1293
1294         if (!handler->is_pd_created) {
1295                 ErrPrint("PD is not created\n");
1296                 return LB_STATUS_ERROR_INVALID;
1297         }
1298
1299         packet = packet_create_noack("pd_move", "ssdd", handler->pkgname, handler->id, x, y);
1300         if (!packet) {
1301                 ErrPrint("Failed to build param\n");
1302                 return LB_STATUS_ERROR_FAULT;
1303         }
1304
1305         return master_rpc_request_only(handler, packet);
1306 }
1307
1308 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
1309 {
1310         struct packet *packet;
1311         struct cb_info *cbinfo;
1312         int ret;
1313
1314         if (!pkgname) {
1315                 return LB_STATUS_ERROR_INVALID;
1316         }
1317
1318         packet = packet_create("activate_package", "s", pkgname);
1319         if (!packet) {
1320                 ErrPrint("Failed to build a param\n");
1321                 return LB_STATUS_ERROR_FAULT;
1322         }
1323
1324         cbinfo = create_cb_info(cb, data);
1325         if (!cbinfo) {
1326                 ErrPrint("Unable to create cbinfo\n");
1327                 packet_destroy(packet);
1328                 return LB_STATUS_ERROR_FAULT;
1329         }
1330
1331         ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo);
1332         if (ret < 0) {
1333                 destroy_cb_info(cbinfo);
1334         }
1335
1336         return ret;
1337 }
1338
1339 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
1340 {
1341         struct packet *packet;
1342         struct cb_info *cbinfo;
1343         int ret;
1344
1345         if (!handler) {
1346                 ErrPrint("Handler is NIL\n");
1347                 return LB_STATUS_ERROR_INVALID;
1348         }
1349
1350         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1351                 ErrPrint("Handler is not valid\n");
1352                 return LB_STATUS_ERROR_INVALID;
1353         }
1354
1355         if (!handler->is_pd_created && !handler->pd_created_cb) {
1356                 ErrPrint("PD is not created\n");
1357                 return LB_STATUS_ERROR_INVALID;
1358         }
1359
1360         packet = packet_create("destroy_pd", "ss", handler->pkgname, handler->id);
1361         if (!packet) {
1362                 ErrPrint("Failed to build a param\n");
1363                 return LB_STATUS_ERROR_FAULT;
1364         }
1365
1366         if (!cb) {
1367                 cb = default_pd_destroyed_cb;
1368         }
1369
1370         cbinfo = create_cb_info(cb, data);
1371         if (!cbinfo) {
1372                 packet_destroy(packet);
1373                 return LB_STATUS_ERROR_FAULT;
1374         }
1375
1376         ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo);
1377         if (ret < 0) {
1378                 destroy_cb_info(cbinfo);
1379         }
1380
1381         return ret;
1382 }
1383
1384 EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data)
1385 {
1386         int w = 1;
1387         int h = 1;
1388         char cmd[32] = { '\0', };
1389         char *ptr = cmd;
1390         int ret;
1391
1392         if (!handler) {
1393                 ErrPrint("Handler is NIL\n");
1394                 return LB_STATUS_ERROR_INVALID;
1395         }
1396
1397         if (handler->state != CREATE || !handler->id) {
1398                 ErrPrint("Handler is not valid\n");
1399                 return LB_STATUS_ERROR_INVALID;
1400         }
1401
1402         if (handler->access_event_cb) {
1403                 ErrPrint("Previous access event is not yet done\n");
1404                 return LB_STATUS_ERROR_BUSY;
1405         }
1406
1407         if (type & ACCESS_EVENT_PD_MASK) {
1408                 if (!handler->is_pd_created) {
1409                         ErrPrint("PD is not created\n");
1410                         return LB_STATUS_ERROR_INVALID;
1411                 }
1412                 *ptr++ = 'p';
1413                 *ptr++ = 'd';
1414                 w = handler->pd.width;
1415                 h = handler->pd.height;
1416         } else if (type & ACCESS_EVENT_LB_MASK) {
1417                 *ptr++ = 'l';
1418                 *ptr++ = 'b';
1419                 w = handler->lb.width;
1420                 h = handler->lb.height;
1421         } else {
1422                 ErrPrint("Invalid event type\n");
1423                 return LB_STATUS_ERROR_INVALID;
1424         }
1425
1426         switch (type & ~ACCESS_EVENT_PD_MASK) {
1427         case ACCESS_EVENT_HIGHLIGHT:
1428                 strcpy(ptr, "_access_hl");
1429                 break;
1430         case ACCESS_EVENT_HIGHLIGHT_NEXT:
1431                 strcpy(ptr, "_access_hl_next");
1432                 break;
1433         case ACCESS_EVENT_HIGHLIGHT_PREV:
1434                 strcpy(ptr, "_access_hl_prev");
1435                 break;
1436         case ACCESS_EVENT_ACTIVATE:
1437                 strcpy(ptr, "_access_activate");
1438                 break;
1439         case ACCESS_EVENT_ACTION_DOWN:
1440                 strcpy(ptr, "_access_action_down");
1441                 break;
1442         case ACCESS_EVENT_ACTION_UP:
1443                 strcpy(ptr, "_access_action_up");
1444                 break;
1445         case ACCESS_EVENT_UNHIGHLIGHT:
1446                 strcpy(ptr, "_access_unhighlight");
1447                 break;
1448         case ACCESS_EVENT_SCROLL_DOWN:
1449                 strcpy(ptr, "_access_scroll_down");
1450                 break;
1451         case ACCESS_EVENT_SCROLL_MOVE:
1452                 strcpy(ptr, "_access_scroll_move");
1453                 break;
1454         case ACCESS_EVENT_SCROLL_UP:
1455                 strcpy(ptr, "_access_scroll_up");
1456                 break;
1457         default:
1458                 return LB_STATUS_ERROR_INVALID;
1459         }
1460
1461         if (!cb) {
1462                 cb = default_access_event_cb;
1463         }
1464
1465         ret = send_access_event(handler, cmd, x * w, y * h);
1466         if (ret == LB_STATUS_SUCCESS) {
1467                 handler->access_event_cb = cb;
1468                 handler->access_event_cbdata = data;
1469         }
1470
1471         return ret;
1472 }
1473
1474 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
1475 {
1476         int w = 1;
1477         int h = 1;
1478         char cmd[32] = { '\0', };
1479         char *ptr = cmd;
1480
1481         if (!handler) {
1482                 ErrPrint("Handler is NIL\n");
1483                 return LB_STATUS_ERROR_INVALID;
1484         }
1485
1486         if (handler->state != CREATE || !handler->id) {
1487                 ErrPrint("Handler is not valid\n");
1488                 return LB_STATUS_ERROR_INVALID;
1489         }
1490
1491         if (type & CONTENT_EVENT_PD_MASK) {
1492                 int flag = 1;
1493
1494                 if (!handler->is_pd_created) {
1495                         ErrPrint("PD is not created\n");
1496                         return LB_STATUS_ERROR_INVALID;
1497                 }
1498
1499                 if (type & CONTENT_EVENT_MOUSE_MASK) {
1500                         if (!handler->pd.data.fb) {
1501                                 ErrPrint("Handler is not valid\n");
1502                                 return LB_STATUS_ERROR_INVALID;
1503                         }
1504
1505                         if (type & CONTENT_EVENT_MOUSE_MOVE) {
1506                                 if (fabs(x - handler->pd.x) < MINIMUM_EVENT && fabs(y - handler->pd.y) < MINIMUM_EVENT) {
1507                                         return LB_STATUS_ERROR_BUSY;
1508                                 }
1509                         } else if (type & CONTENT_EVENT_MOUSE_SET) {
1510                                 flag = 0;
1511                         }
1512                 }
1513
1514                 if (flag) {
1515                         w = handler->pd.width;
1516                         h = handler->pd.height;
1517                         handler->pd.x = x;
1518                         handler->pd.y = y;
1519                 }
1520                 *ptr++ = 'p';
1521                 *ptr++ = 'd';
1522         } else if (type & CONTENT_EVENT_LB_MASK) {
1523                 int flag = 1;
1524
1525                 if (type & CONTENT_EVENT_MOUSE_MASK) {
1526                         if (!handler->lb.mouse_event) {
1527                                 return LB_STATUS_ERROR_INVALID;
1528                         }
1529
1530                         if (!handler->lb.data.fb) {
1531                                 ErrPrint("Handler is not valid\n");
1532                                 return LB_STATUS_ERROR_INVALID;
1533                         }
1534
1535                         if (type & CONTENT_EVENT_MOUSE_MOVE) {
1536                                 if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT) {
1537                                         return LB_STATUS_ERROR_BUSY;
1538                                 }
1539                         } else if (type & CONTENT_EVENT_MOUSE_SET) {
1540                                 flag = 0;
1541                         }
1542                 }
1543
1544                 if (flag) {
1545                         w = handler->lb.width;
1546                         h = handler->lb.height;
1547                         handler->lb.x = x;
1548                         handler->lb.y = y;
1549                 }
1550                 *ptr++ = 'l';
1551                 *ptr++ = 'b';
1552         } else {
1553                 ErrPrint("Invalid event type\n");
1554                 return LB_STATUS_ERROR_INVALID;
1555         }
1556
1557         /*!
1558          * Must be short than 29 bytes.
1559          */
1560         switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
1561         case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
1562                 strcpy(ptr, "_mouse_enter");
1563                 break;
1564         case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
1565                 strcpy(ptr, "_mouse_leave");
1566                 break;
1567         case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
1568                 strcpy(ptr, "_mouse_up");
1569                 break;
1570         case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
1571                 strcpy(ptr, "_mouse_down");
1572                 break;
1573         case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
1574                 strcpy(ptr, "_mouse_move");
1575                 break;
1576         case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
1577                 strcpy(ptr, "_mouse_set");
1578                 break;
1579         case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
1580                 strcpy(ptr, "_mouse_unset");
1581                 break;
1582         case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
1583                 strcpy(ptr, "_key_down");
1584                 break;
1585         case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
1586                 strcpy(ptr, "_key_up");
1587                 break;
1588         default:
1589                 ErrPrint("Invalid event type\n");
1590                 return LB_STATUS_ERROR_INVALID;
1591         }
1592
1593         return send_mouse_event(handler, cmd, x * w, y * h);
1594 }
1595
1596 EAPI const char *livebox_filename(struct livebox *handler)
1597 {
1598         if (!handler) {
1599                 ErrPrint("Handler is NIL\n");
1600                 return NULL;
1601         }
1602
1603         if (handler->state != CREATE || !handler->id) {
1604                 ErrPrint("Handler is not valid\n");
1605                 return NULL;
1606         }
1607
1608         if (handler->filename) {
1609                 return handler->filename;
1610         }
1611
1612         /* Oooops */
1613         return util_uri_to_path(handler->id);
1614 }
1615
1616 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
1617 {
1618         int _w;
1619         int _h;
1620
1621         if (!handler) {
1622                 ErrPrint("Handler is NIL\n");
1623                 return LB_STATUS_ERROR_INVALID;
1624         }
1625
1626         if (handler->state != CREATE || !handler->id) {
1627                 ErrPrint("Handler is not valid\n");
1628                 return LB_STATUS_ERROR_INVALID;
1629         }
1630
1631         if (!w) {
1632                 w = &_w;
1633         }
1634         if (!h) {
1635                 h = &_h;
1636         }
1637
1638         if (!handler->is_pd_created) {
1639                 *w = handler->pd.default_width;
1640                 *h = handler->pd.default_height;
1641         } else {
1642                 *w = handler->pd.width;
1643                 *h = handler->pd.height;
1644         }
1645
1646         return LB_STATUS_SUCCESS;
1647 }
1648
1649 EAPI int livebox_size(struct livebox *handler)
1650 {
1651         int w;
1652         int h;
1653
1654         if (!handler) {
1655                 ErrPrint("Handler is NIL\n");
1656                 return LB_STATUS_ERROR_INVALID;
1657         }
1658
1659         if (handler->state != CREATE || !handler->id) {
1660                 ErrPrint("Handler is not valid\n");
1661                 return LB_STATUS_ERROR_INVALID;
1662         }
1663
1664         w = handler->lb.width;
1665         h = handler->lb.height;
1666
1667         switch (handler->lb.type) {
1668         case _LB_TYPE_BUFFER:
1669         case _LB_TYPE_SCRIPT:
1670                 if (!fb_is_created(handler->lb.data.fb)) {
1671                         w = 0;
1672                         h = 0;
1673                 }
1674                 break;
1675         default:
1676                 break;
1677         }
1678
1679         return livebox_service_size_type(w, h);
1680 }
1681
1682 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
1683 {
1684         struct packet *packet;
1685         int ret;
1686
1687         if (!handler) {
1688                 ErrPrint("Handler is NIL\n");
1689                 return LB_STATUS_ERROR_INVALID;
1690         }
1691
1692         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1693                 ErrPrint("Invalid argument\n");
1694                 return LB_STATUS_ERROR_INVALID;
1695         }
1696
1697         if (handler->group_changed_cb) {
1698                 ErrPrint("Previous group changing request is not finished yet\n");
1699                 return LB_STATUS_ERROR_BUSY;
1700         }
1701
1702         if (!handler->is_user) {
1703                 ErrPrint("CA Livebox is not able to change the group\n");
1704                 return LB_STATUS_ERROR_PERMISSION;
1705         }
1706
1707         if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
1708                 DbgPrint("No changes\n");
1709                 return LB_STATUS_ERROR_ALREADY;
1710         }
1711
1712         packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
1713         if (!packet) {
1714                 ErrPrint("Failed to build a param\n");
1715                 return LB_STATUS_ERROR_FAULT;
1716         }
1717
1718         if (!cb) {
1719                 cb = default_group_changed_cb;
1720         }
1721
1722         ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
1723         if (ret == LB_STATUS_SUCCESS) {
1724                 handler->group_changed_cb = cb;
1725                 handler->group_cbdata = data; 
1726         }
1727
1728         return ret;
1729 }
1730
1731 EAPI int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category)
1732 {
1733         if (!handler) {
1734                 ErrPrint("Handler is NIL\n");
1735                 return LB_STATUS_ERROR_INVALID;
1736         }
1737
1738         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1739                 ErrPrint("Invalid argument\n");
1740                 return LB_STATUS_ERROR_INVALID;
1741         }
1742
1743         *cluster = handler->cluster;
1744         *category = handler->category;
1745         return LB_STATUS_SUCCESS;
1746 }
1747
1748 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
1749 {
1750         register int i;
1751         register int j;
1752
1753         if (!handler || !size_list) {
1754                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
1755                 return LB_STATUS_ERROR_INVALID;
1756         }
1757
1758         if (!cnt || handler->state != CREATE || !handler->id) {
1759                 ErrPrint("Handler is not valid\n");
1760                 return LB_STATUS_ERROR_INVALID;
1761         }
1762
1763         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
1764                 if (handler->lb.size_list & (0x01 << i)) {
1765                         if (j == *cnt) {
1766                                 break;
1767                         }
1768
1769                         size_list[j++] = (0x01 << i);
1770                 }
1771         }
1772
1773         *cnt = j;
1774         return LB_STATUS_SUCCESS;
1775 }
1776
1777 EAPI const char *livebox_pkgname(struct livebox *handler)
1778 {
1779         if (!handler) {
1780                 ErrPrint("Handler is NIL\n");
1781                 return NULL;
1782         }
1783
1784         if (handler->state != CREATE) {
1785                 ErrPrint("Handler is not valid\n");
1786                 return NULL;
1787         }
1788
1789         return handler->pkgname;
1790 }
1791
1792 EAPI double livebox_priority(struct livebox *handler)
1793 {
1794         if (!handler) {
1795                 ErrPrint("Handler is NIL\n");
1796                 return 0.0f;
1797         }
1798
1799         if (handler->state != CREATE || !handler->id) {
1800                 ErrPrint("Handler is not valid (%p)\n", handler);
1801                 return -1.0f;
1802         }
1803
1804         return handler->lb.priority;
1805 }
1806
1807 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
1808 {
1809         struct packet *packet;
1810         struct cb_info *cbinfo;
1811         int ret;
1812
1813         packet = packet_create("delete_cluster", "s", cluster);
1814         if (!packet) {
1815                 ErrPrint("Failed to build a param\n");
1816                 return LB_STATUS_ERROR_FAULT;
1817         }
1818
1819         cbinfo = create_cb_info(cb, data);
1820         if (!cbinfo) {
1821                 packet_destroy(packet);
1822                 return LB_STATUS_ERROR_FAULT;
1823         }
1824
1825         ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
1826         if (ret < 0) {
1827                 destroy_cb_info(cbinfo);
1828         }
1829
1830         return ret;
1831 }
1832
1833 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
1834 {
1835         struct packet *packet;
1836         struct cb_info *cbinfo;
1837         int ret;
1838
1839         packet = packet_create("delete_category", "ss", cluster, category);
1840         if (!packet) {
1841                 ErrPrint("Failed to build a param\n");
1842                 return LB_STATUS_ERROR_FAULT;
1843         }
1844
1845         cbinfo = create_cb_info(cb, data);
1846         if (!cbinfo) {
1847                 packet_destroy(packet);
1848                 return LB_STATUS_ERROR_FAULT;
1849         }
1850
1851         ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
1852         if (ret < 0) {
1853                 destroy_cb_info(cbinfo);
1854         }
1855
1856         return ret;
1857 }
1858
1859 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
1860 {
1861         if (!handler) {
1862                 ErrPrint("Handler is NIL\n");
1863                 return LB_TYPE_INVALID;
1864         }
1865
1866         if (handler->state != CREATE || !handler->id) {
1867                 ErrPrint("Handler is not valid\n");
1868                 return LB_TYPE_INVALID;
1869         }
1870
1871         switch (handler->lb.type) {
1872         case _LB_TYPE_FILE:
1873                 return LB_TYPE_IMAGE;
1874         case _LB_TYPE_BUFFER:
1875         case _LB_TYPE_SCRIPT:
1876                 {
1877                         const char *id;
1878                         id = fb_id(handler->lb.data.fb);
1879                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
1880                                 return LB_TYPE_PIXMAP;
1881                         }
1882                 }
1883                 return LB_TYPE_BUFFER;
1884         case _LB_TYPE_TEXT:
1885                 return LB_TYPE_TEXT;
1886         default:
1887                 break;
1888         }
1889
1890         return LB_TYPE_INVALID;
1891 }
1892
1893 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
1894 {
1895         if (!handler) {
1896                 ErrPrint("Handler is NIL\n");
1897                 return PD_TYPE_INVALID;
1898         }
1899
1900         if (handler->state != CREATE || !handler->id) {
1901                 ErrPrint("Handler is not valid\n");
1902                 return PD_TYPE_INVALID;
1903         }
1904
1905         switch (handler->pd.type) {
1906         case _PD_TYPE_TEXT:
1907                 return PD_TYPE_TEXT;
1908         case _PD_TYPE_BUFFER:
1909         case _PD_TYPE_SCRIPT:
1910                 {
1911                         const char *id;
1912                         id = fb_id(handler->pd.data.fb);
1913                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
1914                                 return PD_TYPE_PIXMAP;
1915                         }
1916                 }
1917                 return PD_TYPE_BUFFER;
1918         default:
1919                 break;
1920         }
1921
1922         return PD_TYPE_INVALID;
1923 }
1924
1925 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1926 {
1927         if (!handler) {
1928                 ErrPrint("Handler is NIL\n");
1929                 return LB_STATUS_ERROR_INVALID;
1930         }
1931
1932         if (handler->state != CREATE) {
1933                 ErrPrint("Handler is not valid\n");
1934                 return LB_STATUS_ERROR_INVALID;
1935         }
1936
1937         memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
1938         return LB_STATUS_SUCCESS;
1939 }
1940
1941 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1942 {
1943         if (!handler) {
1944                 ErrPrint("Handler is NIL\n");
1945                 return LB_STATUS_ERROR_INVALID;
1946         }
1947
1948         if (handler->state != CREATE) {
1949                 ErrPrint("Handler is not valid\n");
1950                 return LB_STATUS_ERROR_INVALID;
1951         }
1952
1953         memcpy(&handler->lb.data.ops, ops, sizeof(*ops));
1954         return LB_STATUS_SUCCESS;
1955 }
1956
1957 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1958 {
1959         struct packet *packet;
1960         struct cb_info *cbinfo;
1961         const char *id;
1962         int ret;
1963
1964         if (!handler) {
1965                 ErrPrint("Handler is NIL\n");
1966                 return LB_STATUS_ERROR_INVALID;
1967         }
1968
1969         if (handler->state != CREATE || !handler->id) {
1970                 ErrPrint("Invalid handle\n");
1971                 return LB_STATUS_ERROR_INVALID;
1972         }
1973
1974         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1975                 ErrPrint("Handler is not valid type\n");
1976                 return LB_STATUS_ERROR_INVALID;
1977         }
1978
1979         id = fb_id(handler->lb.data.fb);
1980         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
1981                 return LB_STATUS_ERROR_INVALID;
1982         }
1983
1984         packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
1985         if (!packet) {
1986                 ErrPrint("Failed to build a param\n");
1987                 return LB_STATUS_ERROR_FAULT;
1988         }
1989
1990         cbinfo = create_cb_info(cb, data);
1991         if (!cbinfo) {
1992                 packet_destroy(packet);
1993                 return LB_STATUS_ERROR_FAULT;
1994         }
1995
1996         ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo);
1997         if (ret < 0) {
1998                 destroy_cb_info(cbinfo);
1999         }
2000
2001         return ret;
2002 }
2003
2004 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
2005 {
2006         struct packet *packet;
2007
2008         if (!handler || pixmap == 0) {
2009                 ErrPrint("Handler is NIL [%d]\n", pixmap);
2010                 return LB_STATUS_ERROR_INVALID;
2011         }
2012
2013         if (handler->state != CREATE || !handler->id) {
2014                 ErrPrint("Invalid handle\n");
2015                 return LB_STATUS_ERROR_INVALID;
2016         }
2017
2018         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2019                 ErrPrint("Handler is not valid type\n");
2020                 return LB_STATUS_ERROR_INVALID;
2021         }
2022
2023         packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
2024         if (!packet) {
2025                 ErrPrint("Failed to build a param\n");
2026                 return LB_STATUS_ERROR_INVALID;
2027         }
2028
2029         return master_rpc_request_only(handler, packet);
2030 }
2031
2032 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
2033 {
2034         struct packet *packet;
2035         struct cb_info *cbinfo;
2036         const char *id;
2037         int ret;
2038
2039         if (!handler) {
2040                 ErrPrint("Handler is NIL\n");
2041                 return LB_STATUS_ERROR_INVALID;
2042         }
2043
2044         if (handler->state != CREATE || !handler->id) {
2045                 ErrPrint("Invalid handle\n");
2046                 return LB_STATUS_ERROR_INVALID;
2047         }
2048
2049         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2050                 ErrPrint("Handler is not valid type\n");
2051                 return LB_STATUS_ERROR_INVALID;
2052         }
2053
2054         id = fb_id(handler->pd.data.fb);
2055         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
2056                 return LB_STATUS_ERROR_INVALID;
2057         }
2058
2059         packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
2060         if (!packet) {
2061                 ErrPrint("Failed to build a param\n");
2062                 return LB_STATUS_ERROR_FAULT;
2063         }
2064
2065         cbinfo = create_cb_info(cb, data);
2066         if (!cbinfo) {
2067                 packet_destroy(packet);
2068                 return LB_STATUS_ERROR_FAULT;
2069         }
2070
2071         ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo);
2072         if (ret < 0) {
2073                 destroy_cb_info(cbinfo);
2074         }
2075
2076         return ret;
2077 }
2078
2079 EAPI int livebox_pd_pixmap(const struct livebox *handler)
2080 {
2081         const char *id;
2082         int pixmap = 0;
2083
2084         if (!handler) {
2085                 ErrPrint("Handler is NIL\n");
2086                 return 0;
2087         }
2088
2089         if (handler->state != CREATE || !handler->id) {
2090                 ErrPrint("Invalid handler\n");
2091                 return 0;
2092         }
2093
2094         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2095                 ErrPrint("Invalid handler\n");
2096                 return 0;
2097         }
2098
2099         id = fb_id(handler->pd.data.fb);
2100         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
2101                 ErrPrint("PIXMAP Id is not valid\n");
2102                 return 0;
2103         }
2104
2105         return pixmap;
2106 }
2107
2108 EAPI int livebox_lb_pixmap(const struct livebox *handler)
2109 {
2110         const char *id;
2111         int pixmap = 0;
2112
2113         if (!handler) {
2114                 ErrPrint("Handler is NIL\n");
2115                 return 0;
2116         }
2117
2118         if (handler->state != CREATE || !handler->id) {
2119                 ErrPrint("Invalid handler\n");
2120                 return 0;
2121         }
2122
2123         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2124                 ErrPrint("Invalid handler\n");
2125                 return 0;
2126         }
2127
2128         id = fb_id(handler->lb.data.fb);
2129         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
2130                 ErrPrint("PIXMAP Id is not valid\n");
2131                 return 0;
2132         }
2133
2134         return pixmap;
2135 }
2136
2137 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
2138 {
2139         struct packet *packet;
2140
2141         if (!handler || pixmap == 0) {
2142                 ErrPrint("Handler is NIL [%d]\n", pixmap);
2143                 return LB_STATUS_ERROR_INVALID;
2144         }
2145
2146         if (handler->state != CREATE || !handler->id) {
2147                 ErrPrint("Invalid handle\n");
2148                 return LB_STATUS_ERROR_INVALID;
2149         }
2150
2151         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2152                 ErrPrint("Handler is not valid type\n");
2153                 return LB_STATUS_ERROR_INVALID;
2154         }
2155
2156         packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
2157         if (!packet) {
2158                 ErrPrint("Failed to build a param\n");
2159                 return LB_STATUS_ERROR_FAULT;
2160         }
2161
2162         return master_rpc_request_only(handler, packet);
2163 }
2164
2165 EAPI void *livebox_acquire_fb(struct livebox *handler)
2166 {
2167         if (!handler) {
2168                 ErrPrint("Handler is NIL\n");
2169                 return NULL;
2170         }
2171
2172         if (handler->state != CREATE || !handler->id) {
2173                 ErrPrint("Invalid handle\n");
2174                 return NULL;
2175         }
2176
2177         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2178                 ErrPrint("Handler is not valid type\n");
2179                 return NULL;
2180         }
2181
2182         return fb_acquire_buffer(handler->lb.data.fb);
2183 }
2184
2185 EAPI int livebox_release_fb(void *buffer)
2186 {
2187         return fb_release_buffer(buffer);
2188 }
2189
2190 EAPI int livebox_fb_refcnt(void *buffer)
2191 {
2192         return fb_refcnt(buffer);
2193 }
2194
2195 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
2196 {
2197         if (!handler) {
2198                 ErrPrint("Handler is NIL\n");
2199                 return NULL;
2200         }
2201
2202         if (handler->state != CREATE || !handler->id) {
2203                 ErrPrint("Invalid handler\n");
2204                 return NULL;
2205         }
2206
2207         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2208                 ErrPrint("Handler is not valid type\n");
2209                 return NULL;
2210         }
2211
2212         return fb_acquire_buffer(handler->pd.data.fb);
2213 }
2214
2215 EAPI int livebox_release_pdfb(void *buffer)
2216 {
2217         return fb_release_buffer(buffer);
2218 }
2219
2220 EAPI int livebox_pdfb_refcnt(void *buffer)
2221 {
2222         return fb_refcnt(buffer);
2223 }
2224
2225 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
2226 {
2227         if (!handler) {
2228                 ErrPrint("Handler is NIL\n");
2229                 return LB_STATUS_ERROR_INVALID;
2230         }
2231
2232         if (handler->state != CREATE || !handler->id) {
2233                 ErrPrint("Handler is not valid\n");
2234                 return LB_STATUS_ERROR_INVALID;
2235         }
2236
2237         return fb_size(handler->pd.data.fb);
2238 }
2239
2240 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
2241 {
2242         if (!handler) {
2243                 ErrPrint("Handler is NIL\n");
2244                 return LB_STATUS_ERROR_INVALID;
2245         }
2246
2247         if (handler->state != CREATE || !handler->id) {
2248                 ErrPrint("Handler is not valid\n");
2249                 return LB_STATUS_ERROR_INVALID;
2250         }
2251
2252         return fb_size(handler->lb.data.fb);
2253 }
2254
2255 EAPI int livebox_is_user(struct livebox *handler)
2256 {
2257         if (!handler) {
2258                 ErrPrint("Handler is NIL\n");
2259                 return LB_STATUS_ERROR_INVALID;
2260         }
2261
2262         if (handler->state != CREATE) {
2263                 ErrPrint("Handler is invalid\n");
2264                 return LB_STATUS_ERROR_INVALID;
2265         }
2266
2267         return handler->is_user;
2268 }
2269
2270 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
2271 {
2272         struct packet *packet;
2273         int ret;
2274
2275         if (!handler) {
2276                 ErrPrint("Handler is NIL\n");
2277                 return LB_STATUS_ERROR_INVALID;
2278         }
2279
2280         if (handler->state != CREATE || !handler->id) {
2281                 ErrPrint("Handler is not valid\n");
2282                 return LB_STATUS_ERROR_INVALID;
2283         }
2284
2285         if (handler->pinup_cb) {
2286                 ErrPrint("Previous pinup request is not finished\n");
2287                 return LB_STATUS_ERROR_BUSY;
2288         }
2289
2290         if (handler->is_pinned_up == flag) {
2291                 DbgPrint("No changes\n");
2292                 return LB_STATUS_ERROR_ALREADY;
2293         }
2294
2295         packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
2296         if (!packet) {
2297                 ErrPrint("Failed to build a param\n");
2298                 return LB_STATUS_ERROR_FAULT;
2299         }
2300
2301         if (!cb) {
2302                 cb = default_pinup_cb;
2303         }
2304
2305         ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
2306         if (ret == LB_STATUS_SUCCESS) {
2307                 handler->pinup_cb = cb;
2308                 handler->pinup_cbdata = data;
2309         }
2310
2311         return ret;
2312 }
2313
2314 EAPI int livebox_is_pinned_up(struct livebox *handler)
2315 {
2316         if (!handler) {
2317                 ErrPrint("Handler is NIL\n");
2318                 return LB_STATUS_ERROR_INVALID;
2319         }
2320
2321         if (handler->state != CREATE || !handler->id) {
2322                 return LB_STATUS_ERROR_INVALID;
2323         }
2324
2325         return handler->is_pinned_up;
2326 }
2327
2328 EAPI int livebox_has_pinup(struct livebox *handler)
2329 {
2330         if (!handler) {
2331                 ErrPrint("Handler is NIL\n");
2332                 return LB_STATUS_ERROR_INVALID;
2333         }
2334
2335         if (handler->state != CREATE || !handler->id) {
2336                 return LB_STATUS_ERROR_INVALID;
2337         }
2338
2339         return handler->lb.pinup_supported;
2340 }
2341
2342 EAPI int livebox_set_data(struct livebox *handler, void *data)
2343 {
2344         if (!handler) {
2345                 ErrPrint("Handler is NIL\n");
2346                 return LB_STATUS_ERROR_INVALID;
2347         }
2348
2349         if (handler->state != CREATE) {
2350                 return LB_STATUS_ERROR_INVALID;
2351         }
2352
2353         handler->data = data;
2354         return LB_STATUS_SUCCESS;
2355 }
2356
2357 EAPI void *livebox_get_data(struct livebox *handler)
2358 {
2359         if (!handler) {
2360                 ErrPrint("Handler is NIL\n");
2361                 return NULL;
2362         }
2363
2364         if (handler->state != CREATE) {
2365                 return NULL;
2366         }
2367
2368         return handler->data;
2369 }
2370
2371 EAPI int livebox_is_exists(const char *pkgname)
2372 {
2373         char *lb;
2374
2375         lb = lb_pkgname(pkgname);
2376         if (lb) {
2377                 free(lb);
2378                 return 1;
2379         }
2380
2381         return 0;
2382 }
2383
2384 EAPI const char *livebox_content(struct livebox *handler)
2385 {
2386         if (!handler) {
2387                 ErrPrint("Handler is NIL\n");
2388                 return NULL;
2389         }
2390
2391         if (handler->state != CREATE) {
2392                 return NULL;
2393         }
2394
2395         return handler->content;
2396 }
2397
2398 EAPI const char *livebox_category_title(struct livebox *handler)
2399 {
2400         if (!handler) {
2401                 ErrPrint("Handler is NIL\n");
2402                 return NULL;
2403         }
2404
2405         if (handler->state != CREATE) {
2406                 return NULL;
2407         }
2408
2409         return handler->title;
2410 }
2411
2412 EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data)
2413 {
2414         struct packet *packet;
2415         struct cb_info *cbinfo;
2416         int ret;
2417
2418         if (!handler) {
2419                 ErrPrint("Handler is NIL\n");
2420                 return LB_STATUS_ERROR_INVALID;
2421         }
2422
2423         if ((handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || handler->state != CREATE || !handler->id) {
2424                 ErrPrint("Handler is not valid\n");
2425                 return LB_STATUS_ERROR_INVALID;
2426         }
2427
2428         if (!emission) {
2429                 emission = "";
2430         }
2431
2432         if (!source) {
2433                 source = "";
2434         }
2435
2436         packet = packet_create("text_signal", "ssssdddd",
2437                                 handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
2438         if (!packet) {
2439                 ErrPrint("Failed to build a param\n");
2440                 return LB_STATUS_ERROR_FAULT;
2441         }
2442
2443         cbinfo = create_cb_info(cb, data);
2444         if (!cbinfo) {
2445                 packet_destroy(packet);
2446                 return LB_STATUS_ERROR_FAULT;
2447         }
2448
2449         ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
2450         if (ret < 0) {
2451                 destroy_cb_info(cbinfo);
2452         }
2453
2454         return ret;
2455 }
2456
2457 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
2458 {
2459         struct packet *packet;
2460
2461         /*!
2462          * \todo
2463          * Validate the group info using DB
2464          * If the group info is not valid, do not send this request
2465          */
2466
2467         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
2468         if (!packet) {
2469                 ErrPrint("Failed to create a packet\n");
2470                 return LB_STATUS_ERROR_FAULT;
2471         }
2472
2473         return master_rpc_request_only(NULL, packet);
2474 }
2475
2476 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
2477 {
2478         struct packet *packet;
2479
2480         /*!
2481          * \todo
2482          * Validate the group info using DB
2483          * If the group info is not valid, do not send this request
2484          * AND Check the subscribed or not too
2485          */
2486
2487         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
2488         if (!packet) {
2489                 ErrPrint("Failed to create a packet\n");
2490                 return LB_STATUS_ERROR_FAULT;
2491         }
2492
2493         return master_rpc_request_only(NULL, packet);
2494 }
2495
2496 EAPI int livebox_refresh(struct livebox *handler)
2497 {
2498         struct packet *packet;
2499
2500         if (!handler) {
2501                 ErrPrint("Hnalder is NIL\n");
2502                 return LB_STATUS_ERROR_INVALID;
2503         }
2504
2505         if (handler->state != CREATE || !handler->id) {
2506                 return LB_STATUS_ERROR_INVALID;
2507         }
2508
2509         packet = packet_create_noack("update", "ss", handler->pkgname, handler->id);
2510         if (!packet) {
2511                 ErrPrint("Failed to create a packet\n");
2512                 return LB_STATUS_ERROR_FAULT;
2513         }
2514
2515         return master_rpc_request_only(handler, packet);
2516 }
2517
2518 EAPI int livebox_refresh_group(const char *cluster, const char *category)
2519 {
2520         struct packet *packet;
2521
2522         if (!cluster || !category) {
2523                 ErrPrint("Invalid argument\n");
2524                 return LB_STATUS_ERROR_INVALID;
2525         }
2526
2527         packet = packet_create_noack("refresh_group", "ss", cluster, category);
2528         if (!packet) {
2529                 ErrPrint("Failed to create a packet\n");
2530                 return LB_STATUS_ERROR_FAULT;
2531         }
2532
2533         return master_rpc_request_only(NULL, packet);
2534 }
2535
2536 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
2537 {
2538         struct packet *packet;
2539         int ret;
2540
2541         if (!handler) {
2542                 ErrPrint("Handler is NIL\n");
2543                 return LB_STATUS_ERROR_INVALID;
2544         }
2545
2546         if (handler->state != CREATE || !handler->id) {
2547                 return LB_STATUS_ERROR_INVALID;
2548         }
2549
2550         if (!handler->is_user) {
2551                 /* System cluster livebox cannot be changed its visible states */
2552                 if (state == LB_HIDE_WITH_PAUSE) {
2553                         ErrPrint("CA Livebox is not able to change the visibility\n");
2554                         return LB_STATUS_ERROR_PERMISSION;
2555                 }
2556         }
2557
2558         if (handler->visible == state) {
2559                 return LB_STATUS_ERROR_ALREADY;
2560         }
2561
2562         packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
2563         if (!packet) {
2564                 ErrPrint("Failed to create a packet\n");
2565                 return LB_STATUS_ERROR_FAULT;
2566         }
2567
2568         ret = master_rpc_request_only(handler, packet);
2569         if (ret == 0) {
2570                 handler->visible = state;
2571         }
2572
2573         return ret;
2574 }
2575
2576 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
2577 {
2578         if (!handler) {
2579                 ErrPrint("Handler is NIL\n");
2580                 return LB_VISIBLE_ERROR;
2581         }
2582
2583         if (handler->state != CREATE || !handler->id) {
2584                 return LB_VISIBLE_ERROR;
2585         }
2586
2587         return handler->visible;
2588 }
2589
2590 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
2591 {
2592         void *pc = NULL;
2593         void *ps = NULL;
2594
2595         if (cluster) {
2596                 pc = strdup(cluster);
2597                 if (!pc) {
2598                         CRITICAL_LOG("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
2599                         return LB_STATUS_ERROR_MEMORY;
2600                 }
2601         }
2602
2603         if (category) {
2604                 ps = strdup(category);
2605                 if (!ps) {
2606                         CRITICAL_LOG("Heap: %s (category: %s)\n", strerror(errno), category);
2607                         free(pc);
2608                         return LB_STATUS_ERROR_MEMORY;
2609                 }
2610         }
2611
2612         if (handler->cluster) {
2613                 free(handler->cluster);
2614         }
2615
2616         if (handler->category) {
2617                 free(handler->category);
2618         }
2619
2620         handler->cluster = pc;
2621         handler->category = ps;
2622
2623         return LB_STATUS_SUCCESS;
2624 }
2625
2626 void lb_set_size(struct livebox *handler, int w, int h)
2627 {
2628         handler->lb.width = w;
2629         handler->lb.height = h;
2630 }
2631
2632 void lb_set_update_mode(struct livebox *handle, int active_mode)
2633 {
2634         handle->is_active_update = active_mode;
2635 }
2636
2637 void lb_set_pdsize(struct livebox *handler, int w, int h)
2638 {
2639         handler->pd.width = w;
2640         handler->pd.height = h;
2641 }
2642
2643 void lb_set_default_pdsize(struct livebox *handler, int w, int h)
2644 {
2645         handler->pd.default_width = w;
2646         handler->pd.default_height = h;
2647 }
2648
2649 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
2650 {
2651         struct dlist *l;
2652         struct dlist *n;
2653         struct fault_info *info;
2654
2655         dlist_foreach_safe(s_info.fault_list, l, n, info) {
2656                 if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
2657                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
2658                 }
2659         }
2660 }
2661
2662 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
2663 {
2664         struct dlist *l;
2665         struct dlist *n;
2666         struct event_info *info;
2667
2668         dlist_foreach_safe(s_info.event_list, l, n, info) {
2669                 if (info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
2670                         s_info.event_list = dlist_remove(s_info.event_list, l);
2671                 }
2672         }
2673 }
2674
2675 struct livebox *lb_find_livebox(const char *pkgname, const char *id)
2676 {
2677         struct dlist *l;
2678         struct livebox *handler;
2679
2680         dlist_foreach(s_info.livebox_list, l, handler) {
2681                 if (!handler->id) {
2682                         continue;
2683                 }
2684
2685                 if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id)) {
2686                         return handler;
2687                 }
2688         }
2689
2690         return NULL;
2691 }
2692
2693 struct livebox *lb_find_livebox_by_timestamp(double timestamp)
2694 {
2695         struct dlist *l;
2696         struct livebox *handler;
2697
2698         dlist_foreach(s_info.livebox_list, l, handler) {
2699                 if (handler->timestamp == timestamp) {
2700                         return handler;
2701                 }
2702         }
2703
2704         return NULL;
2705 }
2706
2707 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
2708 {
2709         struct livebox *handler;
2710
2711         handler = calloc(1, sizeof(*handler));
2712         if (!handler) {
2713                 ErrPrint("Failed to create a new livebox\n");
2714                 return NULL;
2715         }
2716
2717         handler->pkgname = strdup(pkgname);
2718         if (!handler->pkgname) {
2719                 ErrPrint("%s\n", strerror(errno));
2720                 free(handler);
2721                 return NULL;
2722         }
2723
2724         handler->id = strdup(id);
2725         if (!handler->id) {
2726                 ErrPrint("%s\n", strerror(errno));
2727                 free(handler->pkgname);
2728                 free(handler);
2729                 return NULL;
2730         }
2731
2732         handler->timestamp = timestamp;
2733         handler->lb.type = _LB_TYPE_FILE;
2734         handler->pd.type = _PD_TYPE_SCRIPT;
2735         handler->state = CREATE;
2736         handler->visible = LB_SHOW;
2737
2738         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
2739         lb_ref(handler);
2740         return handler;
2741 }
2742
2743 int lb_delete_all(void)
2744 {
2745         struct dlist *l;
2746         struct dlist *n;
2747         struct livebox *handler;
2748
2749         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
2750                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
2751                 lb_unref(handler);
2752         }
2753
2754         return LB_STATUS_SUCCESS;
2755 }
2756
2757 int lb_set_content(struct livebox *handler, const char *content)
2758 {
2759         if (handler->content) {
2760                 free(handler->content);
2761                 handler->content = NULL;
2762         }
2763
2764         if (content) {
2765                 handler->content = strdup(content);
2766                 if (!handler->content) {
2767                         CRITICAL_LOG("Heap: %s (content: %s)\n", strerror(errno), content);
2768                         return LB_STATUS_ERROR_MEMORY;
2769                 }
2770         }
2771
2772         return LB_STATUS_SUCCESS;
2773 }
2774
2775 int lb_set_title(struct livebox *handler, const char *title)
2776 {
2777         if (handler->title) {
2778                 free(handler->title);
2779                 handler->title = NULL;
2780         }
2781
2782         if (title) {
2783                 handler->title = strdup(title);
2784                 if (!handler->title) {
2785                         CRITICAL_LOG("Heap: %s (title: %s)\n", strerror(errno), title);
2786                         return LB_STATUS_ERROR_MEMORY;
2787                 }
2788         }
2789
2790         return LB_STATUS_SUCCESS;
2791 }
2792
2793 void lb_set_size_list(struct livebox *handler, int size_list)
2794 {
2795         handler->lb.size_list = size_list;
2796 }
2797
2798 void lb_set_auto_launch(struct livebox *handler, const char *auto_launch)
2799 {
2800         if (!strlen(auto_launch)) {
2801                 return;
2802         }
2803
2804         handler->lb.auto_launch = strdup(auto_launch);
2805         if (!handler->lb.auto_launch) {
2806                 ErrPrint("Heap: %s\n", strerror(errno));
2807         }
2808 }
2809
2810 void lb_set_priority(struct livebox *handler, double priority)
2811 {
2812         handler->lb.priority = priority;
2813 }
2814
2815 void lb_set_id(struct livebox *handler, const char *id)
2816 {
2817         if (handler->id) {
2818                 free(handler->id);
2819         }
2820
2821         handler->id = strdup(id);
2822         if (!handler->id) {
2823                 ErrPrint("Error: %s\n", strerror(errno));
2824         }
2825 }
2826
2827 void lb_set_filename(struct livebox *handler, const char *filename)
2828 {
2829         if (handler->filename) {
2830                 if (unlink(handler->filename) < 0) {
2831                         ErrPrint("unlink: %s\n", strerror(errno));
2832                 }
2833
2834                 free(handler->filename);
2835         }
2836
2837         handler->filename = strdup(filename);
2838         if (!handler->filename) {
2839                 ErrPrint("Heap: %s\n", strerror(errno));
2840                 return;
2841         }
2842 }
2843
2844 int lb_set_lb_fb(struct livebox *handler, const char *filename)
2845 {
2846         struct fb_info *fb;
2847
2848         if (!handler) {
2849                 return LB_STATUS_ERROR_INVALID;
2850         }
2851
2852         fb = handler->lb.data.fb;
2853         if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
2854                 return LB_STATUS_SUCCESS;
2855         }
2856
2857         handler->lb.data.fb = NULL;
2858
2859         if (!filename || filename[0] == '\0') {
2860                 if (fb) {
2861                         fb_destroy(fb);
2862                 }
2863                 return LB_STATUS_SUCCESS;
2864         }
2865
2866         handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
2867         if (!handler->lb.data.fb) {
2868                 ErrPrint("Faield to create a FB\n");
2869                 if (fb) {
2870                         fb_destroy(fb);
2871                 }
2872                 return LB_STATUS_ERROR_FAULT;
2873         }
2874
2875         if (fb) {
2876                 fb_destroy(fb);
2877         }
2878
2879         return LB_STATUS_SUCCESS;
2880 }
2881
2882 int lb_set_pd_fb(struct livebox *handler, const char *filename)
2883 {
2884         struct fb_info *fb;
2885
2886         if (!handler) {
2887                 return LB_STATUS_ERROR_INVALID;
2888         }
2889
2890         fb = handler->pd.data.fb;
2891         if (fb && !strcmp(fb_id(fb), filename)) {
2892                 /* BUFFER is not changed, just update the content */
2893                 return LB_STATUS_ERROR_EXIST;
2894         }
2895         handler->pd.data.fb = NULL;
2896
2897         if (!filename || filename[0] == '\0') {
2898                 if (fb) {
2899                         fb_destroy(fb);
2900                 }
2901                 return LB_STATUS_SUCCESS;
2902         }
2903
2904         handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
2905         if (!handler->pd.data.fb) {
2906                 ErrPrint("Failed to create a FB\n");
2907                 if (fb) {
2908                         fb_destroy(fb);
2909                 }
2910                 return LB_STATUS_ERROR_FAULT;
2911         }
2912
2913         if (fb) {
2914                 fb_destroy(fb);
2915         }
2916         return LB_STATUS_SUCCESS;
2917 }
2918
2919 struct fb_info *lb_get_lb_fb(struct livebox *handler)
2920 {
2921         return handler->lb.data.fb;
2922 }
2923
2924 struct fb_info *lb_get_pd_fb(struct livebox *handler)
2925 {
2926         return handler->pd.data.fb;
2927 }
2928
2929 void lb_set_user(struct livebox *handler, int user)
2930 {
2931         handler->is_user = user;
2932 }
2933
2934 void lb_set_pinup(struct livebox *handler, int pinup_supported)
2935 {
2936         handler->lb.pinup_supported = pinup_supported;
2937 }
2938
2939 void lb_set_text_lb(struct livebox *handler)
2940 {
2941         handler->lb.type = _LB_TYPE_TEXT;
2942 }
2943
2944 void lb_set_text_pd(struct livebox *handler)
2945 {
2946         handler->pd.type = _PD_TYPE_TEXT;
2947 }
2948
2949 int lb_text_lb(struct livebox *handler)
2950 {
2951         return handler->lb.type == _LB_TYPE_TEXT;
2952 }
2953
2954 int lb_text_pd(struct livebox *handler)
2955 {
2956         return handler->pd.type == _PD_TYPE_TEXT;
2957 }
2958
2959 void lb_set_period(struct livebox *handler, double period)
2960 {
2961         handler->lb.period = period;
2962 }
2963
2964 struct livebox *lb_ref(struct livebox *handler)
2965 {
2966         if (!handler) {
2967                 return NULL;
2968         }
2969
2970         handler->refcnt++;
2971         return handler;
2972 }
2973
2974 struct livebox *lb_unref(struct livebox *handler)
2975 {
2976         if (!handler) {
2977                 return NULL;
2978         }
2979
2980         handler->refcnt--;
2981         if (handler->refcnt > 0) {
2982                 return handler;
2983         }
2984
2985         if (handler->created_cb) {
2986                 handler->created_cb(handler, LB_STATUS_ERROR_FAULT, handler->created_cbdata);
2987                 handler->created_cb = NULL;
2988                 handler->created_cbdata = NULL;
2989         }
2990
2991         if (handler->deleted_cb) {
2992                 handler->deleted_cb(handler, LB_STATUS_ERROR_FAULT, handler->deleted_cbdata);
2993                 handler->deleted_cb = NULL;
2994                 handler->deleted_cbdata = NULL;
2995         }
2996
2997         if (handler->pinup_cb) {
2998                 handler->pinup_cb(handler, LB_STATUS_ERROR_FAULT, handler->pinup_cbdata);
2999                 handler->pinup_cb = NULL;
3000                 handler->pinup_cbdata = NULL;
3001         }
3002
3003         if (handler->group_changed_cb) {
3004                 handler->group_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->group_cbdata);
3005                 handler->group_changed_cb = NULL;
3006                 handler->group_cbdata = NULL;
3007         }
3008
3009         if (handler->period_changed_cb) {
3010                 handler->period_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->period_cbdata);
3011                 handler->period_changed_cb = NULL;
3012                 handler->period_cbdata = NULL;
3013         }
3014
3015         if (handler->size_changed_cb) {
3016                 handler->size_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->size_cbdata);
3017                 handler->size_changed_cb = NULL;
3018                 handler->size_cbdata = NULL;
3019         }
3020
3021         if (handler->pd_created_cb) {
3022                 handler->pd_created_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_created_cbdata);
3023                 handler->pd_created_cb = NULL;
3024                 handler->pd_created_cbdata = NULL;
3025         }
3026
3027         if (handler->pd_destroyed_cb) {
3028                 handler->pd_destroyed_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_destroyed_cbdata);
3029                 handler->pd_destroyed_cb = NULL;
3030                 handler->pd_destroyed_cbdata = NULL;
3031         }
3032
3033         if (handler->update_mode_cb) {
3034                 handler->update_mode_cb(handler, LB_STATUS_ERROR_FAULT, handler->update_mode_cbdata);
3035                 handler->update_mode_cb = NULL;
3036                 handler->update_mode_cbdata = NULL;
3037         }
3038
3039         if (handler->access_event_cb) {
3040                 handler->access_event_cb(handler, LB_ACCESS_STATUS_ERROR, handler->access_event_cbdata);
3041                 handler->access_event_cb = NULL;
3042                 handler->access_event_cbdata = NULL;
3043         }
3044
3045         if (handler->filename) {
3046                 (void)util_unlink(handler->filename);
3047         }
3048
3049         dlist_remove_data(s_info.livebox_list, handler);
3050
3051         handler->state = DESTROYED;
3052         free(handler->cluster);
3053         free(handler->category);
3054         free(handler->id);
3055         free(handler->pkgname);
3056         free(handler->filename);
3057         free(handler->lb.auto_launch);
3058
3059         if (handler->lb.data.fb) {
3060                 fb_destroy(handler->lb.data.fb);
3061                 handler->lb.data.fb = NULL;
3062         }
3063
3064         if (handler->pd.data.fb) {
3065                 fb_destroy(handler->pd.data.fb);
3066                 handler->pd.data.fb = NULL;
3067         }
3068
3069         free(handler);
3070         return NULL;
3071 }
3072
3073 int lb_send_delete(struct livebox *handler, ret_cb_t cb, void *data)
3074 {
3075         struct packet *packet;
3076         struct cb_info *cbinfo;
3077         int ret;
3078
3079         if (!cb && !!data) {
3080                 ErrPrint("Invalid argument\n");
3081                 return LB_STATUS_ERROR_INVALID;
3082         }
3083
3084         if (handler->deleted_cb) {
3085                 ErrPrint("Already in-progress\n");
3086                 return LB_STATUS_ERROR_BUSY;
3087         }
3088
3089         packet = packet_create("delete", "ss", handler->pkgname, handler->id);
3090         if (!packet) {
3091                 ErrPrint("Failed to build a param\n");
3092                 if (cb) {
3093                         cb(handler, LB_STATUS_ERROR_FAULT, data);
3094                 }
3095
3096                 return LB_STATUS_ERROR_FAULT;
3097         }
3098
3099         if (!cb) {
3100                 cb = default_delete_cb;
3101         }
3102
3103         cbinfo = create_cb_info(cb, data);
3104         if (!cbinfo) {
3105                 packet_destroy(packet);
3106                 return LB_STATUS_ERROR_FAULT;
3107         }
3108
3109         ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
3110         if (ret < 0) {
3111                 destroy_cb_info(cbinfo);
3112         }
3113
3114         return ret;
3115 }
3116
3117 EAPI int livebox_client_paused(void)
3118 {
3119         struct packet *packet;
3120
3121         packet = packet_create_noack("client_paused", "d", util_timestamp());
3122         if (!packet) {
3123                 ErrPrint("Failed to create a pause packet\n");
3124                 return LB_STATUS_ERROR_FAULT;
3125         }
3126
3127         return master_rpc_request_only(NULL, packet);
3128 }
3129
3130 EAPI int livebox_client_resumed(void)
3131 {
3132         struct packet *packet;
3133
3134         packet = packet_create_noack("client_resumed", "d", util_timestamp());
3135         if (!packet) {
3136                 ErrPrint("Failed to create a resume packet\n");
3137                 return LB_STATUS_ERROR_FAULT;
3138         }
3139
3140         return master_rpc_request_only(NULL, packet);
3141 }
3142
3143 /* End of a file */