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