Add livebox update interface.
[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 __attribute__((always_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         /* Used for handling the mouse event on a box */
648         handler->lb.mouse_event = livebox_service_mouse_event(handler->pkgname);
649
650         /* Cluster infomration is not determined yet */
651         handler->nr_of_sizes = 0x01;
652
653         handler->timestamp = util_timestamp();
654         handler->is_user = 1;
655         handler->visible = LB_SHOW;
656
657         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
658
659         packet = packet_create("new", "dssssdii", handler->timestamp, handler->pkgname, handler->content, cluster, category, period, width, height);
660         if (!packet) {
661                 ErrPrint("Failed to create a new packet\n");
662                 free(handler->category);
663                 free(handler->cluster);
664                 free(handler->content);
665                 free(handler->pkgname);
666                 free(handler);
667                 return NULL;
668         }
669
670         ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, create_cb_info(cb, data));
671         if (ret < 0) {
672                 ErrPrint("Failed to send a new packet\n");
673                 free(handler->category);
674                 free(handler->cluster);
675                 free(handler->content);
676                 free(handler->pkgname);
677                 free(handler);
678                 return NULL;
679         }
680
681         DbgPrint("Successfully sent a new request ([%lf] %s)\n", handler->timestamp, handler->pkgname);
682         handler->state = CREATE;
683         return lb_ref(handler);
684 }
685
686 EAPI double livebox_period(struct livebox *handler)
687 {
688         if (!handler || handler->state != CREATE || !handler->id) {
689                 ErrPrint("Handler is not valid\n");
690                 return 0.0f;
691         }
692
693         return handler->lb.period;
694 }
695
696 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
697 {
698         struct packet *packet;
699
700         if (!handler || handler->state != CREATE || !handler->id) {
701                 ErrPrint("Handler is not valid\n");
702                 return -EINVAL;
703         }
704
705         if (!handler->is_user) {
706                 ErrPrint("CA Livebox is not able to change the period\n");
707                 return -EPERM;
708         }
709
710         if (handler->lb.period == period) {
711                 DbgPrint("No changes\n");
712                 return -EALREADY;
713         }
714
715         packet = packet_create("set_period", "ssd", handler->pkgname, handler->id, period);
716         if (!packet) {
717                 ErrPrint("Failed to build a packet %s\n", handler->pkgname);
718                 return -EFAULT;
719         }
720
721         if (!cb)
722                 cb = default_period_changed_cb;
723
724         return master_rpc_async_request(handler, packet, 0, period_ret_cb, create_cb_info(cb, data));
725 }
726
727 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
728 {
729         if (!handler) {
730                 ErrPrint("Handler is NIL\n");
731                 return -EINVAL;
732         }
733
734         if (handler->state != CREATE) {
735                 ErrPrint("Handler is already deleted\n");
736                 return -EINVAL;
737         }
738
739         handler->state = DELETE;
740
741         if (!handler->id) {
742                 /*!
743                  * \note
744                  * The id is not determined yet.
745                  * It means a user didn't receive created event yet.
746                  * Then just stop to delete procedure from here.
747                  * Because the "created" event handler will release this.
748                  * By the way, if the user adds any callback for getting return status of this,
749                  * call it at here.
750                  */
751                 if (cb)
752                         cb(handler, 0, data);
753                 return 0;
754         }
755
756         if (!cb)
757                 cb = default_delete_cb;
758
759         return lb_send_delete(handler, cb, data);
760 }
761
762 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
763 {
764         struct fault_info *info;
765
766         if (!cb)
767                 return -EINVAL;
768
769         info = malloc(sizeof(*info));
770         if (!info) {
771                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
772                 return -ENOMEM;
773         }
774
775         info->handler = cb;
776         info->user_data = data;
777
778         s_info.fault_list = dlist_append(s_info.fault_list, info);
779         return 0;
780 }
781
782 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
783 {
784         struct fault_info *info;
785         struct dlist *l;
786
787         dlist_foreach(s_info.fault_list, l, info) {
788                 if (info->handler == cb) {
789                         void *data;
790                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
791                         data = info->user_data;
792                         free(info);
793
794                         return data;
795                 }
796         }
797
798         return NULL;
799 }
800
801 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
802 {
803         struct event_info *info;
804
805         if (!cb) {
806                 ErrPrint("Invalid argument cb is nil\n");
807                 return -EINVAL;
808         }
809
810         info = malloc(sizeof(*info));
811         if (!info) {
812                 CRITICAL_LOG("Heap: %s\n", strerror(errno));
813                 return -ENOMEM;
814         }
815
816         info->handler = cb;
817         info->user_data = data;
818
819         s_info.event_list = dlist_append(s_info.event_list, info);
820         return 0;
821 }
822
823 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
824 {
825         struct event_info *info;
826         struct dlist *l;
827
828         dlist_foreach(s_info.event_list, l, info) {
829                 if (info->handler == cb) {
830                         void *data;
831
832                         s_info.event_list = dlist_remove(s_info.event_list, l);
833                         data = info->user_data;
834                         free(info);
835
836                         return data;
837                 }
838         }
839
840         return NULL;
841 }
842
843 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
844 {
845         struct packet *packet;
846         int w;
847         int h;
848
849         if (!handler) {
850                 ErrPrint("Handler is NIL\n");
851                 return -EINVAL;
852         }
853
854         if (handler->state != CREATE || !handler->id) {
855                 ErrPrint("Handler is not valid\n");
856                 return -EINVAL;
857         }
858
859         if (!handler->is_user) {
860                 ErrPrint("CA Livebox is not able to be resized\n");
861                 return -EPERM;
862         }
863
864         if (livebox_service_get_size(type, &w, &h) != 0) {
865                 ErrPrint("Invalid size type\n");
866                 return -EINVAL;
867         }
868
869         if (handler->lb.width == w && handler->lb.height == h) {
870                 DbgPrint("No changes\n");
871                 return -EALREADY;
872         }
873
874         packet = packet_create("resize", "ssii", handler->pkgname, handler->id, w, h);
875         if (!packet) {
876                 ErrPrint("Failed to build param\n");
877                 return -EFAULT;
878         }
879
880         return master_rpc_async_request(handler, packet, 0, resize_cb, create_cb_info(cb, data));
881 }
882
883 EAPI int livebox_click(struct livebox *handler, double x, double y)
884 {
885         struct packet *packet;
886         double timestamp;
887         int ret;
888
889         if (!handler) {
890                 ErrPrint("Handler is NIL\n");
891                 return -EINVAL;
892         }
893
894         if (handler->state != CREATE || !handler->id) {
895                 ErrPrint("Handler is not valid\n");
896                 return -EINVAL;
897         }
898
899         if (handler->lb.auto_launch)
900                 if (aul_launch_app(handler->lb.auto_launch, NULL) < 0)
901                         ErrPrint("Failed to launch app %s\n", handler->lb.auto_launch);
902
903         timestamp = util_timestamp();
904         packet = packet_create_noack("clicked", "sssddd", handler->pkgname, handler->id, "clicked", timestamp, x, y);
905         if (!packet) {
906                 ErrPrint("Failed to build param\n");
907                 return -EFAULT;
908         }
909
910         ret = master_rpc_request_only(handler, packet);
911
912         if (!handler->lb.mouse_event && (handler->lb.type == _LB_TYPE_BUFFER || handler->lb.type == _LB_TYPE_SCRIPT)) {
913                 int ret; /* Shadow variable */
914                 ret = send_mouse_event(handler, "lb_mouse_down", x, y, handler->lb.width, handler->lb.height);
915                 if (ret < 0)
916                         DbgPrint("Failed to send Down: %d\n", ret);
917
918                 ret = send_mouse_event(handler, "lb_mouse_move", x, y, handler->lb.width, handler->lb.height);
919                 if (ret < 0)
920                         DbgPrint("Failed to send Move: %d\n", ret);
921
922                 ret = send_mouse_event(handler, "lb_mouse_up", x, y, handler->lb.width, handler->lb.height);
923                 if (ret < 0)
924                         DbgPrint("Failed to send Up: %d\n", ret);
925         }
926
927         return ret;
928 }
929
930 EAPI int livebox_has_pd(struct livebox *handler)
931 {
932         if (!handler) {
933                 ErrPrint("Handler is NIL\n");
934                 return -EINVAL;
935         }
936
937         if (handler->state != CREATE || !handler->id) {
938                 ErrPrint("Handler is not valid\n");
939                 return -EINVAL;
940         }
941
942         return !!handler->pd.data.fb;
943 }
944
945 EAPI int livebox_pd_is_created(struct livebox *handler)
946 {
947         if (!handler) {
948                 ErrPrint("Handler is NIL\n");
949                 return -EINVAL;
950         }
951
952         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
953                 ErrPrint("Handler is not valid\n");
954                 return -EINVAL;
955         }
956
957         return handler->is_pd_created;
958 }
959
960 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
961 {
962         return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
963 }
964
965 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
966 {
967         struct packet *packet;
968
969         if (!handler) {
970                 ErrPrint("Handler is NIL\n");
971                 return -EINVAL;
972         }
973
974         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
975                 ErrPrint("Handler is not valid\n");
976                 return -EINVAL;
977         }
978
979         if (handler->is_pd_created == 1) {
980                 DbgPrint("PD already created\n");
981                 return 0;
982         }
983
984         packet = packet_create("create_pd", "ssdd", handler->pkgname, handler->id, x, y);
985         if (!packet) {
986                 ErrPrint("Failed to build param\n");
987                 return -EFAULT;
988         }
989
990         if (!cb)
991                 handler->pd_created_cb = default_pd_created_cb;
992
993         return master_rpc_async_request(handler, packet, 0, pd_create_cb, create_cb_info(cb, data));
994 }
995
996 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
997 {
998         struct packet *packet;
999
1000         if (!pkgname)
1001                 return -EINVAL;
1002
1003         packet = packet_create("activate_package", "s", pkgname);
1004         if (!packet) {
1005                 ErrPrint("Failed to build a param\n");
1006                 return -EFAULT;
1007         }
1008
1009         return master_rpc_async_request(NULL, packet, 0, activated_cb, create_cb_info(cb, data));
1010 }
1011
1012 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
1013 {
1014         struct packet *packet;
1015
1016         if (!handler) {
1017                 ErrPrint("Handler is NIL\n");
1018                 return -EINVAL;
1019         }
1020
1021         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1022                 ErrPrint("Handler is not valid\n");
1023                 return -EINVAL;
1024         }
1025
1026         if (!handler->is_pd_created) {
1027                 ErrPrint("PD is not created\n");
1028                 return -EINVAL;
1029         }
1030
1031         packet = packet_create("destroy_pd", "ss", handler->pkgname, handler->id);
1032         if (!packet) {
1033                 ErrPrint("Failed to build a param\n");
1034                 return -EFAULT;
1035         }
1036
1037         if (!cb)
1038                 cb = default_pd_destroyed_cb;
1039
1040         return master_rpc_async_request(handler, packet, 0, pd_destroy_cb, create_cb_info(cb, data));
1041 }
1042
1043 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
1044 {
1045         int w;
1046         int h;
1047         char cmd[20] = { '\0', };
1048         char *ptr = cmd;
1049
1050         if (!handler) {
1051                 ErrPrint("Handler is NIL\n");
1052                 return -EINVAL;
1053         }
1054
1055         if (handler->state != CREATE || !handler->id) {
1056                 ErrPrint("Handler is not valid\n");
1057                 return -EINVAL;
1058         }
1059
1060         if (type & CONTENT_EVENT_PD_MASK) {
1061                 if (!handler->is_pd_created) {
1062                         ErrPrint("PD is not created\n");
1063                         return -EINVAL;
1064                 }
1065
1066                 if (type & CONTENT_EVENT_MOUSE_MASK) {
1067                         if (!handler->pd.data.fb) {
1068                                 ErrPrint("Handler is not valid\n");
1069                                 return -EINVAL;
1070                         }
1071
1072                         if (type & CONTENT_EVENT_MOUSE_MOVE) {
1073                                 if (fabs(x - handler->pd.x) < MINIMUM_EVENT && fabs(y - handler->pd.y) < MINIMUM_EVENT)
1074                                         return -EBUSY;
1075                         }
1076                 }
1077
1078                 w = handler->pd.width;
1079                 h = handler->pd.height;
1080                 handler->pd.x = x;
1081                 handler->pd.y = y;
1082                 *ptr++ = 'p';
1083                 *ptr++ = 'd';
1084         } else {
1085                 if (type & CONTENT_EVENT_MOUSE_MASK) {
1086                         if (!handler->lb.mouse_event) {
1087                                 ErrPrint("Box is not support the mouse event\n");
1088                                 return -EINVAL;
1089                         }
1090
1091                         if (!handler->lb.data.fb) {
1092                                 ErrPrint("Handler is not valid\n");
1093                                 return -EINVAL;
1094                         }
1095
1096                         if (type & CONTENT_EVENT_MOUSE_MOVE) {
1097                                 if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT)
1098                                         return -EBUSY;
1099                         }
1100                 }
1101
1102                 w = handler->lb.width;
1103                 h = handler->lb.height;
1104                 handler->lb.x = x;
1105                 handler->lb.y = y;
1106                 *ptr++ = 'l';
1107                 *ptr++ = 'b';
1108         }
1109
1110         switch ((type & ~CONTENT_EVENT_PD_MASK)) {
1111         case CONTENT_EVENT_ACCESS_READ | CONTENT_EVENT_ACCESS_MASK:
1112                 strcpy(ptr, "_access_read");
1113                 break;
1114         case CONTENT_EVENT_ACCESS_READ_PREV | CONTENT_EVENT_ACCESS_MASK:
1115                 strcpy(ptr, "_access_read_prev");
1116                 break;
1117         case CONTENT_EVENT_ACCESS_READ_NEXT | CONTENT_EVENT_ACCESS_MASK:
1118                 strcpy(ptr, "_access_read_next");
1119                 break;
1120         case CONTENT_EVENT_ACCESS_ACTIVATE | CONTENT_EVENT_ACCESS_MASK:
1121                 strcpy(ptr, "_access_activate");
1122                 break;
1123         case CONTENT_EVENT_ACCESS_UP | CONTENT_EVENT_ACCESS_MASK:
1124                 strcpy(ptr, "_access_up");
1125                 break;
1126         case CONTENT_EVENT_ACCESS_DOWN | CONTENT_EVENT_ACCESS_MASK:
1127                 strcpy(ptr, "_access_down");
1128                 break;
1129         case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
1130                 strcpy(ptr, "_mouse_enter");
1131                 break;
1132         case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
1133                 strcpy(ptr, "_mouse_leave");
1134                 break;
1135         case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
1136                 strcpy(ptr, "_mouse_up");
1137                 break;
1138         case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
1139                 strcpy(ptr, "_mouse_down");
1140                 break;
1141         case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
1142                 strcpy(ptr, "_mouse_move");
1143                 break;
1144         case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
1145                 strcpy(ptr, "_key_down");
1146                 break;
1147         case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
1148                 strcpy(ptr, "_key_up");
1149                 break;
1150         default:
1151                 ErrPrint("Invalid event type\n");
1152                 return -EINVAL;
1153         }
1154
1155         return send_mouse_event(handler, cmd, x, y, w, h);
1156 }
1157
1158 EAPI const char *livebox_filename(struct livebox *handler)
1159 {
1160         if (!handler) {
1161                 ErrPrint("Handler is NIL\n");
1162                 return NULL;
1163         }
1164
1165         if (handler->state != CREATE || !handler->id) {
1166                 ErrPrint("Handler is not valid\n");
1167                 return NULL;
1168         }
1169
1170         if (handler->filename)
1171                 return handler->filename;
1172
1173         /* Oooops */
1174         return util_uri_to_path(handler->id);
1175 }
1176
1177 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
1178 {
1179         int _w;
1180         int _h;
1181
1182         if (!handler) {
1183                 ErrPrint("Handler is NIL\n");
1184                 return -EINVAL;
1185         }
1186
1187         if (handler->state != CREATE || !handler->id) {
1188                 ErrPrint("Handler is not valid\n");
1189                 return -EINVAL;
1190         }
1191
1192         if (!w)
1193                 w = &_w;
1194         if (!h)
1195                 h = &_h;
1196
1197         *w = handler->pd.width;
1198         *h = handler->pd.height;
1199
1200         switch (handler->pd.type) {
1201         case _PD_TYPE_BUFFER:
1202         case _PD_TYPE_SCRIPT:
1203                 if (!handler->is_pd_created) {
1204                         DbgPrint("Buffer is not created yet - reset size\n");
1205                         *w = 0;
1206                         *h = 0;
1207                 }
1208                 break;
1209         default:
1210                 break;
1211         }
1212
1213         return 0;
1214 }
1215
1216 EAPI int livebox_size(struct livebox *handler)
1217 {
1218         int w;
1219         int h;
1220
1221         if (!handler) {
1222                 ErrPrint("Handler is NIL\n");
1223                 return -EINVAL;
1224         }
1225
1226         if (handler->state != CREATE || !handler->id) {
1227                 ErrPrint("Handler is not valid\n");
1228                 return -EINVAL;
1229         }
1230
1231         w = handler->lb.width;
1232         h = handler->lb.height;
1233
1234         switch (handler->lb.type) {
1235         case _LB_TYPE_BUFFER:
1236         case _LB_TYPE_SCRIPT:
1237                 if (!fb_is_created(handler->lb.data.fb)) {
1238                         DbgPrint("Buffer is not created yet - reset size\n");
1239                         w = 0;
1240                         h = 0;
1241                 }
1242                 break;
1243         default:
1244                 break;
1245         }
1246
1247         return livebox_service_size_type(w, h);
1248 }
1249
1250 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
1251 {
1252         struct packet *packet;
1253
1254         if (!handler) {
1255                 ErrPrint("Handler is NIL\n");
1256                 return -EINVAL;
1257         }
1258
1259         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1260                 ErrPrint("Invalid argument\n");
1261                 return -EINVAL;
1262         }
1263
1264         if (!handler->is_user) {
1265                 ErrPrint("CA Livebox is not able to change the group\n");
1266                 return -EPERM;
1267         }
1268
1269         if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
1270                 DbgPrint("No changes\n");
1271                 return -EALREADY;
1272         }
1273
1274         packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
1275         if (!packet) {
1276                 ErrPrint("Failed to build a param\n");
1277                 return -EFAULT;
1278         }
1279
1280         if (!cb)
1281                 cb = default_group_changed_cb;
1282
1283         return master_rpc_async_request(handler, packet, 0, set_group_ret_cb, create_cb_info(cb, data));
1284 }
1285
1286 EAPI int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category)
1287 {
1288         if (!handler) {
1289                 ErrPrint("Handler is NIL\n");
1290                 return -EINVAL;
1291         }
1292
1293         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1294                 ErrPrint("Invalid argument\n");
1295                 return -EINVAL;
1296         }
1297
1298         *cluster = handler->cluster;
1299         *category = handler->category;
1300         return 0;
1301 }
1302
1303 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
1304 {
1305         register int i;
1306         register int j;
1307
1308         if (!handler || !size_list) {
1309                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
1310                 return -EINVAL;
1311         }
1312
1313         if (!cnt || handler->state != CREATE || !handler->id) {
1314                 ErrPrint("Handler is not valid\n");
1315                 return -EINVAL;
1316         }
1317
1318         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
1319                 if (handler->lb.size_list & (0x01 << i)) {
1320                         if (j == *cnt)
1321                                 break;
1322
1323                         size_list[j++] = (0x01 << i);
1324                 }
1325         }
1326
1327         *cnt = j;
1328         return 0;
1329 }
1330
1331 EAPI const char *livebox_pkgname(struct livebox *handler)
1332 {
1333         if (!handler) {
1334                 ErrPrint("Handler is NIL\n");
1335                 return NULL;
1336         }
1337
1338         if (handler->state != CREATE) {
1339                 ErrPrint("Handler is not valid\n");
1340                 return NULL;
1341         }
1342
1343         return handler->pkgname;
1344 }
1345
1346 EAPI double livebox_priority(struct livebox *handler)
1347 {
1348         if (!handler) {
1349                 ErrPrint("Handler is NIL\n");
1350                 return 0.0f;
1351         }
1352
1353         if (handler->state != CREATE || !handler->id) {
1354                 ErrPrint("Handler is not valid (%p)\n", handler);
1355                 return -1.0f;
1356         }
1357
1358         return handler->lb.priority;
1359 }
1360
1361 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
1362 {
1363         struct packet *packet;
1364
1365         packet = packet_create("delete_cluster", "s", cluster);
1366         if (!packet) {
1367                 ErrPrint("Failed to build a param\n");
1368                 return -EFAULT;
1369         }
1370
1371         return master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, create_cb_info(cb, data));
1372 }
1373
1374 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
1375 {
1376         struct packet *packet;
1377
1378         packet = packet_create("delete_category", "ss", cluster, category);
1379         if (!packet) {
1380                 ErrPrint("Failed to build a param\n");
1381                 return -EFAULT;
1382         }
1383
1384         return master_rpc_async_request(NULL, packet, 0, delete_category_cb, create_cb_info(cb, data));
1385 }
1386
1387 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
1388 {
1389         if (!handler) {
1390                 ErrPrint("Handler is NIL\n");
1391                 return LB_TYPE_INVALID;
1392         }
1393
1394         if (handler->state != CREATE || !handler->id) {
1395                 ErrPrint("Handler is not valid\n");
1396                 return LB_TYPE_INVALID;
1397         }
1398
1399         switch (handler->lb.type) {
1400         case _LB_TYPE_FILE:
1401                 return LB_TYPE_IMAGE;
1402         case _LB_TYPE_BUFFER:
1403         case _LB_TYPE_SCRIPT:
1404                 {
1405                         const char *id;
1406                         id = fb_id(handler->lb.data.fb);
1407                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1408                                 return LB_TYPE_PIXMAP;
1409                 }
1410                 return LB_TYPE_BUFFER;
1411         case _LB_TYPE_TEXT:
1412                 return LB_TYPE_TEXT;
1413         default:
1414                 break;
1415         }
1416
1417         return LB_TYPE_INVALID;
1418 }
1419
1420 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
1421 {
1422         if (!handler) {
1423                 ErrPrint("Handler is NIL\n");
1424                 return PD_TYPE_INVALID;
1425         }
1426
1427         if (handler->state != CREATE || !handler->id) {
1428                 ErrPrint("Handler is not valid\n");
1429                 return PD_TYPE_INVALID;
1430         }
1431
1432         switch (handler->pd.type) {
1433         case _PD_TYPE_TEXT:
1434                 return PD_TYPE_TEXT;
1435         case _PD_TYPE_BUFFER:
1436         case _PD_TYPE_SCRIPT:
1437                 {
1438                         const char *id;
1439                         id = fb_id(handler->pd.data.fb);
1440                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1441                                 return PD_TYPE_PIXMAP;
1442                 }
1443                 return PD_TYPE_BUFFER;
1444         default:
1445                 break;
1446         }
1447
1448         return PD_TYPE_INVALID;
1449 }
1450
1451 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1452 {
1453         if (!handler) {
1454                 ErrPrint("Handler is NIL\n");
1455                 return -EINVAL;
1456         }
1457
1458         if (handler->state != CREATE) {
1459                 ErrPrint("Handler is not valid\n");
1460                 return -EINVAL;
1461         }
1462
1463         memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
1464         return 0;
1465 }
1466
1467 EAPI int livebox_set_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->lb.data.ops, ops, sizeof(*ops));
1480         return 0;
1481 }
1482
1483 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1484 {
1485         struct packet *packet;
1486         const char *id;
1487
1488         if (!handler) {
1489                 ErrPrint("Handler is NIL\n");
1490                 return -EINVAL;
1491         }
1492
1493         if (handler->state != CREATE || !handler->id) {
1494                 ErrPrint("Invalid handle\n");
1495                 return -EINVAL;
1496         }
1497
1498         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1499                 ErrPrint("Handler is not valid type\n");
1500                 return -EINVAL;
1501         }
1502
1503         id = fb_id(handler->lb.data.fb);
1504         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1505                 return -EINVAL;
1506
1507         packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
1508         if (!packet) {
1509                 ErrPrint("Failed to build a param\n");
1510                 return -EFAULT;
1511         }
1512
1513         return master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, create_cb_info(cb, data));
1514 }
1515
1516 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
1517 {
1518         struct packet *packet;
1519
1520         if (!handler) {
1521                 ErrPrint("Handler is NIL\n");
1522                 return -EINVAL;
1523         }
1524
1525         if (handler->state != CREATE || !handler->id) {
1526                 ErrPrint("Invalid handle\n");
1527                 return -EINVAL;
1528         }
1529
1530         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1531                 ErrPrint("Handler is not valid type\n");
1532                 return -EINVAL;
1533         }
1534
1535         packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1536         if (!packet) {
1537                 ErrPrint("Failed to build a param\n");
1538                 return -EFAULT;
1539         }
1540
1541         return master_rpc_request_only(handler, packet);
1542 }
1543
1544 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1545 {
1546         struct packet *packet;
1547         const char *id;
1548
1549         if (!handler) {
1550                 ErrPrint("Handler is NIL\n");
1551                 return -EINVAL;
1552         }
1553
1554         if (handler->state != CREATE || !handler->id) {
1555                 ErrPrint("Invalid handle\n");
1556                 return -EINVAL;
1557         }
1558
1559         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1560                 ErrPrint("Handler is not valid type\n");
1561                 return -EINVAL;
1562         }
1563
1564         id = fb_id(handler->pd.data.fb);
1565         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1566                 return -EINVAL;
1567
1568         packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
1569         if (!packet) {
1570                 ErrPrint("Failed to build a param\n");
1571                 return -EFAULT;
1572         }
1573
1574         return master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, create_cb_info(cb, data));
1575 }
1576
1577 EAPI int livebox_pd_pixmap(const struct livebox *handler)
1578 {
1579         const char *id;
1580         int pixmap = 0;
1581
1582         if (!handler) {
1583                 ErrPrint("Handler is NIL\n");
1584                 return 0;
1585         }
1586
1587         if (handler->state != CREATE || !handler->id) {
1588                 ErrPrint("Invalid handler\n");
1589                 return 0;
1590         }
1591
1592         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1593                 ErrPrint("Invalid handler\n");
1594                 return 0;
1595         }
1596
1597         id = fb_id(handler->pd.data.fb);
1598         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
1599                 ErrPrint("PIXMAP Id is not valid\n");
1600                 return 0;
1601         }
1602
1603         return pixmap;
1604 }
1605
1606 EAPI int livebox_lb_pixmap(const struct livebox *handler)
1607 {
1608         const char *id;
1609         int pixmap = 0;
1610
1611         if (!handler) {
1612                 ErrPrint("Handler is NIL\n");
1613                 return 0;
1614         }
1615
1616         if (handler->state != CREATE || !handler->id) {
1617                 ErrPrint("Invalid handler\n");
1618                 return 0;
1619         }
1620
1621         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1622                 ErrPrint("Invalid handler\n");
1623                 return 0;
1624         }
1625
1626         id = fb_id(handler->lb.data.fb);
1627         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
1628                 ErrPrint("PIXMAP Id is not valid\n");
1629                 return 0;
1630         }
1631
1632         return pixmap;
1633 }
1634
1635 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
1636 {
1637         struct packet *packet;
1638
1639         if (!handler) {
1640                 ErrPrint("Handler is NIL\n");
1641                 return -EINVAL;
1642         }
1643
1644         if (handler->state != CREATE || !handler->id) {
1645                 ErrPrint("Invalid handle\n");
1646                 return -EINVAL;
1647         }
1648
1649         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1650                 ErrPrint("Handler is not valid type\n");
1651                 return -EINVAL;
1652         }
1653
1654         packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1655         if (!packet) {
1656                 ErrPrint("Failed to build a param\n");
1657                 return -EFAULT;
1658         }
1659
1660         return master_rpc_request_only(handler, packet);
1661 }
1662
1663 EAPI void *livebox_acquire_fb(struct livebox *handler)
1664 {
1665         if (!handler) {
1666                 ErrPrint("Handler is NIL\n");
1667                 return NULL;
1668         }
1669
1670         if (handler->state != CREATE || !handler->id) {
1671                 ErrPrint("Invalid handle\n");
1672                 return NULL;
1673         }
1674
1675         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1676                 ErrPrint("Handler is not valid type\n");
1677                 return NULL;
1678         }
1679
1680         return fb_acquire_buffer(handler->lb.data.fb);
1681 }
1682
1683 EAPI int livebox_release_fb(void *buffer)
1684 {
1685         return fb_release_buffer(buffer);
1686 }
1687
1688 EAPI int livebox_fb_refcnt(void *buffer)
1689 {
1690         return fb_refcnt(buffer);
1691 }
1692
1693 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
1694 {
1695         if (!handler) {
1696                 ErrPrint("Handler is NIL\n");
1697                 return NULL;
1698         }
1699
1700         if (handler->state != CREATE || !handler->id) {
1701                 ErrPrint("Invalid handler\n");
1702                 return NULL;
1703         }
1704
1705         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1706                 ErrPrint("Handler is not valid type\n");
1707                 return NULL;
1708         }
1709
1710         return fb_acquire_buffer(handler->pd.data.fb);
1711 }
1712
1713 EAPI int livebox_release_pdfb(void *buffer)
1714 {
1715         return fb_release_buffer(buffer);
1716 }
1717
1718 EAPI int livebox_pdfb_refcnt(void *buffer)
1719 {
1720         return fb_refcnt(buffer);
1721 }
1722
1723 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
1724 {
1725         if (!handler) {
1726                 ErrPrint("Handler is NIL\n");
1727                 return -EINVAL;
1728         }
1729
1730         if (handler->state != CREATE || !handler->id) {
1731                 ErrPrint("Handler is not valid\n");
1732                 return -EINVAL;
1733         }
1734
1735         return fb_size(handler->pd.data.fb);
1736 }
1737
1738 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
1739 {
1740         if (!handler) {
1741                 ErrPrint("Handler is NIL\n");
1742                 return -EINVAL;
1743         }
1744
1745         if (handler->state != CREATE || !handler->id) {
1746                 ErrPrint("Handler is not valid\n");
1747                 return -EINVAL;
1748         }
1749
1750         return fb_size(handler->lb.data.fb);
1751 }
1752
1753 EAPI int livebox_is_user(struct livebox *handler)
1754 {
1755         if (!handler) {
1756                 ErrPrint("Handler is NIL\n");
1757                 return -EINVAL;
1758         }
1759
1760         if (handler->state != CREATE) {
1761                 ErrPrint("Handler is invalid\n");
1762                 return -EINVAL;
1763         }
1764
1765         return handler->is_user;
1766 }
1767
1768 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
1769 {
1770         struct packet *packet;
1771
1772         if (!handler) {
1773                 ErrPrint("Handler is NIL\n");
1774                 return -EINVAL;
1775         }
1776
1777         if (handler->state != CREATE || !handler->id) {
1778                 ErrPrint("Handler is not valid\n");
1779                 return -EINVAL;
1780         }
1781
1782         if (handler->is_pinned_up == flag) {
1783                 DbgPrint("No changes\n");
1784                 return -EALREADY;
1785         }
1786
1787         packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
1788         if (!packet) {
1789                 ErrPrint("Failed to build a param\n");
1790                 return -EFAULT;
1791         }
1792
1793         if (!cb)
1794                 cb = default_pinup_cb;
1795
1796         return master_rpc_async_request(handler, packet, 0, pinup_done_cb, create_cb_info(cb, data));
1797 }
1798
1799 EAPI int livebox_is_pinned_up(struct livebox *handler)
1800 {
1801         if (!handler) {
1802                 ErrPrint("Handler is NIL\n");
1803                 return -EINVAL;
1804         }
1805
1806         if (handler->state != CREATE || !handler->id)
1807                 return -EINVAL;
1808
1809         return handler->is_pinned_up;
1810 }
1811
1812 EAPI int livebox_has_pinup(struct livebox *handler)
1813 {
1814         if (!handler) {
1815                 ErrPrint("Handler is NIL\n");
1816                 return -EINVAL;
1817         }
1818
1819         if (handler->state != CREATE || !handler->id)
1820                 return -EINVAL;
1821
1822         return handler->lb.pinup_supported;
1823 }
1824
1825 EAPI int livebox_set_data(struct livebox *handler, void *data)
1826 {
1827         if (!handler) {
1828                 ErrPrint("Handler is NIL\n");
1829                 return -EINVAL;
1830         }
1831
1832         if (handler->state != CREATE)
1833                 return -EINVAL;
1834
1835         handler->data = data;
1836         return 0;
1837 }
1838
1839 EAPI void *livebox_get_data(struct livebox *handler)
1840 {
1841         if (!handler) {
1842                 ErrPrint("Handler is NIL\n");
1843                 return NULL;
1844         }
1845
1846         if (handler->state != CREATE)
1847                 return NULL;
1848
1849         return handler->data;
1850 }
1851
1852 EAPI int livebox_is_exists(const char *pkgname)
1853 {
1854         char *lb;
1855
1856         lb = lb_pkgname(pkgname);
1857         if (lb) {
1858                 free(lb);
1859                 return 1;
1860         }
1861
1862         return 0;
1863 }
1864
1865 EAPI const char *livebox_content(struct livebox *handler)
1866 {
1867         if (!handler) {
1868                 ErrPrint("Handler is NIL\n");
1869                 return NULL;
1870         }
1871
1872         if (handler->state != CREATE)
1873                 return NULL;
1874
1875         return handler->content;
1876 }
1877
1878 EAPI const char *livebox_category_title(struct livebox *handler)
1879 {
1880         if (!handler) {
1881                 ErrPrint("Handler is NIL\n");
1882                 return NULL;
1883         }
1884
1885         if (handler->state != CREATE)
1886                 return NULL;
1887
1888         return handler->title;
1889 }
1890
1891 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)
1892 {
1893         struct packet *packet;
1894
1895         if (!handler) {
1896                 ErrPrint("Handler is NIL\n");
1897                 return -EINVAL;
1898         }
1899
1900         if ((handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || handler->state != CREATE || !handler->id) {
1901                 ErrPrint("Handler is not valid\n");
1902                 return -EINVAL;
1903         }
1904
1905         if (!emission)
1906                 emission = "";
1907
1908         if (!source)
1909                 source = "";
1910
1911         packet = packet_create("text_signal", "ssssdddd",
1912                                 handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
1913         if (!packet) {
1914                 ErrPrint("Failed to build a param\n");
1915                 return -EFAULT;
1916         }
1917
1918         return master_rpc_async_request(handler, packet, 0, text_signal_cb, create_cb_info(cb, data));
1919 }
1920
1921 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
1922 {
1923         struct packet *packet;
1924
1925         /*!
1926          * \TODO
1927          * Validate the group info using DB
1928          * If the group info is not valid, do not send this request
1929          */
1930
1931         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
1932         if (!packet) {
1933                 ErrPrint("Failed to create a packet\n");
1934                 return -EFAULT;
1935         }
1936
1937         return master_rpc_request_only(NULL, packet);
1938 }
1939
1940 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
1941 {
1942         struct packet *packet;
1943
1944         /*!
1945          * \TODO
1946          * Validate the group info using DB
1947          * If the group info is not valid, do not send this request
1948          * AND Check the subscribed or not too
1949          */
1950
1951         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
1952         if (!packet) {
1953                 ErrPrint("Failed to create a packet\n");
1954                 return -EFAULT;
1955         }
1956
1957         return master_rpc_request_only(NULL, packet);
1958 }
1959
1960 EAPI int livebox_refresh(struct livebox *handler)
1961 {
1962         struct packet *packet;
1963
1964         if (!handler) {
1965                 ErrPrint("Hnalder is NIL\n");
1966                 return -EINVAL;
1967         }
1968
1969         if (handler->state != CREATE || !handler->id)
1970                 return -EINVAL;
1971
1972         packet = packet_create_noack("update", "ss", handler->pkgname, handler->id);
1973         if (!packet) {
1974                 ErrPrint("Failed to create a packet\n");
1975                 return -EFAULT;
1976         }
1977
1978         return master_rpc_request_only(handler, packet);
1979 }
1980
1981 EAPI int livebox_refresh_group(const char *cluster, const char *category)
1982 {
1983         struct packet *packet;
1984
1985         if (!cluster || !category) {
1986                 ErrPrint("Invalid argument\n");
1987                 return -EINVAL;
1988         }
1989
1990         packet = packet_create_noack("refresh_group", "ss", cluster, category);
1991         if (!packet) {
1992                 ErrPrint("Failed to create a packet\n");
1993                 return -EFAULT;
1994         }
1995
1996         return master_rpc_request_only(NULL, packet);
1997 }
1998
1999 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
2000 {
2001         struct packet *packet;
2002         int ret;
2003
2004         if (!handler) {
2005                 ErrPrint("Handler is NIL\n");
2006                 return -EINVAL;
2007         }
2008
2009         if (handler->state != CREATE || !handler->id)
2010                 return -EINVAL;
2011
2012         if (!handler->is_user) {
2013                 /* System cluster livebox cannot be changed its visible states */
2014                 if (state == LB_HIDE_WITH_PAUSE) {
2015                         ErrPrint("CA Livebox is not able to change the visibility\n");
2016                         return -EPERM;
2017                 }
2018         }
2019
2020         if (handler->visible == state)
2021                 return 0;
2022
2023         packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
2024         if (!packet) {
2025                 ErrPrint("Failed to create a packet\n");
2026                 return -EFAULT;
2027         }
2028
2029         ret = master_rpc_request_only(handler, packet);
2030         if (ret == 0)
2031                 handler->visible = state;
2032
2033         return ret;
2034 }
2035
2036 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
2037 {
2038         if (!handler) {
2039                 ErrPrint("Handler is NIL\n");
2040                 return LB_VISIBLE_ERROR;
2041         }
2042
2043         if (handler->state != CREATE)
2044                 return LB_VISIBLE_ERROR;
2045
2046         return handler->visible;
2047 }
2048
2049 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
2050 {
2051         void *pc = NULL;
2052         void *ps = NULL;
2053
2054         if (cluster) {
2055                 pc = strdup(cluster);
2056                 if (!pc) {
2057                         CRITICAL_LOG("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
2058                         return -ENOMEM;
2059                 }
2060         }
2061
2062         if (category) {
2063                 ps = strdup(category);
2064                 if (!ps) {
2065                         CRITICAL_LOG("Heap: %s (category: %s)\n", strerror(errno), category);
2066                         free(pc);
2067                         return -ENOMEM;
2068                 }
2069         }
2070
2071         if (handler->cluster)
2072                 free(handler->cluster);
2073
2074         if (handler->category)
2075                 free(handler->category);
2076
2077         handler->cluster = pc;
2078         handler->category = ps;
2079
2080         return 0;
2081 }
2082
2083 void lb_set_size(struct livebox *handler, int w, int h)
2084 {
2085         handler->lb.width = w;
2086         handler->lb.height = h;
2087 }
2088
2089 void lb_set_pdsize(struct livebox *handler, int w, int h)
2090 {
2091         handler->pd.width = w;
2092         handler->pd.height = h;
2093 }
2094
2095 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
2096 {
2097         struct dlist *l;
2098         struct dlist *n;
2099         struct fault_info *info;
2100
2101         dlist_foreach_safe(s_info.fault_list, l, n, info) {
2102                 if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE)
2103                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
2104         }
2105 }
2106
2107 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
2108 {
2109         struct dlist *l;
2110         struct dlist *n;
2111         struct event_info *info;
2112
2113         dlist_foreach_safe(s_info.event_list, l, n, info) {
2114                 if (info->handler(handler, event, info->user_data) == EXIT_FAILURE)
2115                         s_info.event_list = dlist_remove(s_info.event_list, l);
2116         }
2117 }
2118
2119 struct livebox *lb_find_livebox(const char *pkgname, const char *id)
2120 {
2121         struct dlist *l;
2122         struct livebox *handler;
2123
2124         dlist_foreach(s_info.livebox_list, l, handler) {
2125                 if (!handler->id)
2126                         continue;
2127
2128                 if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id))
2129                         return handler;
2130         }
2131
2132         return NULL;
2133 }
2134
2135 struct livebox *lb_find_livebox_by_timestamp(double timestamp)
2136 {
2137         struct dlist *l;
2138         struct livebox *handler;
2139
2140         dlist_foreach(s_info.livebox_list, l, handler) {
2141                 if (handler->timestamp == timestamp)
2142                         return handler;
2143         }
2144
2145         return NULL;
2146 }
2147
2148 static inline char *get_file_kept_in_safe(const char *id)
2149 {
2150         const char *path;
2151         char *new_path;
2152         int len;
2153         int base_idx;
2154
2155         path = util_uri_to_path(id);
2156         if (!path) {
2157                 ErrPrint("Invalid URI(%s)\n", id);
2158                 return NULL;
2159         }
2160
2161         /*!
2162          * \TODO: REMOVE ME
2163          */
2164         if (s_info.prevent_overwrite) {
2165                 new_path = strdup(path);
2166                 if (!new_path)
2167                         ErrPrint("Heap: %s\n", strerror(errno));
2168
2169                 return new_path;
2170         }
2171
2172
2173         len = strlen(path);
2174         base_idx = len - 1;
2175
2176         while (base_idx > 0 && path[base_idx] != '/') base_idx--;
2177         base_idx += (path[base_idx] == '/');
2178
2179         new_path = malloc(len + 10);
2180         if (!new_path) {
2181                 ErrPrint("Heap: %s\n", strerror(errno));
2182                 return NULL;
2183         }
2184
2185         strncpy(new_path, path, base_idx);
2186         snprintf(new_path + base_idx, len + 10 - base_idx, "reader/%s", path + base_idx);
2187         return new_path;
2188 }
2189
2190 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
2191 {
2192         struct livebox *handler;
2193
2194         handler = calloc(1, sizeof(*handler));
2195         if (!handler) {
2196                 ErrPrint("Failed to create a new livebox\n");
2197                 return NULL;
2198         }
2199
2200         handler->pkgname = strdup(pkgname);
2201         if (!handler->pkgname) {
2202                 ErrPrint("%s\n", strerror(errno));
2203                 free(handler);
2204                 return NULL;
2205         }
2206
2207         handler->id = strdup(id);
2208         if (!handler->id) {
2209                 ErrPrint("%s\n", strerror(errno));
2210                 free(handler->pkgname);
2211                 free(handler);
2212                 return NULL;
2213         }
2214
2215         handler->filename = get_file_kept_in_safe(id);
2216         if (!handler->filename) {
2217                 handler->filename = strdup(util_uri_to_path(id));
2218                 if (!handler->filename)
2219                         ErrPrint("Error: %s\n", strerror(errno));
2220         }
2221
2222         handler->timestamp = timestamp;
2223         handler->lb.type = _LB_TYPE_FILE;
2224         handler->pd.type = _PD_TYPE_SCRIPT;
2225         handler->state = CREATE;
2226         handler->visible = LB_SHOW;
2227
2228         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
2229         lb_ref(handler);
2230         return handler;
2231 }
2232
2233 int lb_delete_all(void)
2234 {
2235         struct dlist *l;
2236         struct dlist *n;
2237         struct livebox *handler;
2238
2239         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
2240                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
2241                 lb_unref(handler);
2242         }
2243
2244         return 0;
2245 }
2246
2247 int lb_set_content(struct livebox *handler, const char *content)
2248 {
2249         if (handler->content) {
2250                 free(handler->content);
2251                 handler->content = NULL;
2252         }
2253
2254         if (content) {
2255                 handler->content = strdup(content);
2256                 if (!handler->content) {
2257                         CRITICAL_LOG("Heap: %s (content: %s)\n", strerror(errno), content);
2258                         return -ENOMEM;
2259                 }
2260         }
2261
2262         return 0;
2263 }
2264
2265 int lb_set_title(struct livebox *handler, const char *title)
2266 {
2267         if (handler->title) {
2268                 free(handler->title);
2269                 handler->title = NULL;
2270         }
2271
2272         if (title) {
2273                 handler->title = strdup(title);
2274                 if (!handler->title) {
2275                         CRITICAL_LOG("Heap: %s (title: %s)\n", strerror(errno), title);
2276                         return -ENOMEM;
2277                 }
2278         }
2279
2280         return 0;
2281 }
2282
2283 void lb_set_size_list(struct livebox *handler, int size_list)
2284 {
2285         handler->lb.size_list = size_list;
2286 }
2287
2288 void lb_set_auto_launch(struct livebox *handler, const char *auto_launch)
2289 {
2290         if (!strlen(auto_launch))
2291                 return;
2292
2293         handler->lb.auto_launch = strdup(auto_launch);
2294         if (!handler->lb.auto_launch)
2295                 ErrPrint("Heap: %s\n", strerror(errno));
2296 }
2297
2298 void lb_set_priority(struct livebox *handler, double priority)
2299 {
2300         handler->lb.priority = priority;
2301 }
2302
2303 void lb_set_id(struct livebox *handler, const char *id)
2304 {
2305         if (handler->id)
2306                 free(handler->id);
2307
2308         handler->id = strdup(id);
2309         if (!handler->id)
2310                 ErrPrint("Error: %s\n", strerror(errno));
2311
2312         if (handler->filename)
2313                 free(handler->filename);
2314
2315         handler->filename = get_file_kept_in_safe(id);
2316         if (!handler->filename) {
2317                 handler->filename = strdup(util_uri_to_path(id));
2318                 if (!handler->filename)
2319                         ErrPrint("Error: %s\n", strerror(errno));
2320         }
2321 }
2322
2323 int lb_set_lb_fb(struct livebox *handler, const char *filename)
2324 {
2325         struct fb_info *fb;
2326
2327         if (!handler)
2328                 return -EINVAL;
2329
2330         fb = handler->lb.data.fb;
2331         if (fb && !strcmp(fb_id(fb), filename)) /*!< BUFFER is not changed, */
2332                 return 0;
2333
2334         handler->lb.data.fb = NULL;
2335
2336         if (!filename || filename[0] == '\0') {
2337                 if (fb)
2338                         fb_destroy(fb);
2339                 return 0;
2340         }
2341
2342         handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
2343         if (!handler->lb.data.fb) {
2344                 ErrPrint("Faield to create a FB\n");
2345                 if (fb)
2346                         fb_destroy(fb);
2347                 return -EFAULT;
2348         }
2349
2350         if (fb)
2351                 fb_destroy(fb);
2352
2353         return 0;
2354 }
2355
2356 int lb_set_pd_fb(struct livebox *handler, const char *filename)
2357 {
2358         struct fb_info *fb;
2359
2360         if (!handler)
2361                 return -EINVAL;
2362
2363         fb = handler->pd.data.fb;
2364         if (fb && !strcmp(fb_id(fb), filename)) {
2365                 /* BUFFER is not changed, just update the content */
2366                 return -EEXIST;
2367         }
2368         handler->pd.data.fb = NULL;
2369
2370         if (!filename || filename[0] == '\0') {
2371                 if (fb)
2372                         fb_destroy(fb);
2373                 return 0;
2374         }
2375
2376         handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
2377         if (!handler->pd.data.fb) {
2378                 ErrPrint("Failed to create a FB\n");
2379                 if (fb)
2380                         fb_destroy(fb);
2381                 return -EFAULT;
2382         }
2383
2384         if (fb)
2385                 fb_destroy(fb);
2386         return 0;
2387 }
2388
2389 struct fb_info *lb_get_lb_fb(struct livebox *handler)
2390 {
2391         return handler->lb.data.fb;
2392 }
2393
2394 struct fb_info *lb_get_pd_fb(struct livebox *handler)
2395 {
2396         return handler->pd.data.fb;
2397 }
2398
2399 void lb_set_user(struct livebox *handler, int user)
2400 {
2401         handler->is_user = user;
2402 }
2403
2404 void lb_set_pinup(struct livebox *handler, int pinup_supported)
2405 {
2406         handler->lb.pinup_supported = pinup_supported;
2407 }
2408
2409 void lb_set_text_lb(struct livebox *handler)
2410 {
2411         handler->lb.type = _LB_TYPE_TEXT;
2412 }
2413
2414 void lb_set_text_pd(struct livebox *handler)
2415 {
2416         handler->pd.type = _PD_TYPE_TEXT;
2417 }
2418
2419 int lb_text_lb(struct livebox *handler)
2420 {
2421         return handler->lb.type == _LB_TYPE_TEXT;
2422 }
2423
2424 int lb_text_pd(struct livebox *handler)
2425 {
2426         return handler->pd.type == _PD_TYPE_TEXT;
2427 }
2428
2429 void lb_set_period(struct livebox *handler, double period)
2430 {
2431         handler->lb.period = period;
2432 }
2433
2434 struct livebox *lb_ref(struct livebox *handler)
2435 {
2436         if (!handler)
2437                 return NULL;
2438
2439         handler->refcnt++;
2440         return handler;
2441 }
2442
2443 struct livebox *lb_unref(struct livebox *handler)
2444 {
2445         if (!handler)
2446                 return NULL;
2447
2448         handler->refcnt--;
2449         if (handler->refcnt > 0)
2450                 return handler;
2451
2452         dlist_remove_data(s_info.livebox_list, handler);
2453
2454         handler->state = DESTROYED;
2455         free(handler->cluster);
2456         free(handler->category);
2457         free(handler->id);
2458         free(handler->pkgname);
2459         free(handler->filename);
2460         free(handler->lb.auto_launch);
2461
2462         if (handler->lb.data.fb) {
2463                 fb_destroy(handler->lb.data.fb);
2464                 handler->lb.data.fb = NULL;
2465         }
2466
2467         if (handler->pd.data.fb) {
2468                 fb_destroy(handler->pd.data.fb);
2469                 handler->pd.data.fb = NULL;
2470         }
2471
2472         free(handler);
2473         return NULL;
2474 }
2475
2476 int lb_send_delete(struct livebox *handler, ret_cb_t cb, void *data)
2477 {
2478         struct packet *packet;
2479
2480         if (!cb && !!data) {
2481                 ErrPrint("Invalid argument\n");
2482                 return -EINVAL;
2483         }
2484
2485         if (handler->deleted_cb) {
2486                 ErrPrint("Already in-progress\n");
2487                 return -EINPROGRESS;
2488         }
2489
2490         packet = packet_create("delete", "ss", handler->pkgname, handler->id);
2491         if (!packet) {
2492                 ErrPrint("Failed to build a param\n");
2493                 if (cb)
2494                         cb(handler, -EFAULT, data);
2495
2496                 return -EFAULT;
2497         }
2498
2499         if (!cb)
2500                 cb = default_delete_cb;
2501
2502         return master_rpc_async_request(handler, packet, 0, del_ret_cb, create_cb_info(cb, data));
2503 }
2504
2505 /* End of a file */