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