Initialize the project.
[platform/framework/web/livebox-viewer.git] / src / livebox.c
1 /*
2  * Copyright 2012  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.tizenopensource.org/license
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
21 #include <math.h>
22
23 #include <aul.h>
24 #include <dlog.h>
25
26 #include <com-core_packet.h>
27 #include <packet.h>
28 #include <livebox-service.h>
29
30 #include "debug.h"
31 #include "fb.h"
32 #include "livebox.h"
33 #include "livebox_internal.h"
34 #include "dlist.h"
35 #include "util.h"
36 #include "master_rpc.h"
37 #include "client.h"
38 #include "critical_log.h"
39
40 #define EAPI __attribute__((visibility("default")))
41 #define MINIMUM_EVENT   s_info.event_filter
42
43 #if defined(FLOG)
44 FILE *__file_log_fp;
45 #endif
46
47 static struct info {
48         struct dlist *livebox_list;
49         struct dlist *event_list;
50         struct dlist *fault_list;
51         int init_count;
52         int prevent_overwrite;
53         double event_filter;
54 } s_info = {
55         .livebox_list = NULL,
56         .event_list = NULL,
57         .fault_list = NULL,
58         .init_count = 0,
59         .prevent_overwrite = 0,
60         .event_filter = 0.02f,
61 };
62
63 struct cb_info {
64         ret_cb_t cb;
65         void *data;
66 };
67
68 struct event_info {
69         int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data);
70         void *user_data;
71 };
72
73 struct fault_info {
74         int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data);
75         void *user_data;
76 };
77
78 static inline void default_create_cb(struct livebox *handler, int ret, void *data)
79 {
80         DbgPrint("Default created event handler: %d\n", ret);
81 }
82
83 static inline void default_delete_cb(struct livebox *handler, int ret, void *data)
84 {
85         DbgPrint("Default deleted event handler: %d\n", ret);
86 }
87
88 static inline void default_pinup_cb(struct livebox *handler, int ret, void *data)
89 {
90         DbgPrint("Default pinup event handler: %d\n", ret);
91 }
92
93 static inline void default_group_changed_cb(struct livebox *handler, int ret, void *data)
94 {
95         DbgPrint("Default group changed event handler: %d\n", ret);
96 }
97
98 static inline void default_period_changed_cb(struct livebox *handler, int ret, void *data)
99 {
100         DbgPrint("Default period changed event handler: %d\n", ret);
101 }
102
103 static inline void default_pd_created_cb(struct livebox *handler, int ret, void *data)
104 {
105         DbgPrint("Default PD created event handler: %d\n", ret);
106 }
107
108 static inline void default_pd_destroyed_cb(struct livebox *handler, int ret, void *data)
109 {
110         DbgPrint("Default PD destroyed event handler: %d\n", ret);
111 }
112
113 static inline struct cb_info *create_cb_info(ret_cb_t cb, void *data)
114 {
115         struct cb_info *info;
116
117         info = malloc(sizeof(*info));
118         if (!info) {
119                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
120                 return NULL;
121         }
122
123         info->cb = cb;
124         info->data = data;
125         return info;
126 }
127
128 static inline void destroy_cb_info(struct cb_info *info)
129 {
130         free(info);
131 }
132
133 static void resize_cb(struct livebox *handler, const struct packet *result, void *data)
134 {
135         int ret;
136         struct cb_info *info = data;
137         ret_cb_t cb;
138         void *cbdata;
139
140         cb = info->cb;
141         cbdata = info->data;
142         destroy_cb_info(info);
143
144         if (!result) {
145                 ret = -EFAULT;
146         } else if (packet_get(result, "i", &ret) != 1) {
147                 ErrPrint("Invalid argument\n");
148                 ret = -EINVAL;
149         }
150
151         /*!
152          * \note
153          * In case of resize request,
154          * The livebox handler will not have resized value right after this callback,
155          * It can only get the new size when it makes updates.
156          *
157          * So the user can only get the resized value(result) from the first update event
158          * after this request.
159          */
160
161         if (cb)
162                 cb(handler, ret, cbdata);
163 }
164
165 static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data)
166 {
167         int ret;
168         void *cbdata;
169         struct cb_info *info = data;
170         ret_cb_t cb;
171
172         cbdata = info->data;
173         cb = info->cb;
174         destroy_cb_info(info);
175
176         if (!result) {
177                 ret = -EFAULT;
178         } else if (packet_get(result, "i", &ret) != 1) {
179                 ErrPrint("Invalid argument\n");
180                 ret = -EINVAL;
181         }
182
183         if (cb)
184                 cb(handler, ret, cbdata);
185         return;
186 }
187
188 static void set_group_ret_cb(struct livebox *handler, const struct packet *result, void *data)
189 {
190         int ret;
191         void *cbdata;
192         ret_cb_t cb;
193         struct cb_info *info = data;
194
195         cbdata = info->data;
196         cb = info->cb;
197         destroy_cb_info(info);
198
199         if (!result) {
200                 ret = -EFAULT;
201         } else if (packet_get(result, "i", &ret) != 1) {
202                 ErrPrint("Invalid argument\n");
203                 ret = -EINVAL;
204         }
205
206         if (ret == 0) { /*!< Group information is successfully changed */
207                 handler->group_changed_cb = cb;
208                 handler->group_cbdata = cbdata;
209         } else if (cb) {
210                 cb(handler, ret, cbdata);
211         }
212
213         return;
214 }
215
216 static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data)
217 {
218         struct cb_info *info = data;
219         int ret;
220         ret_cb_t cb;
221         void *cbdata;
222
223         cb = info->cb;
224         cbdata = info->data;
225         destroy_cb_info(info);
226
227         if (!result) {
228                 ret = -EFAULT;
229         } else if (packet_get(result, "i", &ret) != 1) {
230                 ErrPrint("Invalid argument\n");
231                 ret = -EINVAL;
232         }
233
234         if (ret == 0) {
235                 handler->period_changed_cb = cb;
236                 handler->period_cbdata = cbdata;
237         } else if (cb) {
238                 cb(handler, ret, cbdata);
239         }
240 }
241
242 static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data)
243 {
244         struct cb_info *info = data;
245         int ret;
246         ret_cb_t cb;
247         void *cbdata;
248
249         cb = info->cb;
250         cbdata = info->data;
251         destroy_cb_info(info);
252
253         if (!result) {
254                 ErrPrint("Connection lost?\n");
255                 ret = -EFAULT;
256         } else if (packet_get(result, "i", &ret) != 1) {
257                 ErrPrint("Invalid argument\n");
258                 ret = -EINVAL;
259         }
260
261         if (ret == 0) {
262                 DbgPrint("Returns %d (waiting deleted event)\n", ret);
263                 handler->deleted_cb = cb;
264                 handler->deleted_cbdata = cbdata;
265         } else if (cb) {
266                 cb(handler, ret, cbdata);
267         }
268
269         /*!
270          * \note
271          * Do not call the deleted callback from here.
272          * master will send the "deleted" event.
273          * Then invoke this callback.
274          *
275          * if (handler->deleted_cb)
276          *      handler->deleted_cb(handler, ret, handler->deleted_cbdata);
277          */
278 }
279
280 static void new_ret_cb(struct livebox *handler, const struct packet *result, void *data)
281 {
282         int ret;
283         struct cb_info *info = data;
284         ret_cb_t cb;
285         void *cbdata;
286
287         cb = info->cb;
288         cbdata = info->data;
289         destroy_cb_info(info);
290
291         if (!result) {
292                 ret = -EFAULT;
293         } else if (packet_get(result, "i", &ret) != 1) {
294                 ret = -EINVAL;
295         }
296
297         if (ret >= 0) {
298                 DbgPrint("new request is sent, just waiting the created event\n");
299                 handler->created_cb = cb;
300                 handler->created_cbdata = cbdata;
301
302                 /*!
303                  * \note
304                  * Don't go anymore ;)
305                  */
306                 return;
307         } else if (cb) {
308                 /*!
309                  * \note
310                  * It means the current instance is not created,
311                  * so user has to know about this.
312                  * notice it to user using "deleted" event.
313                  */
314                 cb(handler, ret, cbdata);
315         }
316
317         lb_unref(handler);
318 }
319
320 static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data)
321 {
322         struct cb_info *info = data;
323         void *cbdata;
324         ret_cb_t cb;
325         int ret;
326
327         cb = info->cb;
328         cbdata = info->data;
329         destroy_cb_info(data);
330
331         if (!result) {
332                 ret = -EFAULT;
333         } else if (packet_get(result, "i", &ret) != 1) {
334                 ret = -EINVAL;
335         }
336
337         if (ret == 0) {
338                 DbgPrint("PD Created event handler prepared\n");
339                 handler->pd_created_cb = cb;
340                 handler->pd_created_cbdata = cbdata;
341         } else if (cb) {
342                 DbgPrint("Failed to create a PD\n");
343                 cb(handler, ret, cbdata);
344         }
345 }
346
347 static void activated_cb(struct livebox *handler, const struct packet *result, void *data)
348 {
349         int ret;
350         struct cb_info *info = data;
351         void *cbdata;
352         ret_cb_t cb;
353         const char *pkgname = "";
354
355         cbdata = info->data;
356         cb = info->cb;
357         destroy_cb_info(info);
358
359         if (!result) {
360                 ret = -EFAULT;
361         } else if (packet_get(result, "is", &ret, &pkgname) != 2) {
362                 ret = -EINVAL;
363         }
364
365         if (cb)
366                 cb(handler, ret, cbdata);
367 }
368
369 static void pd_destroy_cb(struct livebox *handler, const struct packet *result, void *data)
370 {
371         int ret;
372         ret_cb_t cb;
373         void *cbdata;
374         struct cb_info *info = data;
375
376         cbdata = info->data;
377         cb = info->cb;
378         destroy_cb_info(info);
379
380         if (!result) {
381                 DbgPrint("Result is NIL (may connection lost)\n");
382                 ret = -EFAULT;
383         } else if (packet_get(result, "i", &ret) != 1) {
384                 DbgPrint("Invalid parameter\n");
385                 ret = -EINVAL;
386         }
387
388         if (ret == 0) {
389                 DbgPrint("PD Destroyed callback prepared\n");
390                 handler->pd_destroyed_cb = cb;
391                 handler->pd_destroyed_cbdata = cbdata;
392         } else if (cb) {
393                 DbgPrint("PD is not desroyed (forcely reset, pd flag)\n");
394                 handler->is_pd_created = 0;
395                 cb(handler, ret, cbdata);
396         }
397 }
398
399 static void delete_cluster_cb(struct livebox *handler, const struct packet *result, void *data)
400 {
401         struct cb_info *info = data;
402         int ret;
403         ret_cb_t cb;
404         void *cbdata;
405
406         cb = info->cb;
407         cbdata = info->data;
408         destroy_cb_info(info);
409
410         if (!result) {
411                 ret = -EFAULT;
412         } else if (packet_get(result, "i", &ret) != 1) {
413                 ret = -EINVAL;
414         }
415
416         DbgPrint("Delete category returns: %d\n", ret);
417
418         if (cb)
419                 cb(handler, ret, cbdata);
420 }
421
422 static void delete_category_cb(struct livebox *handler, const struct packet *result, void *data)
423 {
424         struct cb_info *info = data;
425         int ret;
426         ret_cb_t cb;
427         void *cbdata;
428
429         cb = info->cb;
430         cbdata = info->data;
431         destroy_cb_info(info);
432
433         if (!result)
434                 ret = -EFAULT;
435         else if (packet_get(result, "i", &ret) != 1)
436                 ret = -EINVAL;
437
438         DbgPrint("Delete category returns: %d\n", ret);
439
440         if (cb)
441                 cb(handler, ret, cbdata);
442 }
443
444 static void pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
445 {
446         int ret;
447         ret_cb_t cb;
448         void *cbdata;
449         struct cb_info *info = data;
450
451         cb = info->cb;
452         cbdata = info->data;
453         destroy_cb_info(info);
454
455         if (!result)
456                 ret = 0; /* PIXMAP 0 means error */
457         else if (packet_get(result, "i", &ret) != 1)
458                 ret = 0;
459
460         if (cb)
461                 cb(handler, ret, cbdata);
462 }
463
464 static void pinup_done_cb(struct livebox *handler, const struct packet *result, void *data)
465 {
466         int ret;
467         ret_cb_t cb;
468         void *cbdata;
469         struct cb_info *info = data;
470
471         cb = info->cb;
472         cbdata = info->data;
473         destroy_cb_info(info);
474
475         if (!result)
476                 ret = -EFAULT;
477         else if (packet_get(result, "i", &ret) != 1)
478                 ret = -EINVAL;
479
480         if (ret == 0) {
481                 handler->pinup_cb = cb;
482                 handler->pinup_cbdata = cbdata;
483         } else if (cb) {
484                 cb(handler, ret, cbdata);
485         }
486 }
487
488 static int send_mouse_event(struct livebox *handler, const char *event, double x, double y, int w, int h)
489 {
490         struct packet *packet;
491         double timestamp;
492
493         timestamp = util_timestamp();
494         packet = packet_create_noack(event, "ssiiddd", handler->pkgname, handler->id, w, h,
495                                                 timestamp, x, y);
496         if (!packet) {
497                 ErrPrint("Failed to build param\n");
498                 return -EFAULT;
499         }
500
501         return master_rpc_request_only(handler, packet);
502 }
503
504 EAPI int livebox_init(void *disp)
505 {
506         const char *env;
507
508         if (s_info.init_count > 0) {
509                 s_info.init_count++;
510                 return 0;
511         }
512         env = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE");
513         if (env && !strcasecmp(env, "true"))
514                 s_info.prevent_overwrite = 1;
515
516         env = getenv("PROVIDER_EVENT_FILTER");
517         if (env)
518                 sscanf(env, "%lf", &MINIMUM_EVENT);
519
520 #if defined(FLOG)
521         char filename[BUFSIZ];
522         snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid());
523         __file_log_fp = fopen(filename, "w+t");
524         if (!__file_log_fp)
525                 __file_log_fp = fdopen(1, "w+t");
526 #endif
527         critical_log_init("viewer");
528         livebox_service_init();
529         fb_init(disp);
530
531         client_init();
532
533         s_info.init_count++;
534         return 0;
535 }
536
537 EAPI int livebox_fini(void)
538 {
539         if (s_info.init_count <= 0) {
540                 DbgPrint("Didn't initialized\n");
541                 return -EINVAL;
542         }
543
544         s_info.init_count--;
545         if (s_info.init_count > 0) {
546                 DbgPrint("init count : %d\n", s_info.init_count);
547                 return 0;
548         }
549
550         client_fini();
551         fb_fini();
552         livebox_service_fini();
553         critical_log_fini();
554         return 0;
555 }
556
557 static inline char *lb_pkgname(const char *pkgname)
558 {
559         char *lb;
560
561         lb = livebox_service_pkgname(pkgname);
562         if (!lb) {
563                 if (util_validate_livebox_package(pkgname) == 0)
564                         return strdup(pkgname);
565         }
566
567         return lb;
568 }
569
570 /*!
571  * Just wrapping the livebox_add_with_size function.
572  */
573 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)
574 {
575         return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data);
576 }
577
578 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)
579 {
580         struct livebox *handler;
581         struct packet *packet;
582         int ret;
583         int width = 0;
584         int height = 0;
585
586         if (!pkgname || !cluster || !category || width < 0 || height < 0) {
587                 ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
588                                                                 pkgname, cluster, category);
589                 return NULL;
590         }
591
592         if (type != LB_SIZE_TYPE_UNKNOWN)
593                 livebox_service_get_size(type, &width, &height);
594
595         handler = calloc(1, sizeof(*handler));
596         if (!handler) {
597                 ErrPrint("Error: %s\n", strerror(errno));
598                 return NULL;
599         }
600
601         handler->pkgname = lb_pkgname(pkgname);
602         if (!handler->pkgname) {
603                 ErrPrint("Error: %s\n", strerror(errno));
604                 free(handler);
605                 return NULL;
606         }
607
608         if (content) {
609                 handler->content = strdup(content);
610                 if (!handler->content) {
611                         ErrPrint("Error: %s\n", strerror(errno));
612                         free(handler->pkgname);
613                         free(handler);
614                         return NULL;
615                 }
616         } else {
617                 handler->content = livebox_service_content(handler->pkgname);
618         }
619
620         handler->cluster = strdup(cluster);
621         if (!handler->cluster) {
622                 ErrPrint("Error: %s\n", strerror(errno));
623                 free(handler->content);
624                 free(handler->pkgname);
625                 free(handler);
626                 return NULL;
627         }
628
629         handler->category = strdup(category);
630         if (!handler->category) {
631                 ErrPrint("Error: %s\n", strerror(errno));
632                 free(handler->cluster);
633                 free(handler->content);
634                 free(handler->pkgname);
635                 free(handler);
636                 return NULL;
637         }
638
639         if (!cb)
640                 cb = default_create_cb;
641
642         /* Data provider will set this */
643         handler->lb.type = _LB_TYPE_FILE;
644         handler->pd.type = _PD_TYPE_SCRIPT;
645         handler->lb.period = period;
646
647         /* Cluster infomration is not determined yet */
648         handler->nr_of_sizes = 0x01;
649
650         handler->timestamp = util_timestamp();
651         handler->is_user = 1;
652         handler->visible = LB_SHOW;
653
654         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
655
656         packet = packet_create("new", "dssssdii", handler->timestamp, handler->pkgname, handler->content, cluster, category, period, width, height);
657         if (!packet) {
658                 ErrPrint("Failed to create a new packet\n");
659                 free(handler->category);
660                 free(handler->cluster);
661                 free(handler->content);
662                 free(handler->pkgname);
663                 free(handler);
664                 return NULL;
665         }
666
667         ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, create_cb_info(cb, data));
668         if (ret < 0) {
669                 ErrPrint("Failed to send a new packet\n");
670                 free(handler->category);
671                 free(handler->cluster);
672                 free(handler->content);
673                 free(handler->pkgname);
674                 free(handler);
675                 return NULL;
676         }
677
678         DbgPrint("Successfully sent a new request ([%lf] %s)\n", handler->timestamp, handler->pkgname);
679         handler->state = CREATE;
680         return lb_ref(handler);
681 }
682
683 EAPI double livebox_period(struct livebox *handler)
684 {
685         if (!handler || handler->state != CREATE || !handler->id) {
686                 ErrPrint("Handler is not valid\n");
687                 return 0.0f;
688         }
689
690         return handler->lb.period;
691 }
692
693 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
694 {
695         struct packet *packet;
696
697         if (!handler || handler->state != CREATE || !handler->id) {
698                 ErrPrint("Handler is not valid\n");
699                 return -EINVAL;
700         }
701
702         if (!handler->is_user) {
703                 ErrPrint("CA Livebox is not able to change the period\n");
704                 return -EPERM;
705         }
706
707         if (handler->lb.period == period) {
708                 DbgPrint("No changes\n");
709                 return -EALREADY;
710         }
711
712         packet = packet_create("set_period", "ssd", handler->pkgname, handler->id, period);
713         if (!packet) {
714                 ErrPrint("Failed to build a packet %s\n", handler->pkgname);
715                 return -EFAULT;
716         }
717
718         if (!cb)
719                 cb = default_period_changed_cb;
720
721         return master_rpc_async_request(handler, packet, 0, period_ret_cb, create_cb_info(cb, data));
722 }
723
724 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
725 {
726         if (!handler) {
727                 ErrPrint("Handler is NIL\n");
728                 return -EINVAL;
729         }
730
731         if (handler->state != CREATE) {
732                 ErrPrint("Handler is already deleted\n");
733                 return -EINVAL;
734         }
735
736         handler->state = DELETE;
737
738         if (!handler->id) {
739                 /*!
740                  * \note
741                  * The id is not determined yet.
742                  * It means a user didn't receive created event yet.
743                  * Then just stop to delete procedure from here.
744                  * Because the "created" event handler will release this.
745                  * By the way, if the user adds any callback for getting return status of this,
746                  * call it at here.
747                  */
748                 if (cb)
749                         cb(handler, 0, data);
750                 return 0;
751         }
752
753         if (!cb)
754                 cb = default_delete_cb;
755
756         return lb_send_delete(handler, cb, data);
757 }
758
759 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
760 {
761         struct fault_info *info;
762
763         if (!cb)
764                 return -EINVAL;
765
766         info = malloc(sizeof(*info));
767         if (!info) {
768                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
769                 return -ENOMEM;
770         }
771
772         info->handler = cb;
773         info->user_data = data;
774
775         s_info.fault_list = dlist_append(s_info.fault_list, info);
776         return 0;
777 }
778
779 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
780 {
781         struct fault_info *info;
782         struct dlist *l;
783
784         dlist_foreach(s_info.fault_list, l, info) {
785                 if (info->handler == cb) {
786                         void *data;
787                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
788                         data = info->user_data;
789                         free(info);
790
791                         return data;
792                 }
793         }
794
795         return NULL;
796 }
797
798 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
799 {
800         struct event_info *info;
801
802         if (!cb) {
803                 ErrPrint("Invalid argument cb is nil\n");
804                 return -EINVAL;
805         }
806
807         info = malloc(sizeof(*info));
808         if (!info) {
809                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
810                 return -ENOMEM;
811         }
812
813         info->handler = cb;
814         info->user_data = data;
815
816         s_info.event_list = dlist_append(s_info.event_list, info);
817         return 0;
818 }
819
820 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
821 {
822         struct event_info *info;
823         struct dlist *l;
824
825         dlist_foreach(s_info.event_list, l, info) {
826                 if (info->handler == cb) {
827                         void *data;
828
829                         s_info.event_list = dlist_remove(s_info.event_list, l);
830                         data = info->user_data;
831                         free(info);
832
833                         return data;
834                 }
835         }
836
837         return NULL;
838 }
839
840 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
841 {
842         struct packet *packet;
843         int w;
844         int h;
845
846         if (!handler) {
847                 ErrPrint("Handler is NIL\n");
848                 return -EINVAL;
849         }
850
851         if (handler->state != CREATE || !handler->id) {
852                 ErrPrint("Handler is not valid\n");
853                 return -EINVAL;
854         }
855
856         if (!handler->is_user) {
857                 ErrPrint("CA Livebox is not able to be resized\n");
858                 return -EPERM;
859         }
860
861         if (livebox_service_get_size(type, &w, &h) != 0) {
862                 ErrPrint("Invalid size type\n");
863                 return -EINVAL;
864         }
865
866         if (handler->lb.width == w && handler->lb.height == h) {
867                 DbgPrint("No changes\n");
868                 return -EALREADY;
869         }
870
871         packet = packet_create("resize", "ssii", handler->pkgname, handler->id, w, h);
872         if (!packet) {
873                 ErrPrint("Failed to build param\n");
874                 return -EFAULT;
875         }
876
877         return master_rpc_async_request(handler, packet, 0, resize_cb, create_cb_info(cb, data));
878 }
879
880 EAPI int livebox_click(struct livebox *handler, double x, double y)
881 {
882         struct packet *packet;
883         double timestamp;
884
885         if (!handler) {
886                 ErrPrint("Handler is NIL\n");
887                 return -EINVAL;
888         }
889
890         if (handler->state != CREATE || !handler->id) {
891                 ErrPrint("Handler is not valid\n");
892                 return -EINVAL;
893         }
894
895         if (handler->lb.auto_launch)
896                 if (aul_launch_app(handler->pkgname, NULL) < 0)
897                         ErrPrint("Failed to launch app %s\n", handler->pkgname);
898
899         timestamp = util_timestamp();
900         packet = packet_create_noack("clicked", "sssddd", handler->pkgname, handler->id, "clicked", timestamp, x, y);
901         if (!packet) {
902                 ErrPrint("Failed to build param\n");
903                 return -EFAULT;
904         }
905
906         return master_rpc_request_only(handler, packet);
907 }
908
909 EAPI int livebox_has_pd(struct livebox *handler)
910 {
911         if (!handler) {
912                 ErrPrint("Handler is NIL\n");
913                 return -EINVAL;
914         }
915
916         if (handler->state != CREATE || !handler->id) {
917                 ErrPrint("Handler is not valid\n");
918                 return -EINVAL;
919         }
920
921         return !!handler->pd.data.fb;
922 }
923
924 EAPI int livebox_pd_is_created(struct livebox *handler)
925 {
926         if (!handler) {
927                 ErrPrint("Handler is NIL\n");
928                 return -EINVAL;
929         }
930
931         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
932                 ErrPrint("Handler is not valid\n");
933                 return -EINVAL;
934         }
935
936         return handler->is_pd_created;
937 }
938
939 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
940 {
941         return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
942 }
943
944 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
945 {
946         struct packet *packet;
947
948         if (!handler) {
949                 ErrPrint("Handler is NIL\n");
950                 return -EINVAL;
951         }
952
953         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
954                 ErrPrint("Handler is not valid\n");
955                 return -EINVAL;
956         }
957
958         if (handler->is_pd_created == 1) {
959                 DbgPrint("PD already created\n");
960                 return 0;
961         }
962
963         packet = packet_create("create_pd", "ssdd", handler->pkgname, handler->id, x, y);
964         if (!packet) {
965                 ErrPrint("Failed to build param\n");
966                 return -EFAULT;
967         }
968
969         if (!cb)
970                 handler->pd_created_cb = default_pd_created_cb;
971
972         return master_rpc_async_request(handler, packet, 0, pd_create_cb, create_cb_info(cb, data));
973 }
974
975 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
976 {
977         struct packet *packet;
978
979         if (!pkgname)
980                 return -EINVAL;
981
982         packet = packet_create("activate_package", "s", pkgname);
983         if (!packet) {
984                 ErrPrint("Failed to build a param\n");
985                 return -EFAULT;
986         }
987
988         return master_rpc_async_request(NULL, packet, 0, activated_cb, create_cb_info(cb, data));
989 }
990
991 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
992 {
993         struct packet *packet;
994
995         if (!handler) {
996                 ErrPrint("Handler is NIL\n");
997                 return -EINVAL;
998         }
999
1000         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1001                 ErrPrint("Handler is not valid\n");
1002                 return -EINVAL;
1003         }
1004
1005         if (!handler->is_pd_created) {
1006                 ErrPrint("PD is not created\n");
1007                 return -EINVAL;
1008         }
1009
1010         packet = packet_create("destroy_pd", "ss", handler->pkgname, handler->id);
1011         if (!packet) {
1012                 ErrPrint("Failed to build a param\n");
1013                 return -EFAULT;
1014         }
1015
1016         if (!cb)
1017                 cb = default_pd_destroyed_cb;
1018
1019         return master_rpc_async_request(handler, packet, 0, pd_destroy_cb, create_cb_info(cb, data));
1020 }
1021
1022 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
1023 {
1024         int w;
1025         int h;
1026         const char *cmd;
1027
1028         if (!handler) {
1029                 ErrPrint("Handler is NIL\n");
1030                 return -EINVAL;
1031         }
1032
1033         if (handler->state != CREATE || !handler->id) {
1034                 ErrPrint("Handler is not valid\n");
1035                 return -EINVAL;
1036         }
1037
1038         switch (type) {
1039         case LB_MOUSE_DOWN:
1040                 if (!handler->lb.data.fb) {
1041                         ErrPrint("Handler is not valid\n");
1042                         return -EINVAL;
1043                 }
1044
1045                 cmd = "lb_mouse_down";
1046                 w = handler->lb.width;
1047                 h = handler->lb.height;
1048
1049                 handler->lb.x = x;
1050                 handler->lb.y = y;
1051                 break;
1052
1053         case LB_MOUSE_UP:
1054                 if (!handler->lb.data.fb) {
1055                         ErrPrint("Handler is not valid\n");
1056                         return -EINVAL;
1057                 }
1058
1059                 cmd = "lb_mouse_up";
1060                 w = handler->lb.width;
1061                 h = handler->lb.height;
1062                 break;
1063
1064         case LB_MOUSE_MOVE:
1065                 if (!handler->lb.data.fb) {
1066                         ErrPrint("Handler is not valid\n");
1067                         return -EINVAL;
1068                 }
1069
1070                 if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT)
1071                         return -EBUSY;
1072
1073                 cmd = "lb_mouse_move";
1074                 w = handler->lb.width;
1075                 h = handler->lb.height;
1076
1077                 handler->lb.x = x;
1078                 handler->lb.y = y;
1079                 break;
1080
1081         case LB_MOUSE_ENTER:
1082                 if (!handler->lb.data.fb) {
1083                         ErrPrint("Handler is not valid\n");
1084                         return -EINVAL;
1085                 }
1086
1087                 cmd = "lb_mouse_enter";
1088                 w = handler->lb.width;
1089                 h = handler->lb.height;
1090                 break;
1091
1092         case LB_MOUSE_LEAVE:
1093                 if (!handler->lb.data.fb) {
1094                         ErrPrint("Handler is not valid\n");
1095                         return -EINVAL;
1096                 }
1097
1098                 cmd = "lb_mouse_leave";
1099                 w = handler->lb.width;
1100                 h = handler->lb.height;
1101                 break;
1102
1103         case PD_MOUSE_ENTER:
1104                 if (!handler->pd.data.fb) {
1105                         ErrPrint("Handler is not valid\n");
1106                         return -EINVAL;
1107                 }
1108
1109                 cmd = "pd_mouse_enter";
1110                 w = handler->pd.width;
1111                 h = handler->pd.height;
1112                 break;
1113
1114         case PD_MOUSE_LEAVE:
1115                 if (!handler->pd.data.fb) {
1116                         ErrPrint("Handler is not valid\n");
1117                         return -EINVAL;
1118                 }
1119
1120                 cmd = "pd_mouse_leave";
1121                 w = handler->pd.width;
1122                 h = handler->pd.height;
1123                 break;
1124
1125         case PD_MOUSE_DOWN:
1126                 if (!handler->pd.data.fb) {
1127                         ErrPrint("Handler is not valid\n");
1128                         return -EINVAL;
1129                 }
1130
1131                 cmd = "pd_mouse_down";
1132                 w = handler->pd.width;
1133                 h = handler->pd.height;
1134
1135                 handler->pd.x = x;
1136                 handler->pd.y = y;
1137                 break;
1138
1139         case PD_MOUSE_MOVE:
1140                 if (!handler->pd.data.fb) {
1141                         ErrPrint("Handler is not valid\n");
1142                         return -EINVAL;
1143                 }
1144
1145                 if (fabs(x - handler->pd.x) < MINIMUM_EVENT && fabs(y - handler->pd.y) < MINIMUM_EVENT)
1146                         return -EBUSY;
1147
1148                 cmd = "pd_mouse_move";
1149                 w = handler->pd.width;
1150                 h = handler->pd.height;
1151
1152                 handler->pd.x = x;
1153                 handler->pd.y = y;
1154                 break;
1155
1156         case PD_MOUSE_UP:
1157                 if (!handler->pd.data.fb) {
1158                         ErrPrint("Handler is not valid\n");
1159                         return -EINVAL;
1160                 }
1161
1162                 cmd = "pd_mouse_up";
1163                 w = handler->pd.width;
1164                 h = handler->pd.height;
1165                 break;
1166
1167         default:
1168                 ErrPrint("Invalid event type\n");
1169                 return -EINVAL;
1170         }
1171
1172         return send_mouse_event(handler, cmd, x, y, w, h);
1173 }
1174
1175 EAPI const char *livebox_filename(struct livebox *handler)
1176 {
1177         if (!handler) {
1178                 ErrPrint("Handler is NIL\n");
1179                 return NULL;
1180         }
1181
1182         if (handler->state != CREATE || !handler->id) {
1183                 ErrPrint("Handler is not valid\n");
1184                 return NULL;
1185         }
1186
1187         if (handler->filename)
1188                 return handler->filename;
1189
1190         /* Oooops */
1191         return util_uri_to_path(handler->id);
1192 }
1193
1194 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
1195 {
1196         int _w;
1197         int _h;
1198
1199         if (!handler) {
1200                 ErrPrint("Handler is NIL\n");
1201                 return -EINVAL;
1202         }
1203
1204         if (handler->state != CREATE || !handler->id) {
1205                 ErrPrint("Handler is not valid\n");
1206                 return -EINVAL;
1207         }
1208
1209         if (!w)
1210                 w = &_w;
1211         if (!h)
1212                 h = &_h;
1213
1214         *w = handler->pd.width;
1215         *h = handler->pd.height;
1216
1217         switch (handler->pd.type) {
1218         case _PD_TYPE_BUFFER:
1219         case _PD_TYPE_SCRIPT:
1220                 if (!handler->is_pd_created) {
1221                         DbgPrint("Buffer is not created yet - reset size\n");
1222                         *w = 0;
1223                         *h = 0;
1224                 }
1225                 break;
1226         default:
1227                 break;
1228         }
1229
1230         return 0;
1231 }
1232
1233 EAPI int livebox_size(struct livebox *handler)
1234 {
1235         int w;
1236         int h;
1237
1238         if (!handler) {
1239                 ErrPrint("Handler is NIL\n");
1240                 return -EINVAL;
1241         }
1242
1243         if (handler->state != CREATE || !handler->id) {
1244                 ErrPrint("Handler is not valid\n");
1245                 return -EINVAL;
1246         }
1247
1248         w = handler->lb.width;
1249         h = handler->lb.height;
1250
1251         switch (handler->lb.type) {
1252         case _LB_TYPE_BUFFER:
1253         case _LB_TYPE_SCRIPT:
1254                 if (!fb_is_created(handler->lb.data.fb)) {
1255                         DbgPrint("Buffer is not created yet - reset size\n");
1256                         w = 0;
1257                         h = 0;
1258                 }
1259                 break;
1260         default:
1261                 break;
1262         }
1263
1264         return livebox_service_size_type(w, h);
1265 }
1266
1267 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
1268 {
1269         struct packet *packet;
1270
1271         if (!handler) {
1272                 ErrPrint("Handler is NIL\n");
1273                 return -EINVAL;
1274         }
1275
1276         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1277                 ErrPrint("Invalid argument\n");
1278                 return -EINVAL;
1279         }
1280
1281         if (!handler->is_user) {
1282                 ErrPrint("CA Livebox is not able to change the group\n");
1283                 return -EPERM;
1284         }
1285
1286         if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
1287                 DbgPrint("No changes\n");
1288                 return -EALREADY;
1289         }
1290
1291         packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
1292         if (!packet) {
1293                 ErrPrint("Failed to build a param\n");
1294                 return -EFAULT;
1295         }
1296
1297         if (!cb)
1298                 cb = default_group_changed_cb;
1299
1300         return master_rpc_async_request(handler, packet, 0, set_group_ret_cb, create_cb_info(cb, data));
1301 }
1302
1303 EAPI int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category)
1304 {
1305         if (!handler) {
1306                 ErrPrint("Handler is NIL\n");
1307                 return -EINVAL;
1308         }
1309
1310         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1311                 ErrPrint("Invalid argument\n");
1312                 return -EINVAL;
1313         }
1314
1315         *cluster = handler->cluster;
1316         *category = handler->category;
1317         return 0;
1318 }
1319
1320 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
1321 {
1322         register int i;
1323         register int j;
1324
1325         if (!handler || !size_list) {
1326                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
1327                 return -EINVAL;
1328         }
1329
1330         if (!cnt || handler->state != CREATE || !handler->id) {
1331                 ErrPrint("Handler is not valid\n");
1332                 return -EINVAL;
1333         }
1334
1335         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
1336                 if (handler->lb.size_list & (0x01 << i)) {
1337                         if (j == *cnt)
1338                                 break;
1339
1340                         size_list[j++] = (0x01 << i);
1341                 }
1342         }
1343
1344         *cnt = j;
1345         return 0;
1346 }
1347
1348 EAPI const char *livebox_pkgname(struct livebox *handler)
1349 {
1350         if (!handler) {
1351                 ErrPrint("Handler is NIL\n");
1352                 return NULL;
1353         }
1354
1355         if (handler->state != CREATE) {
1356                 ErrPrint("Handler is not valid\n");
1357                 return NULL;
1358         }
1359
1360         return handler->pkgname;
1361 }
1362
1363 EAPI double livebox_priority(struct livebox *handler)
1364 {
1365         if (!handler) {
1366                 ErrPrint("Handler is NIL\n");
1367                 return 0.0f;
1368         }
1369
1370         if (handler->state != CREATE || !handler->id) {
1371                 ErrPrint("Handler is not valid (%p)\n", handler);
1372                 return -1.0f;
1373         }
1374
1375         return handler->lb.priority;
1376 }
1377
1378 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
1379 {
1380         struct packet *packet;
1381
1382         packet = packet_create("delete_cluster", "s", cluster);
1383         if (!packet) {
1384                 ErrPrint("Failed to build a param\n");
1385                 return -EFAULT;
1386         }
1387
1388         return master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, create_cb_info(cb, data));
1389 }
1390
1391 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
1392 {
1393         struct packet *packet;
1394
1395         packet = packet_create("delete_category", "ss", cluster, category);
1396         if (!packet) {
1397                 ErrPrint("Failed to build a param\n");
1398                 return -EFAULT;
1399         }
1400
1401         return master_rpc_async_request(NULL, packet, 0, delete_category_cb, create_cb_info(cb, data));
1402 }
1403
1404 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
1405 {
1406         if (!handler) {
1407                 ErrPrint("Handler is NIL\n");
1408                 return LB_TYPE_INVALID;
1409         }
1410
1411         if (handler->state != CREATE || !handler->id) {
1412                 ErrPrint("Handler is not valid\n");
1413                 return LB_TYPE_INVALID;
1414         }
1415
1416         switch (handler->lb.type) {
1417         case _LB_TYPE_FILE:
1418                 return LB_TYPE_IMAGE;
1419         case _LB_TYPE_BUFFER:
1420         case _LB_TYPE_SCRIPT:
1421                 {
1422                         const char *id;
1423                         id = fb_id(handler->lb.data.fb);
1424                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1425                                 return LB_TYPE_PIXMAP;
1426                 }
1427                 return LB_TYPE_BUFFER;
1428         case _LB_TYPE_TEXT:
1429                 return LB_TYPE_TEXT;
1430         default:
1431                 break;
1432         }
1433
1434         return LB_TYPE_INVALID;
1435 }
1436
1437 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
1438 {
1439         if (!handler) {
1440                 ErrPrint("Handler is NIL\n");
1441                 return PD_TYPE_INVALID;
1442         }
1443
1444         if (handler->state != CREATE || !handler->id) {
1445                 ErrPrint("Handler is not valid\n");
1446                 return PD_TYPE_INVALID;
1447         }
1448
1449         switch (handler->pd.type) {
1450         case _PD_TYPE_TEXT:
1451                 return PD_TYPE_TEXT;
1452         case _PD_TYPE_BUFFER:
1453         case _PD_TYPE_SCRIPT:
1454                 {
1455                         const char *id;
1456                         id = fb_id(handler->pd.data.fb);
1457                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1458                                 return PD_TYPE_PIXMAP;
1459                 }
1460                 return PD_TYPE_BUFFER;
1461         default:
1462                 break;
1463         }
1464
1465         return PD_TYPE_INVALID;
1466 }
1467
1468 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1469 {
1470         if (!handler) {
1471                 ErrPrint("Handler is NIL\n");
1472                 return -EINVAL;
1473         }
1474
1475         if (handler->state != CREATE) {
1476                 ErrPrint("Handler is not valid\n");
1477                 return -EINVAL;
1478         }
1479
1480         memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
1481         return 0;
1482 }
1483
1484 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1485 {
1486         if (!handler) {
1487                 ErrPrint("Handler is NIL\n");
1488                 return -EINVAL;
1489         }
1490
1491         if (handler->state != CREATE) {
1492                 ErrPrint("Handler is not valid\n");
1493                 return -EINVAL;
1494         }
1495
1496         memcpy(&handler->lb.data.ops, ops, sizeof(*ops));
1497         return 0;
1498 }
1499
1500 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1501 {
1502         struct packet *packet;
1503         const char *id;
1504
1505         if (!handler) {
1506                 ErrPrint("Handler is NIL\n");
1507                 return -EINVAL;
1508         }
1509
1510         if (handler->state != CREATE || !handler->id) {
1511                 ErrPrint("Invalid handle\n");
1512                 return -EINVAL;
1513         }
1514
1515         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1516                 ErrPrint("Handler is not valid type\n");
1517                 return -EINVAL;
1518         }
1519
1520         id = fb_id(handler->lb.data.fb);
1521         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1522                 return -EINVAL;
1523
1524         packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
1525         if (!packet) {
1526                 ErrPrint("Failed to build a param\n");
1527                 return -EFAULT;
1528         }
1529
1530         return master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, create_cb_info(cb, data));
1531 }
1532
1533 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
1534 {
1535         struct packet *packet;
1536
1537         if (!handler) {
1538                 ErrPrint("Handler is NIL\n");
1539                 return -EINVAL;
1540         }
1541
1542         if (handler->state != CREATE || !handler->id) {
1543                 ErrPrint("Invalid handle\n");
1544                 return -EINVAL;
1545         }
1546
1547         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1548                 ErrPrint("Handler is not valid type\n");
1549                 return -EINVAL;
1550         }
1551
1552         packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1553         if (!packet) {
1554                 ErrPrint("Failed to build a param\n");
1555                 return -EFAULT;
1556         }
1557
1558         return master_rpc_request_only(handler, packet);
1559 }
1560
1561 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1562 {
1563         struct packet *packet;
1564         const char *id;
1565
1566         if (!handler) {
1567                 ErrPrint("Handler is NIL\n");
1568                 return -EINVAL;
1569         }
1570
1571         if (handler->state != CREATE || !handler->id) {
1572                 ErrPrint("Invalid handle\n");
1573                 return -EINVAL;
1574         }
1575
1576         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1577                 ErrPrint("Handler is not valid type\n");
1578                 return -EINVAL;
1579         }
1580
1581         id = fb_id(handler->pd.data.fb);
1582         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1583                 return -EINVAL;
1584
1585         packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
1586         if (!packet) {
1587                 ErrPrint("Failed to build a param\n");
1588                 return -EFAULT;
1589         }
1590
1591         return master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, create_cb_info(cb, data));
1592 }
1593
1594 EAPI int livebox_pd_pixmap(const struct livebox *handler)
1595 {
1596         const char *id;
1597         int pixmap = 0;
1598
1599         if (!handler) {
1600                 ErrPrint("Handler is NIL\n");
1601                 return 0;
1602         }
1603
1604         if (handler->state != CREATE || !handler->id) {
1605                 ErrPrint("Invalid handler\n");
1606                 return 0;
1607         }
1608
1609         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1610                 ErrPrint("Invalid handler\n");
1611                 return 0;
1612         }
1613
1614         id = fb_id(handler->pd.data.fb);
1615         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
1616                 ErrPrint("PIXMAP Id is not valid\n");
1617                 return 0;
1618         }
1619
1620         return pixmap;
1621 }
1622
1623 EAPI int livebox_lb_pixmap(const struct livebox *handler)
1624 {
1625         const char *id;
1626         int pixmap = 0;
1627
1628         if (!handler) {
1629                 ErrPrint("Handler is NIL\n");
1630                 return 0;
1631         }
1632
1633         if (handler->state != CREATE || !handler->id) {
1634                 ErrPrint("Invalid handler\n");
1635                 return 0;
1636         }
1637
1638         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1639                 ErrPrint("Invalid handler\n");
1640                 return 0;
1641         }
1642
1643         id = fb_id(handler->lb.data.fb);
1644         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
1645                 ErrPrint("PIXMAP Id is not valid\n");
1646                 return 0;
1647         }
1648
1649         return pixmap;
1650 }
1651
1652 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
1653 {
1654         struct packet *packet;
1655
1656         if (!handler) {
1657                 ErrPrint("Handler is NIL\n");
1658                 return -EINVAL;
1659         }
1660
1661         if (handler->state != CREATE || !handler->id) {
1662                 ErrPrint("Invalid handle\n");
1663                 return -EINVAL;
1664         }
1665
1666         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1667                 ErrPrint("Handler is not valid type\n");
1668                 return -EINVAL;
1669         }
1670
1671         packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1672         if (!packet) {
1673                 ErrPrint("Failed to build a param\n");
1674                 return -EFAULT;
1675         }
1676
1677         return master_rpc_request_only(handler, packet);
1678 }
1679
1680 EAPI void *livebox_acquire_fb(struct livebox *handler)
1681 {
1682         if (!handler) {
1683                 ErrPrint("Handler is NIL\n");
1684                 return NULL;
1685         }
1686
1687         if (handler->state != CREATE || !handler->id) {
1688                 ErrPrint("Invalid handle\n");
1689                 return NULL;
1690         }
1691
1692         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1693                 ErrPrint("Handler is not valid type\n");
1694                 return NULL;
1695         }
1696
1697         return fb_acquire_buffer(handler->lb.data.fb);
1698 }
1699
1700 EAPI int livebox_release_fb(void *buffer)
1701 {
1702         return fb_release_buffer(buffer);
1703 }
1704
1705 EAPI int livebox_fb_refcnt(void *buffer)
1706 {
1707         return fb_refcnt(buffer);
1708 }
1709
1710 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
1711 {
1712         if (!handler) {
1713                 ErrPrint("Handler is NIL\n");
1714                 return NULL;
1715         }
1716
1717         if (handler->state != CREATE || !handler->id) {
1718                 ErrPrint("Invalid handler\n");
1719                 return NULL;
1720         }
1721
1722         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1723                 ErrPrint("Handler is not valid type\n");
1724                 return NULL;
1725         }
1726
1727         return fb_acquire_buffer(handler->pd.data.fb);
1728 }
1729
1730 EAPI int livebox_release_pdfb(void *buffer)
1731 {
1732         return fb_release_buffer(buffer);
1733 }
1734
1735 EAPI int livebox_pdfb_refcnt(void *buffer)
1736 {
1737         return fb_refcnt(buffer);
1738 }
1739
1740 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
1741 {
1742         if (!handler) {
1743                 ErrPrint("Handler is NIL\n");
1744                 return -EINVAL;
1745         }
1746
1747         if (handler->state != CREATE || !handler->id) {
1748                 ErrPrint("Handler is not valid\n");
1749                 return -EINVAL;
1750         }
1751
1752         return fb_size(handler->pd.data.fb);
1753 }
1754
1755 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
1756 {
1757         if (!handler) {
1758                 ErrPrint("Handler is NIL\n");
1759                 return -EINVAL;
1760         }
1761
1762         if (handler->state != CREATE || !handler->id) {
1763                 ErrPrint("Handler is not valid\n");
1764                 return -EINVAL;
1765         }
1766
1767         return fb_size(handler->lb.data.fb);
1768 }
1769
1770 EAPI int livebox_is_user(struct livebox *handler)
1771 {
1772         if (!handler) {
1773                 ErrPrint("Handler is NIL\n");
1774                 return -EINVAL;
1775         }
1776
1777         if (handler->state != CREATE) {
1778                 ErrPrint("Handler is invalid\n");
1779                 return -EINVAL;
1780         }
1781
1782         return handler->is_user;
1783 }
1784
1785 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
1786 {
1787         struct packet *packet;
1788
1789         if (!handler) {
1790                 ErrPrint("Handler is NIL\n");
1791                 return -EINVAL;
1792         }
1793
1794         if (handler->state != CREATE || !handler->id) {
1795                 ErrPrint("Handler is not valid\n");
1796                 return -EINVAL;
1797         }
1798
1799         if (handler->is_pinned_up == flag) {
1800                 DbgPrint("No changes\n");
1801                 return -EALREADY;
1802         }
1803
1804         packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
1805         if (!packet) {
1806                 ErrPrint("Failed to build a param\n");
1807                 return -EFAULT;
1808         }
1809
1810         if (!cb)
1811                 cb = default_pinup_cb;
1812
1813         return master_rpc_async_request(handler, packet, 0, pinup_done_cb, create_cb_info(cb, data));
1814 }
1815
1816 EAPI int livebox_is_pinned_up(struct livebox *handler)
1817 {
1818         if (!handler) {
1819                 ErrPrint("Handler is NIL\n");
1820                 return -EINVAL;
1821         }
1822
1823         if (handler->state != CREATE || !handler->id)
1824                 return -EINVAL;
1825
1826         return handler->is_pinned_up;
1827 }
1828
1829 EAPI int livebox_has_pinup(struct livebox *handler)
1830 {
1831         if (!handler) {
1832                 ErrPrint("Handler is NIL\n");
1833                 return -EINVAL;
1834         }
1835
1836         if (handler->state != CREATE || !handler->id)
1837                 return -EINVAL;
1838
1839         return handler->lb.pinup_supported;
1840 }
1841
1842 EAPI int livebox_set_data(struct livebox *handler, void *data)
1843 {
1844         if (!handler) {
1845                 ErrPrint("Handler is NIL\n");
1846                 return -EINVAL;
1847         }
1848
1849         if (handler->state != CREATE)
1850                 return -EINVAL;
1851
1852         handler->data = data;
1853         return 0;
1854 }
1855
1856 EAPI void *livebox_get_data(struct livebox *handler)
1857 {
1858         if (!handler) {
1859                 ErrPrint("Handler is NIL\n");
1860                 return NULL;
1861         }
1862
1863         if (handler->state != CREATE)
1864                 return NULL;
1865
1866         return handler->data;
1867 }
1868
1869 EAPI int livebox_is_exists(const char *pkgname)
1870 {
1871         char *lb;
1872
1873         lb = lb_pkgname(pkgname);
1874         if (lb) {
1875                 free(lb);
1876                 return 1;
1877         }
1878
1879         return 0;
1880 }
1881
1882 EAPI const char *livebox_content(struct livebox *handler)
1883 {
1884         if (!handler) {
1885                 ErrPrint("Handler is NIL\n");
1886                 return NULL;
1887         }
1888
1889         if (handler->state != CREATE)
1890                 return NULL;
1891
1892         return handler->content;
1893 }
1894
1895 EAPI const char *livebox_category_title(struct livebox *handler)
1896 {
1897         if (!handler) {
1898                 ErrPrint("Handler is NIL\n");
1899                 return NULL;
1900         }
1901
1902         if (handler->state != CREATE)
1903                 return NULL;
1904
1905         return handler->title;
1906 }
1907
1908 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)
1909 {
1910         struct packet *packet;
1911
1912         if (!handler) {
1913                 ErrPrint("Handler is NIL\n");
1914                 return -EINVAL;
1915         }
1916
1917         if ((handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || handler->state != CREATE || !handler->id) {
1918                 ErrPrint("Handler is not valid\n");
1919                 return -EINVAL;
1920         }
1921
1922         if (!emission)
1923                 emission = "";
1924
1925         if (!source)
1926                 source = "";
1927
1928         packet = packet_create("text_signal", "ssssdddd",
1929                                 handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
1930         if (!packet) {
1931                 ErrPrint("Failed to build a param\n");
1932                 return -EFAULT;
1933         }
1934
1935         return master_rpc_async_request(handler, packet, 0, text_signal_cb, create_cb_info(cb, data));
1936 }
1937
1938 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
1939 {
1940         struct packet *packet;
1941
1942         /*!
1943          * \TODO
1944          * Validate the group info using DB
1945          * If the group info is not valid, do not send this request
1946          */
1947
1948         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
1949         if (!packet) {
1950                 ErrPrint("Failed to create a packet\n");
1951                 return -EFAULT;
1952         }
1953
1954         return master_rpc_request_only(NULL, packet);
1955 }
1956
1957 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
1958 {
1959         struct packet *packet;
1960
1961         /*!
1962          * \TODO
1963          * Validate the group info using DB
1964          * If the group info is not valid, do not send this request
1965          * AND Check the subscribed or not too
1966          */
1967
1968         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
1969         if (!packet) {
1970                 ErrPrint("Failed to create a packet\n");
1971                 return -EFAULT;
1972         }
1973
1974         return master_rpc_request_only(NULL, packet);
1975 }
1976
1977 EAPI int livebox_refresh_group(const char *cluster, const char *category)
1978 {
1979         struct packet *packet;
1980
1981         if (!cluster || !category) {
1982                 ErrPrint("Invalid argument\n");
1983                 return -EINVAL;
1984         }
1985
1986         packet = packet_create_noack("refresh_group", "ss", cluster, category);
1987         if (!packet) {
1988                 ErrPrint("Failed to create a packet\n");
1989                 return -EFAULT;
1990         }
1991
1992         return master_rpc_request_only(NULL, packet);
1993 }
1994
1995 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
1996 {
1997         struct packet *packet;
1998         int ret;
1999
2000         if (!handler) {
2001                 ErrPrint("Handler is NIL\n");
2002                 return -EINVAL;
2003         }
2004
2005         if (handler->state != CREATE || !handler->id)
2006                 return -EINVAL;
2007
2008         if (!handler->is_user) {
2009                 /* System cluster livebox cannot be changed its visible states */
2010                 if (state == LB_HIDE_WITH_PAUSE) {
2011                         ErrPrint("CA Livebox is not able to change the visibility\n");
2012                         return -EPERM;
2013                 }
2014         }
2015
2016         if (handler->visible == state)
2017                 return 0;
2018
2019         packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
2020         if (!packet) {
2021                 ErrPrint("Failed to create a packet\n");
2022                 return -EFAULT;
2023         }
2024
2025         ret = master_rpc_request_only(handler, packet);
2026         if (ret == 0)
2027                 handler->visible = state;
2028
2029         return ret;
2030 }
2031
2032 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
2033 {
2034         if (!handler) {
2035                 ErrPrint("Handler is NIL\n");
2036                 return LB_VISIBLE_ERROR;
2037         }
2038
2039         if (handler->state != CREATE)
2040                 return LB_VISIBLE_ERROR;
2041
2042         return handler->visible;
2043 }
2044
2045 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
2046 {
2047         void *pc = NULL;
2048         void *ps = NULL;
2049
2050         if (cluster) {
2051                 pc = strdup(cluster);
2052                 if (!pc) {
2053                         CRITICAL_LOG("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
2054                         return -ENOMEM;
2055                 }
2056         }
2057
2058         if (category) {
2059                 ps = strdup(category);
2060                 if (!ps) {
2061                         CRITICAL_LOG("Heap: %s (category: %s)\n", strerror(errno), category);
2062                         free(pc);
2063                         return -ENOMEM;
2064                 }
2065         }
2066
2067         if (handler->cluster)
2068                 free(handler->cluster);
2069
2070         if (handler->category)
2071                 free(handler->category);
2072
2073         handler->cluster = pc;
2074         handler->category = ps;
2075
2076         return 0;
2077 }
2078
2079 void lb_set_size(struct livebox *handler, int w, int h)
2080 {
2081         handler->lb.width = w;
2082         handler->lb.height = h;
2083 }
2084
2085 void lb_set_pdsize(struct livebox *handler, int w, int h)
2086 {
2087         handler->pd.width = w;
2088         handler->pd.height = h;
2089 }
2090
2091 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
2092 {
2093         struct dlist *l;
2094         struct dlist *n;
2095         struct fault_info *info;
2096
2097         dlist_foreach_safe(s_info.fault_list, l, n, info) {
2098                 if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE)
2099                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
2100         }
2101 }
2102
2103 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
2104 {
2105         struct dlist *l;
2106         struct dlist *n;
2107         struct event_info *info;
2108
2109         dlist_foreach_safe(s_info.event_list, l, n, info) {
2110                 if (info->handler(handler, event, info->user_data) == EXIT_FAILURE)
2111                         s_info.event_list = dlist_remove(s_info.event_list, l);
2112         }
2113 }
2114
2115 struct livebox *lb_find_livebox(const char *pkgname, const char *id)
2116 {
2117         struct dlist *l;
2118         struct livebox *handler;
2119
2120         dlist_foreach(s_info.livebox_list, l, handler) {
2121                 if (!handler->id)
2122                         continue;
2123
2124                 if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id))
2125                         return handler;
2126         }
2127
2128         return NULL;
2129 }
2130
2131 struct livebox *lb_find_livebox_by_timestamp(double timestamp)
2132 {
2133         struct dlist *l;
2134         struct livebox *handler;
2135
2136         dlist_foreach(s_info.livebox_list, l, handler) {
2137                 if (handler->timestamp == timestamp)
2138                         return handler;
2139         }
2140
2141         return NULL;
2142 }
2143
2144 static inline char *get_file_kept_in_safe(const char *id)
2145 {
2146         const char *path;
2147         char *new_path;
2148         int len;
2149         int base_idx;
2150
2151         path = util_uri_to_path(id);
2152         if (!path) {
2153                 ErrPrint("Invalid URI(%s)\n", id);
2154                 return NULL;
2155         }
2156
2157         /*!
2158          * \TODO: REMOVE ME
2159          */
2160         if (s_info.prevent_overwrite) {
2161                 new_path = strdup(path);
2162                 if (!new_path)
2163                         ErrPrint("Heap: %s\n", strerror(errno));
2164
2165                 return new_path;
2166         }
2167
2168
2169         len = strlen(path);
2170         base_idx = len - 1;
2171
2172         while (base_idx > 0 && path[base_idx] != '/') base_idx--;
2173         base_idx += (path[base_idx] == '/');
2174
2175         new_path = malloc(len + 10);
2176         if (!new_path) {
2177                 ErrPrint("Heap: %s\n", strerror(errno));
2178                 return NULL;
2179         }
2180
2181         strncpy(new_path, path, base_idx);
2182         snprintf(new_path + base_idx, len + 10 - base_idx, "reader/%s", path + base_idx);
2183         return new_path;
2184 }
2185
2186 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
2187 {
2188         struct livebox *handler;
2189
2190         handler = calloc(1, sizeof(*handler));
2191         if (!handler) {
2192                 ErrPrint("Failed to create a new livebox\n");
2193                 return NULL;
2194         }
2195
2196         handler->pkgname = strdup(pkgname);
2197         if (!handler->pkgname) {
2198                 ErrPrint("%s\n", strerror(errno));
2199                 free(handler);
2200                 return NULL;
2201         }
2202
2203         handler->id = strdup(id);
2204         if (!handler->id) {
2205                 ErrPrint("%s\n", strerror(errno));
2206                 free(handler->pkgname);
2207                 free(handler);
2208                 return NULL;
2209         }
2210
2211         handler->filename = get_file_kept_in_safe(id);
2212         if (!handler->filename) {
2213                 handler->filename = strdup(util_uri_to_path(id));
2214                 if (!handler->filename)
2215                         ErrPrint("Error: %s\n", strerror(errno));
2216         }
2217
2218         handler->timestamp = timestamp;
2219         handler->lb.type = _LB_TYPE_FILE;
2220         handler->pd.type = _PD_TYPE_SCRIPT;
2221         handler->state = CREATE;
2222         handler->visible = LB_SHOW;
2223
2224         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
2225         lb_ref(handler);
2226         return handler;
2227 }
2228
2229 int lb_delete_all(void)
2230 {
2231         struct dlist *l;
2232         struct dlist *n;
2233         struct livebox *handler;
2234
2235         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
2236                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
2237                 lb_unref(handler);
2238         }
2239
2240         return 0;
2241 }
2242
2243 int lb_set_content(struct livebox *handler, const char *content)
2244 {
2245         if (handler->content) {
2246                 free(handler->content);
2247                 handler->content = NULL;
2248         }
2249
2250         if (content) {
2251                 handler->content = strdup(content);
2252                 if (!handler->content) {
2253                         CRITICAL_LOG("Heap: %s (content: %s)\n", strerror(errno), content);
2254                         return -ENOMEM;
2255                 }
2256         }
2257
2258         return 0;
2259 }
2260
2261 int lb_set_title(struct livebox *handler, const char *title)
2262 {
2263         if (handler->title) {
2264                 free(handler->title);
2265                 handler->title = NULL;
2266         }
2267
2268         if (title) {
2269                 handler->title = strdup(title);
2270                 if (!handler->title) {
2271                         CRITICAL_LOG("Heap: %s (title: %s)\n", strerror(errno), title);
2272                         return -ENOMEM;
2273                 }
2274         }
2275
2276         return 0;
2277 }
2278
2279 void lb_set_size_list(struct livebox *handler, int size_list)
2280 {
2281         handler->lb.size_list = size_list;
2282 }
2283
2284 void lb_set_auto_launch(struct livebox *handler, int auto_launch)
2285 {
2286         handler->lb.auto_launch = auto_launch;
2287 }
2288
2289 void lb_set_priority(struct livebox *handler, double priority)
2290 {
2291         handler->lb.priority = priority;
2292 }
2293
2294 void lb_set_id(struct livebox *handler, const char *id)
2295 {
2296         if (handler->id)
2297                 free(handler->id);
2298
2299         handler->id = strdup(id);
2300         if (!handler->id)
2301                 ErrPrint("Error: %s\n", strerror(errno));
2302
2303         if (handler->filename)
2304                 free(handler->filename);
2305
2306         handler->filename = get_file_kept_in_safe(id);
2307         if (!handler->filename) {
2308                 handler->filename = strdup(util_uri_to_path(id));
2309                 if (!handler->filename)
2310                         ErrPrint("Error: %s\n", strerror(errno));
2311         }
2312 }
2313
2314 int lb_set_lb_fb(struct livebox *handler, const char *filename)
2315 {
2316         struct fb_info *fb;
2317
2318         if (!handler)
2319                 return -EINVAL;
2320
2321         fb = handler->lb.data.fb;
2322         if (fb && !strcmp(fb_id(fb), filename)) /*!< BUFFER is not changed, */
2323                 return 0;
2324
2325         handler->lb.data.fb = NULL;
2326
2327         if (!filename || filename[0] == '\0') {
2328                 if (fb)
2329                         fb_destroy(fb);
2330                 return 0;
2331         }
2332
2333         handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
2334         if (!handler->lb.data.fb) {
2335                 ErrPrint("Faield to create a FB\n");
2336                 if (fb)
2337                         fb_destroy(fb);
2338                 return -EFAULT;
2339         }
2340
2341         if (fb)
2342                 fb_destroy(fb);
2343
2344         return 0;
2345 }
2346
2347 int lb_set_pd_fb(struct livebox *handler, const char *filename)
2348 {
2349         struct fb_info *fb;
2350
2351         if (!handler)
2352                 return -EINVAL;
2353
2354         fb = handler->pd.data.fb;
2355         if (fb && !strcmp(fb_id(fb), filename)) {
2356                 /* BUFFER is not changed, just update the content */
2357                 return -EEXIST;
2358         }
2359         handler->pd.data.fb = NULL;
2360
2361         if (!filename || filename[0] == '\0') {
2362                 if (fb)
2363                         fb_destroy(fb);
2364                 return 0;
2365         }
2366
2367         handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
2368         if (!handler->pd.data.fb) {
2369                 ErrPrint("Failed to create a FB\n");
2370                 if (fb)
2371                         fb_destroy(fb);
2372                 return -EFAULT;
2373         }
2374
2375         if (fb)
2376                 fb_destroy(fb);
2377         return 0;
2378 }
2379
2380 struct fb_info *lb_get_lb_fb(struct livebox *handler)
2381 {
2382         return handler->lb.data.fb;
2383 }
2384
2385 struct fb_info *lb_get_pd_fb(struct livebox *handler)
2386 {
2387         return handler->pd.data.fb;
2388 }
2389
2390 void lb_set_user(struct livebox *handler, int user)
2391 {
2392         handler->is_user = user;
2393 }
2394
2395 void lb_set_pinup(struct livebox *handler, int pinup_supported)
2396 {
2397         handler->lb.pinup_supported = pinup_supported;
2398 }
2399
2400 void lb_set_text_lb(struct livebox *handler)
2401 {
2402         handler->lb.type = _LB_TYPE_TEXT;
2403 }
2404
2405 void lb_set_text_pd(struct livebox *handler)
2406 {
2407         handler->pd.type = _PD_TYPE_TEXT;
2408 }
2409
2410 int lb_text_lb(struct livebox *handler)
2411 {
2412         return handler->lb.type == _LB_TYPE_TEXT;
2413 }
2414
2415 int lb_text_pd(struct livebox *handler)
2416 {
2417         return handler->pd.type == _PD_TYPE_TEXT;
2418 }
2419
2420 void lb_set_period(struct livebox *handler, double period)
2421 {
2422         handler->lb.period = period;
2423 }
2424
2425 struct livebox *lb_ref(struct livebox *handler)
2426 {
2427         if (!handler)
2428                 return NULL;
2429
2430         handler->refcnt++;
2431         return handler;
2432 }
2433
2434 struct livebox *lb_unref(struct livebox *handler)
2435 {
2436         if (!handler)
2437                 return NULL;
2438
2439         handler->refcnt--;
2440         if (handler->refcnt > 0)
2441                 return handler;
2442
2443         dlist_remove_data(s_info.livebox_list, handler);
2444
2445         handler->state = DESTROYED;
2446         free(handler->cluster);
2447         free(handler->category);
2448         free(handler->id);
2449         free(handler->pkgname);
2450         free(handler->filename);
2451
2452         if (handler->lb.data.fb) {
2453                 fb_destroy(handler->lb.data.fb);
2454                 handler->lb.data.fb = NULL;
2455         }
2456
2457         if (handler->pd.data.fb) {
2458                 fb_destroy(handler->pd.data.fb);
2459                 handler->pd.data.fb = NULL;
2460         }
2461
2462         free(handler);
2463         return NULL;
2464 }
2465
2466 int lb_send_delete(struct livebox *handler, ret_cb_t cb, void *data)
2467 {
2468         struct packet *packet;
2469
2470         if (!cb && !!data) {
2471                 ErrPrint("Invalid argument\n");
2472                 return -EINVAL;
2473         }
2474
2475         if (handler->deleted_cb) {
2476                 ErrPrint("Already in-progress\n");
2477                 return -EINPROGRESS;
2478         }
2479
2480         packet = packet_create("delete", "ss", handler->pkgname, handler->id);
2481         if (!packet) {
2482                 ErrPrint("Failed to build a param\n");
2483                 if (cb)
2484                         cb(handler, -EFAULT, data);
2485
2486                 return -EFAULT;
2487         }
2488
2489         if (!cb)
2490                 cb = default_delete_cb;
2491
2492         return master_rpc_async_request(handler, packet, 0, del_ret_cb, create_cb_info(cb, data));
2493 }
2494
2495 /* End of a file */