Add mouse_event attribute
[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         const char *cmd;
1048
1049         if (!handler) {
1050                 ErrPrint("Handler is NIL\n");
1051                 return -EINVAL;
1052         }
1053
1054         if (handler->state != CREATE || !handler->id) {
1055                 ErrPrint("Handler is not valid\n");
1056                 return -EINVAL;
1057         }
1058
1059         switch (type) {
1060         case LB_MOUSE_DOWN:
1061                 if (!handler->lb.mouse_event) {
1062                         ErrPrint("Box is not support the mouse event\n");
1063                         return -EINVAL;
1064                 }
1065
1066                 if (!handler->lb.data.fb) {
1067                         ErrPrint("Handler is not valid\n");
1068                         return -EINVAL;
1069                 }
1070
1071                 cmd = "lb_mouse_down";
1072                 w = handler->lb.width;
1073                 h = handler->lb.height;
1074
1075                 handler->lb.x = x;
1076                 handler->lb.y = y;
1077                 break;
1078
1079         case LB_MOUSE_UP:
1080                 if (!handler->lb.mouse_event) {
1081                         ErrPrint("Box is not support the mouse event\n");
1082                         return -EINVAL;
1083                 }
1084
1085                 if (!handler->lb.data.fb) {
1086                         ErrPrint("Handler is not valid\n");
1087                         return -EINVAL;
1088                 }
1089
1090                 cmd = "lb_mouse_up";
1091                 w = handler->lb.width;
1092                 h = handler->lb.height;
1093                 break;
1094
1095         case LB_MOUSE_MOVE:
1096                 if (!handler->lb.mouse_event) {
1097                         ErrPrint("Box is not support the mouse event\n");
1098                         return -EINVAL;
1099                 }
1100
1101                 if (!handler->lb.data.fb) {
1102                         ErrPrint("Handler is not valid\n");
1103                         return -EINVAL;
1104                 }
1105
1106                 if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT)
1107                         return -EBUSY;
1108
1109                 cmd = "lb_mouse_move";
1110                 w = handler->lb.width;
1111                 h = handler->lb.height;
1112
1113                 handler->lb.x = x;
1114                 handler->lb.y = y;
1115                 break;
1116
1117         case LB_MOUSE_ENTER:
1118                 if (!handler->lb.mouse_event) {
1119                         ErrPrint("Box is not support the mouse event\n");
1120                         return -EINVAL;
1121                 }
1122
1123                 if (!handler->lb.data.fb) {
1124                         ErrPrint("Handler is not valid\n");
1125                         return -EINVAL;
1126                 }
1127
1128                 cmd = "lb_mouse_enter";
1129                 w = handler->lb.width;
1130                 h = handler->lb.height;
1131                 break;
1132
1133         case LB_MOUSE_LEAVE:
1134                 if (!handler->lb.mouse_event) {
1135                         ErrPrint("Box is not support the mouse event\n");
1136                         return -EINVAL;
1137                 }
1138
1139                 if (!handler->lb.data.fb) {
1140                         ErrPrint("Handler is not valid\n");
1141                         return -EINVAL;
1142                 }
1143
1144                 cmd = "lb_mouse_leave";
1145                 w = handler->lb.width;
1146                 h = handler->lb.height;
1147                 break;
1148
1149         case PD_MOUSE_ENTER:
1150                 if (!handler->is_pd_created) {
1151                         ErrPrint("PD is not created\n");
1152                         return -EINVAL;
1153                 }
1154
1155                 if (!handler->pd.data.fb) {
1156                         ErrPrint("Handler is not valid\n");
1157                         return -EINVAL;
1158                 }
1159
1160                 cmd = "pd_mouse_enter";
1161                 w = handler->pd.width;
1162                 h = handler->pd.height;
1163                 break;
1164
1165         case PD_MOUSE_LEAVE:
1166                 if (!handler->is_pd_created) {
1167                         ErrPrint("PD is not created\n");
1168                         return -EINVAL;
1169                 }
1170
1171                 if (!handler->pd.data.fb) {
1172                         ErrPrint("Handler is not valid\n");
1173                         return -EINVAL;
1174                 }
1175
1176                 cmd = "pd_mouse_leave";
1177                 w = handler->pd.width;
1178                 h = handler->pd.height;
1179                 break;
1180
1181         case PD_MOUSE_DOWN:
1182                 if (!handler->is_pd_created) {
1183                         ErrPrint("PD is not created\n");
1184                         return -EINVAL;
1185                 }
1186
1187                 if (!handler->pd.data.fb) {
1188                         ErrPrint("Handler is not valid\n");
1189                         return -EINVAL;
1190                 }
1191
1192                 cmd = "pd_mouse_down";
1193                 w = handler->pd.width;
1194                 h = handler->pd.height;
1195
1196                 handler->pd.x = x;
1197                 handler->pd.y = y;
1198                 break;
1199
1200         case PD_MOUSE_MOVE:
1201                 if (!handler->is_pd_created) {
1202                         ErrPrint("PD is not created\n");
1203                         return -EINVAL;
1204                 }
1205
1206                 if (!handler->pd.data.fb) {
1207                         ErrPrint("Handler is not valid\n");
1208                         return -EINVAL;
1209                 }
1210
1211                 if (fabs(x - handler->pd.x) < MINIMUM_EVENT && fabs(y - handler->pd.y) < MINIMUM_EVENT)
1212                         return -EBUSY;
1213
1214                 cmd = "pd_mouse_move";
1215                 w = handler->pd.width;
1216                 h = handler->pd.height;
1217
1218                 handler->pd.x = x;
1219                 handler->pd.y = y;
1220                 break;
1221
1222         case PD_MOUSE_UP:
1223                 if (!handler->is_pd_created) {
1224                         ErrPrint("PD is not created\n");
1225                         return -EINVAL;
1226                 }
1227
1228                 if (!handler->pd.data.fb) {
1229                         ErrPrint("Handler is not valid\n");
1230                         return -EINVAL;
1231                 }
1232
1233                 cmd = "pd_mouse_up";
1234                 w = handler->pd.width;
1235                 h = handler->pd.height;
1236                 break;
1237
1238         default:
1239                 ErrPrint("Invalid event type\n");
1240                 return -EINVAL;
1241         }
1242
1243         return send_mouse_event(handler, cmd, x, y, w, h);
1244 }
1245
1246 EAPI const char *livebox_filename(struct livebox *handler)
1247 {
1248         if (!handler) {
1249                 ErrPrint("Handler is NIL\n");
1250                 return NULL;
1251         }
1252
1253         if (handler->state != CREATE || !handler->id) {
1254                 ErrPrint("Handler is not valid\n");
1255                 return NULL;
1256         }
1257
1258         if (handler->filename)
1259                 return handler->filename;
1260
1261         /* Oooops */
1262         return util_uri_to_path(handler->id);
1263 }
1264
1265 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
1266 {
1267         int _w;
1268         int _h;
1269
1270         if (!handler) {
1271                 ErrPrint("Handler is NIL\n");
1272                 return -EINVAL;
1273         }
1274
1275         if (handler->state != CREATE || !handler->id) {
1276                 ErrPrint("Handler is not valid\n");
1277                 return -EINVAL;
1278         }
1279
1280         if (!w)
1281                 w = &_w;
1282         if (!h)
1283                 h = &_h;
1284
1285         *w = handler->pd.width;
1286         *h = handler->pd.height;
1287
1288         switch (handler->pd.type) {
1289         case _PD_TYPE_BUFFER:
1290         case _PD_TYPE_SCRIPT:
1291                 if (!handler->is_pd_created) {
1292                         DbgPrint("Buffer is not created yet - reset size\n");
1293                         *w = 0;
1294                         *h = 0;
1295                 }
1296                 break;
1297         default:
1298                 break;
1299         }
1300
1301         return 0;
1302 }
1303
1304 EAPI int livebox_size(struct livebox *handler)
1305 {
1306         int w;
1307         int h;
1308
1309         if (!handler) {
1310                 ErrPrint("Handler is NIL\n");
1311                 return -EINVAL;
1312         }
1313
1314         if (handler->state != CREATE || !handler->id) {
1315                 ErrPrint("Handler is not valid\n");
1316                 return -EINVAL;
1317         }
1318
1319         w = handler->lb.width;
1320         h = handler->lb.height;
1321
1322         switch (handler->lb.type) {
1323         case _LB_TYPE_BUFFER:
1324         case _LB_TYPE_SCRIPT:
1325                 if (!fb_is_created(handler->lb.data.fb)) {
1326                         DbgPrint("Buffer is not created yet - reset size\n");
1327                         w = 0;
1328                         h = 0;
1329                 }
1330                 break;
1331         default:
1332                 break;
1333         }
1334
1335         return livebox_service_size_type(w, h);
1336 }
1337
1338 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
1339 {
1340         struct packet *packet;
1341
1342         if (!handler) {
1343                 ErrPrint("Handler is NIL\n");
1344                 return -EINVAL;
1345         }
1346
1347         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1348                 ErrPrint("Invalid argument\n");
1349                 return -EINVAL;
1350         }
1351
1352         if (!handler->is_user) {
1353                 ErrPrint("CA Livebox is not able to change the group\n");
1354                 return -EPERM;
1355         }
1356
1357         if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
1358                 DbgPrint("No changes\n");
1359                 return -EALREADY;
1360         }
1361
1362         packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
1363         if (!packet) {
1364                 ErrPrint("Failed to build a param\n");
1365                 return -EFAULT;
1366         }
1367
1368         if (!cb)
1369                 cb = default_group_changed_cb;
1370
1371         return master_rpc_async_request(handler, packet, 0, set_group_ret_cb, create_cb_info(cb, data));
1372 }
1373
1374 EAPI int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category)
1375 {
1376         if (!handler) {
1377                 ErrPrint("Handler is NIL\n");
1378                 return -EINVAL;
1379         }
1380
1381         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1382                 ErrPrint("Invalid argument\n");
1383                 return -EINVAL;
1384         }
1385
1386         *cluster = handler->cluster;
1387         *category = handler->category;
1388         return 0;
1389 }
1390
1391 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
1392 {
1393         register int i;
1394         register int j;
1395
1396         if (!handler || !size_list) {
1397                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
1398                 return -EINVAL;
1399         }
1400
1401         if (!cnt || handler->state != CREATE || !handler->id) {
1402                 ErrPrint("Handler is not valid\n");
1403                 return -EINVAL;
1404         }
1405
1406         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
1407                 if (handler->lb.size_list & (0x01 << i)) {
1408                         if (j == *cnt)
1409                                 break;
1410
1411                         size_list[j++] = (0x01 << i);
1412                 }
1413         }
1414
1415         *cnt = j;
1416         return 0;
1417 }
1418
1419 EAPI const char *livebox_pkgname(struct livebox *handler)
1420 {
1421         if (!handler) {
1422                 ErrPrint("Handler is NIL\n");
1423                 return NULL;
1424         }
1425
1426         if (handler->state != CREATE) {
1427                 ErrPrint("Handler is not valid\n");
1428                 return NULL;
1429         }
1430
1431         return handler->pkgname;
1432 }
1433
1434 EAPI double livebox_priority(struct livebox *handler)
1435 {
1436         if (!handler) {
1437                 ErrPrint("Handler is NIL\n");
1438                 return 0.0f;
1439         }
1440
1441         if (handler->state != CREATE || !handler->id) {
1442                 ErrPrint("Handler is not valid (%p)\n", handler);
1443                 return -1.0f;
1444         }
1445
1446         return handler->lb.priority;
1447 }
1448
1449 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
1450 {
1451         struct packet *packet;
1452
1453         packet = packet_create("delete_cluster", "s", cluster);
1454         if (!packet) {
1455                 ErrPrint("Failed to build a param\n");
1456                 return -EFAULT;
1457         }
1458
1459         return master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, create_cb_info(cb, data));
1460 }
1461
1462 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
1463 {
1464         struct packet *packet;
1465
1466         packet = packet_create("delete_category", "ss", cluster, category);
1467         if (!packet) {
1468                 ErrPrint("Failed to build a param\n");
1469                 return -EFAULT;
1470         }
1471
1472         return master_rpc_async_request(NULL, packet, 0, delete_category_cb, create_cb_info(cb, data));
1473 }
1474
1475 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
1476 {
1477         if (!handler) {
1478                 ErrPrint("Handler is NIL\n");
1479                 return LB_TYPE_INVALID;
1480         }
1481
1482         if (handler->state != CREATE || !handler->id) {
1483                 ErrPrint("Handler is not valid\n");
1484                 return LB_TYPE_INVALID;
1485         }
1486
1487         switch (handler->lb.type) {
1488         case _LB_TYPE_FILE:
1489                 return LB_TYPE_IMAGE;
1490         case _LB_TYPE_BUFFER:
1491         case _LB_TYPE_SCRIPT:
1492                 {
1493                         const char *id;
1494                         id = fb_id(handler->lb.data.fb);
1495                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1496                                 return LB_TYPE_PIXMAP;
1497                 }
1498                 return LB_TYPE_BUFFER;
1499         case _LB_TYPE_TEXT:
1500                 return LB_TYPE_TEXT;
1501         default:
1502                 break;
1503         }
1504
1505         return LB_TYPE_INVALID;
1506 }
1507
1508 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
1509 {
1510         if (!handler) {
1511                 ErrPrint("Handler is NIL\n");
1512                 return PD_TYPE_INVALID;
1513         }
1514
1515         if (handler->state != CREATE || !handler->id) {
1516                 ErrPrint("Handler is not valid\n");
1517                 return PD_TYPE_INVALID;
1518         }
1519
1520         switch (handler->pd.type) {
1521         case _PD_TYPE_TEXT:
1522                 return PD_TYPE_TEXT;
1523         case _PD_TYPE_BUFFER:
1524         case _PD_TYPE_SCRIPT:
1525                 {
1526                         const char *id;
1527                         id = fb_id(handler->pd.data.fb);
1528                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1529                                 return PD_TYPE_PIXMAP;
1530                 }
1531                 return PD_TYPE_BUFFER;
1532         default:
1533                 break;
1534         }
1535
1536         return PD_TYPE_INVALID;
1537 }
1538
1539 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1540 {
1541         if (!handler) {
1542                 ErrPrint("Handler is NIL\n");
1543                 return -EINVAL;
1544         }
1545
1546         if (handler->state != CREATE) {
1547                 ErrPrint("Handler is not valid\n");
1548                 return -EINVAL;
1549         }
1550
1551         memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
1552         return 0;
1553 }
1554
1555 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1556 {
1557         if (!handler) {
1558                 ErrPrint("Handler is NIL\n");
1559                 return -EINVAL;
1560         }
1561
1562         if (handler->state != CREATE) {
1563                 ErrPrint("Handler is not valid\n");
1564                 return -EINVAL;
1565         }
1566
1567         memcpy(&handler->lb.data.ops, ops, sizeof(*ops));
1568         return 0;
1569 }
1570
1571 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1572 {
1573         struct packet *packet;
1574         const char *id;
1575
1576         if (!handler) {
1577                 ErrPrint("Handler is NIL\n");
1578                 return -EINVAL;
1579         }
1580
1581         if (handler->state != CREATE || !handler->id) {
1582                 ErrPrint("Invalid handle\n");
1583                 return -EINVAL;
1584         }
1585
1586         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1587                 ErrPrint("Handler is not valid type\n");
1588                 return -EINVAL;
1589         }
1590
1591         id = fb_id(handler->lb.data.fb);
1592         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1593                 return -EINVAL;
1594
1595         packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
1596         if (!packet) {
1597                 ErrPrint("Failed to build a param\n");
1598                 return -EFAULT;
1599         }
1600
1601         return master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, create_cb_info(cb, data));
1602 }
1603
1604 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
1605 {
1606         struct packet *packet;
1607
1608         if (!handler) {
1609                 ErrPrint("Handler is NIL\n");
1610                 return -EINVAL;
1611         }
1612
1613         if (handler->state != CREATE || !handler->id) {
1614                 ErrPrint("Invalid handle\n");
1615                 return -EINVAL;
1616         }
1617
1618         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1619                 ErrPrint("Handler is not valid type\n");
1620                 return -EINVAL;
1621         }
1622
1623         packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1624         if (!packet) {
1625                 ErrPrint("Failed to build a param\n");
1626                 return -EFAULT;
1627         }
1628
1629         return master_rpc_request_only(handler, packet);
1630 }
1631
1632 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1633 {
1634         struct packet *packet;
1635         const char *id;
1636
1637         if (!handler) {
1638                 ErrPrint("Handler is NIL\n");
1639                 return -EINVAL;
1640         }
1641
1642         if (handler->state != CREATE || !handler->id) {
1643                 ErrPrint("Invalid handle\n");
1644                 return -EINVAL;
1645         }
1646
1647         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1648                 ErrPrint("Handler is not valid type\n");
1649                 return -EINVAL;
1650         }
1651
1652         id = fb_id(handler->pd.data.fb);
1653         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1654                 return -EINVAL;
1655
1656         packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
1657         if (!packet) {
1658                 ErrPrint("Failed to build a param\n");
1659                 return -EFAULT;
1660         }
1661
1662         return master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, create_cb_info(cb, data));
1663 }
1664
1665 EAPI int livebox_pd_pixmap(const struct livebox *handler)
1666 {
1667         const char *id;
1668         int pixmap = 0;
1669
1670         if (!handler) {
1671                 ErrPrint("Handler is NIL\n");
1672                 return 0;
1673         }
1674
1675         if (handler->state != CREATE || !handler->id) {
1676                 ErrPrint("Invalid handler\n");
1677                 return 0;
1678         }
1679
1680         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1681                 ErrPrint("Invalid handler\n");
1682                 return 0;
1683         }
1684
1685         id = fb_id(handler->pd.data.fb);
1686         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
1687                 ErrPrint("PIXMAP Id is not valid\n");
1688                 return 0;
1689         }
1690
1691         return pixmap;
1692 }
1693
1694 EAPI int livebox_lb_pixmap(const struct livebox *handler)
1695 {
1696         const char *id;
1697         int pixmap = 0;
1698
1699         if (!handler) {
1700                 ErrPrint("Handler is NIL\n");
1701                 return 0;
1702         }
1703
1704         if (handler->state != CREATE || !handler->id) {
1705                 ErrPrint("Invalid handler\n");
1706                 return 0;
1707         }
1708
1709         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1710                 ErrPrint("Invalid handler\n");
1711                 return 0;
1712         }
1713
1714         id = fb_id(handler->lb.data.fb);
1715         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
1716                 ErrPrint("PIXMAP Id is not valid\n");
1717                 return 0;
1718         }
1719
1720         return pixmap;
1721 }
1722
1723 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
1724 {
1725         struct packet *packet;
1726
1727         if (!handler) {
1728                 ErrPrint("Handler is NIL\n");
1729                 return -EINVAL;
1730         }
1731
1732         if (handler->state != CREATE || !handler->id) {
1733                 ErrPrint("Invalid handle\n");
1734                 return -EINVAL;
1735         }
1736
1737         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1738                 ErrPrint("Handler is not valid type\n");
1739                 return -EINVAL;
1740         }
1741
1742         packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1743         if (!packet) {
1744                 ErrPrint("Failed to build a param\n");
1745                 return -EFAULT;
1746         }
1747
1748         return master_rpc_request_only(handler, packet);
1749 }
1750
1751 EAPI void *livebox_acquire_fb(struct livebox *handler)
1752 {
1753         if (!handler) {
1754                 ErrPrint("Handler is NIL\n");
1755                 return NULL;
1756         }
1757
1758         if (handler->state != CREATE || !handler->id) {
1759                 ErrPrint("Invalid handle\n");
1760                 return NULL;
1761         }
1762
1763         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1764                 ErrPrint("Handler is not valid type\n");
1765                 return NULL;
1766         }
1767
1768         return fb_acquire_buffer(handler->lb.data.fb);
1769 }
1770
1771 EAPI int livebox_release_fb(void *buffer)
1772 {
1773         return fb_release_buffer(buffer);
1774 }
1775
1776 EAPI int livebox_fb_refcnt(void *buffer)
1777 {
1778         return fb_refcnt(buffer);
1779 }
1780
1781 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
1782 {
1783         if (!handler) {
1784                 ErrPrint("Handler is NIL\n");
1785                 return NULL;
1786         }
1787
1788         if (handler->state != CREATE || !handler->id) {
1789                 ErrPrint("Invalid handler\n");
1790                 return NULL;
1791         }
1792
1793         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1794                 ErrPrint("Handler is not valid type\n");
1795                 return NULL;
1796         }
1797
1798         return fb_acquire_buffer(handler->pd.data.fb);
1799 }
1800
1801 EAPI int livebox_release_pdfb(void *buffer)
1802 {
1803         return fb_release_buffer(buffer);
1804 }
1805
1806 EAPI int livebox_pdfb_refcnt(void *buffer)
1807 {
1808         return fb_refcnt(buffer);
1809 }
1810
1811 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
1812 {
1813         if (!handler) {
1814                 ErrPrint("Handler is NIL\n");
1815                 return -EINVAL;
1816         }
1817
1818         if (handler->state != CREATE || !handler->id) {
1819                 ErrPrint("Handler is not valid\n");
1820                 return -EINVAL;
1821         }
1822
1823         return fb_size(handler->pd.data.fb);
1824 }
1825
1826 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
1827 {
1828         if (!handler) {
1829                 ErrPrint("Handler is NIL\n");
1830                 return -EINVAL;
1831         }
1832
1833         if (handler->state != CREATE || !handler->id) {
1834                 ErrPrint("Handler is not valid\n");
1835                 return -EINVAL;
1836         }
1837
1838         return fb_size(handler->lb.data.fb);
1839 }
1840
1841 EAPI int livebox_is_user(struct livebox *handler)
1842 {
1843         if (!handler) {
1844                 ErrPrint("Handler is NIL\n");
1845                 return -EINVAL;
1846         }
1847
1848         if (handler->state != CREATE) {
1849                 ErrPrint("Handler is invalid\n");
1850                 return -EINVAL;
1851         }
1852
1853         return handler->is_user;
1854 }
1855
1856 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
1857 {
1858         struct packet *packet;
1859
1860         if (!handler) {
1861                 ErrPrint("Handler is NIL\n");
1862                 return -EINVAL;
1863         }
1864
1865         if (handler->state != CREATE || !handler->id) {
1866                 ErrPrint("Handler is not valid\n");
1867                 return -EINVAL;
1868         }
1869
1870         if (handler->is_pinned_up == flag) {
1871                 DbgPrint("No changes\n");
1872                 return -EALREADY;
1873         }
1874
1875         packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
1876         if (!packet) {
1877                 ErrPrint("Failed to build a param\n");
1878                 return -EFAULT;
1879         }
1880
1881         if (!cb)
1882                 cb = default_pinup_cb;
1883
1884         return master_rpc_async_request(handler, packet, 0, pinup_done_cb, create_cb_info(cb, data));
1885 }
1886
1887 EAPI int livebox_is_pinned_up(struct livebox *handler)
1888 {
1889         if (!handler) {
1890                 ErrPrint("Handler is NIL\n");
1891                 return -EINVAL;
1892         }
1893
1894         if (handler->state != CREATE || !handler->id)
1895                 return -EINVAL;
1896
1897         return handler->is_pinned_up;
1898 }
1899
1900 EAPI int livebox_has_pinup(struct livebox *handler)
1901 {
1902         if (!handler) {
1903                 ErrPrint("Handler is NIL\n");
1904                 return -EINVAL;
1905         }
1906
1907         if (handler->state != CREATE || !handler->id)
1908                 return -EINVAL;
1909
1910         return handler->lb.pinup_supported;
1911 }
1912
1913 EAPI int livebox_set_data(struct livebox *handler, void *data)
1914 {
1915         if (!handler) {
1916                 ErrPrint("Handler is NIL\n");
1917                 return -EINVAL;
1918         }
1919
1920         if (handler->state != CREATE)
1921                 return -EINVAL;
1922
1923         handler->data = data;
1924         return 0;
1925 }
1926
1927 EAPI void *livebox_get_data(struct livebox *handler)
1928 {
1929         if (!handler) {
1930                 ErrPrint("Handler is NIL\n");
1931                 return NULL;
1932         }
1933
1934         if (handler->state != CREATE)
1935                 return NULL;
1936
1937         return handler->data;
1938 }
1939
1940 EAPI int livebox_is_exists(const char *pkgname)
1941 {
1942         char *lb;
1943
1944         lb = lb_pkgname(pkgname);
1945         if (lb) {
1946                 free(lb);
1947                 return 1;
1948         }
1949
1950         return 0;
1951 }
1952
1953 EAPI const char *livebox_content(struct livebox *handler)
1954 {
1955         if (!handler) {
1956                 ErrPrint("Handler is NIL\n");
1957                 return NULL;
1958         }
1959
1960         if (handler->state != CREATE)
1961                 return NULL;
1962
1963         return handler->content;
1964 }
1965
1966 EAPI const char *livebox_category_title(struct livebox *handler)
1967 {
1968         if (!handler) {
1969                 ErrPrint("Handler is NIL\n");
1970                 return NULL;
1971         }
1972
1973         if (handler->state != CREATE)
1974                 return NULL;
1975
1976         return handler->title;
1977 }
1978
1979 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)
1980 {
1981         struct packet *packet;
1982
1983         if (!handler) {
1984                 ErrPrint("Handler is NIL\n");
1985                 return -EINVAL;
1986         }
1987
1988         if ((handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || handler->state != CREATE || !handler->id) {
1989                 ErrPrint("Handler is not valid\n");
1990                 return -EINVAL;
1991         }
1992
1993         if (!emission)
1994                 emission = "";
1995
1996         if (!source)
1997                 source = "";
1998
1999         packet = packet_create("text_signal", "ssssdddd",
2000                                 handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
2001         if (!packet) {
2002                 ErrPrint("Failed to build a param\n");
2003                 return -EFAULT;
2004         }
2005
2006         return master_rpc_async_request(handler, packet, 0, text_signal_cb, create_cb_info(cb, data));
2007 }
2008
2009 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
2010 {
2011         struct packet *packet;
2012
2013         /*!
2014          * \TODO
2015          * Validate the group info using DB
2016          * If the group info is not valid, do not send this request
2017          */
2018
2019         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
2020         if (!packet) {
2021                 ErrPrint("Failed to create a packet\n");
2022                 return -EFAULT;
2023         }
2024
2025         return master_rpc_request_only(NULL, packet);
2026 }
2027
2028 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
2029 {
2030         struct packet *packet;
2031
2032         /*!
2033          * \TODO
2034          * Validate the group info using DB
2035          * If the group info is not valid, do not send this request
2036          * AND Check the subscribed or not too
2037          */
2038
2039         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
2040         if (!packet) {
2041                 ErrPrint("Failed to create a packet\n");
2042                 return -EFAULT;
2043         }
2044
2045         return master_rpc_request_only(NULL, packet);
2046 }
2047
2048 EAPI int livebox_refresh_group(const char *cluster, const char *category)
2049 {
2050         struct packet *packet;
2051
2052         if (!cluster || !category) {
2053                 ErrPrint("Invalid argument\n");
2054                 return -EINVAL;
2055         }
2056
2057         packet = packet_create_noack("refresh_group", "ss", cluster, category);
2058         if (!packet) {
2059                 ErrPrint("Failed to create a packet\n");
2060                 return -EFAULT;
2061         }
2062
2063         return master_rpc_request_only(NULL, packet);
2064 }
2065
2066 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
2067 {
2068         struct packet *packet;
2069         int ret;
2070
2071         if (!handler) {
2072                 ErrPrint("Handler is NIL\n");
2073                 return -EINVAL;
2074         }
2075
2076         if (handler->state != CREATE || !handler->id)
2077                 return -EINVAL;
2078
2079         if (!handler->is_user) {
2080                 /* System cluster livebox cannot be changed its visible states */
2081                 if (state == LB_HIDE_WITH_PAUSE) {
2082                         ErrPrint("CA Livebox is not able to change the visibility\n");
2083                         return -EPERM;
2084                 }
2085         }
2086
2087         if (handler->visible == state)
2088                 return 0;
2089
2090         packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
2091         if (!packet) {
2092                 ErrPrint("Failed to create a packet\n");
2093                 return -EFAULT;
2094         }
2095
2096         ret = master_rpc_request_only(handler, packet);
2097         if (ret == 0)
2098                 handler->visible = state;
2099
2100         return ret;
2101 }
2102
2103 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
2104 {
2105         if (!handler) {
2106                 ErrPrint("Handler is NIL\n");
2107                 return LB_VISIBLE_ERROR;
2108         }
2109
2110         if (handler->state != CREATE)
2111                 return LB_VISIBLE_ERROR;
2112
2113         return handler->visible;
2114 }
2115
2116 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
2117 {
2118         void *pc = NULL;
2119         void *ps = NULL;
2120
2121         if (cluster) {
2122                 pc = strdup(cluster);
2123                 if (!pc) {
2124                         CRITICAL_LOG("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
2125                         return -ENOMEM;
2126                 }
2127         }
2128
2129         if (category) {
2130                 ps = strdup(category);
2131                 if (!ps) {
2132                         CRITICAL_LOG("Heap: %s (category: %s)\n", strerror(errno), category);
2133                         free(pc);
2134                         return -ENOMEM;
2135                 }
2136         }
2137
2138         if (handler->cluster)
2139                 free(handler->cluster);
2140
2141         if (handler->category)
2142                 free(handler->category);
2143
2144         handler->cluster = pc;
2145         handler->category = ps;
2146
2147         return 0;
2148 }
2149
2150 void lb_set_size(struct livebox *handler, int w, int h)
2151 {
2152         handler->lb.width = w;
2153         handler->lb.height = h;
2154 }
2155
2156 void lb_set_pdsize(struct livebox *handler, int w, int h)
2157 {
2158         handler->pd.width = w;
2159         handler->pd.height = h;
2160 }
2161
2162 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
2163 {
2164         struct dlist *l;
2165         struct dlist *n;
2166         struct fault_info *info;
2167
2168         dlist_foreach_safe(s_info.fault_list, l, n, info) {
2169                 if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE)
2170                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
2171         }
2172 }
2173
2174 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
2175 {
2176         struct dlist *l;
2177         struct dlist *n;
2178         struct event_info *info;
2179
2180         dlist_foreach_safe(s_info.event_list, l, n, info) {
2181                 if (info->handler(handler, event, info->user_data) == EXIT_FAILURE)
2182                         s_info.event_list = dlist_remove(s_info.event_list, l);
2183         }
2184 }
2185
2186 struct livebox *lb_find_livebox(const char *pkgname, const char *id)
2187 {
2188         struct dlist *l;
2189         struct livebox *handler;
2190
2191         dlist_foreach(s_info.livebox_list, l, handler) {
2192                 if (!handler->id)
2193                         continue;
2194
2195                 if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id))
2196                         return handler;
2197         }
2198
2199         return NULL;
2200 }
2201
2202 struct livebox *lb_find_livebox_by_timestamp(double timestamp)
2203 {
2204         struct dlist *l;
2205         struct livebox *handler;
2206
2207         dlist_foreach(s_info.livebox_list, l, handler) {
2208                 if (handler->timestamp == timestamp)
2209                         return handler;
2210         }
2211
2212         return NULL;
2213 }
2214
2215 static inline char *get_file_kept_in_safe(const char *id)
2216 {
2217         const char *path;
2218         char *new_path;
2219         int len;
2220         int base_idx;
2221
2222         path = util_uri_to_path(id);
2223         if (!path) {
2224                 ErrPrint("Invalid URI(%s)\n", id);
2225                 return NULL;
2226         }
2227
2228         /*!
2229          * \TODO: REMOVE ME
2230          */
2231         if (s_info.prevent_overwrite) {
2232                 new_path = strdup(path);
2233                 if (!new_path)
2234                         ErrPrint("Heap: %s\n", strerror(errno));
2235
2236                 return new_path;
2237         }
2238
2239
2240         len = strlen(path);
2241         base_idx = len - 1;
2242
2243         while (base_idx > 0 && path[base_idx] != '/') base_idx--;
2244         base_idx += (path[base_idx] == '/');
2245
2246         new_path = malloc(len + 10);
2247         if (!new_path) {
2248                 ErrPrint("Heap: %s\n", strerror(errno));
2249                 return NULL;
2250         }
2251
2252         strncpy(new_path, path, base_idx);
2253         snprintf(new_path + base_idx, len + 10 - base_idx, "reader/%s", path + base_idx);
2254         return new_path;
2255 }
2256
2257 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
2258 {
2259         struct livebox *handler;
2260
2261         handler = calloc(1, sizeof(*handler));
2262         if (!handler) {
2263                 ErrPrint("Failed to create a new livebox\n");
2264                 return NULL;
2265         }
2266
2267         handler->pkgname = strdup(pkgname);
2268         if (!handler->pkgname) {
2269                 ErrPrint("%s\n", strerror(errno));
2270                 free(handler);
2271                 return NULL;
2272         }
2273
2274         handler->id = strdup(id);
2275         if (!handler->id) {
2276                 ErrPrint("%s\n", strerror(errno));
2277                 free(handler->pkgname);
2278                 free(handler);
2279                 return NULL;
2280         }
2281
2282         handler->filename = get_file_kept_in_safe(id);
2283         if (!handler->filename) {
2284                 handler->filename = strdup(util_uri_to_path(id));
2285                 if (!handler->filename)
2286                         ErrPrint("Error: %s\n", strerror(errno));
2287         }
2288
2289         handler->timestamp = timestamp;
2290         handler->lb.type = _LB_TYPE_FILE;
2291         handler->pd.type = _PD_TYPE_SCRIPT;
2292         handler->state = CREATE;
2293         handler->visible = LB_SHOW;
2294
2295         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
2296         lb_ref(handler);
2297         return handler;
2298 }
2299
2300 int lb_delete_all(void)
2301 {
2302         struct dlist *l;
2303         struct dlist *n;
2304         struct livebox *handler;
2305
2306         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
2307                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
2308                 lb_unref(handler);
2309         }
2310
2311         return 0;
2312 }
2313
2314 int lb_set_content(struct livebox *handler, const char *content)
2315 {
2316         if (handler->content) {
2317                 free(handler->content);
2318                 handler->content = NULL;
2319         }
2320
2321         if (content) {
2322                 handler->content = strdup(content);
2323                 if (!handler->content) {
2324                         CRITICAL_LOG("Heap: %s (content: %s)\n", strerror(errno), content);
2325                         return -ENOMEM;
2326                 }
2327         }
2328
2329         return 0;
2330 }
2331
2332 int lb_set_title(struct livebox *handler, const char *title)
2333 {
2334         if (handler->title) {
2335                 free(handler->title);
2336                 handler->title = NULL;
2337         }
2338
2339         if (title) {
2340                 handler->title = strdup(title);
2341                 if (!handler->title) {
2342                         CRITICAL_LOG("Heap: %s (title: %s)\n", strerror(errno), title);
2343                         return -ENOMEM;
2344                 }
2345         }
2346
2347         return 0;
2348 }
2349
2350 void lb_set_size_list(struct livebox *handler, int size_list)
2351 {
2352         handler->lb.size_list = size_list;
2353 }
2354
2355 void lb_set_auto_launch(struct livebox *handler, const char *auto_launch)
2356 {
2357         if (!strlen(auto_launch))
2358                 return;
2359
2360         handler->lb.auto_launch = strdup(auto_launch);
2361         if (!handler->lb.auto_launch)
2362                 ErrPrint("Heap: %s\n", strerror(errno));
2363 }
2364
2365 void lb_set_priority(struct livebox *handler, double priority)
2366 {
2367         handler->lb.priority = priority;
2368 }
2369
2370 void lb_set_id(struct livebox *handler, const char *id)
2371 {
2372         if (handler->id)
2373                 free(handler->id);
2374
2375         handler->id = strdup(id);
2376         if (!handler->id)
2377                 ErrPrint("Error: %s\n", strerror(errno));
2378
2379         if (handler->filename)
2380                 free(handler->filename);
2381
2382         handler->filename = get_file_kept_in_safe(id);
2383         if (!handler->filename) {
2384                 handler->filename = strdup(util_uri_to_path(id));
2385                 if (!handler->filename)
2386                         ErrPrint("Error: %s\n", strerror(errno));
2387         }
2388 }
2389
2390 int lb_set_lb_fb(struct livebox *handler, const char *filename)
2391 {
2392         struct fb_info *fb;
2393
2394         if (!handler)
2395                 return -EINVAL;
2396
2397         fb = handler->lb.data.fb;
2398         if (fb && !strcmp(fb_id(fb), filename)) /*!< BUFFER is not changed, */
2399                 return 0;
2400
2401         handler->lb.data.fb = NULL;
2402
2403         if (!filename || filename[0] == '\0') {
2404                 if (fb)
2405                         fb_destroy(fb);
2406                 return 0;
2407         }
2408
2409         handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
2410         if (!handler->lb.data.fb) {
2411                 ErrPrint("Faield to create a FB\n");
2412                 if (fb)
2413                         fb_destroy(fb);
2414                 return -EFAULT;
2415         }
2416
2417         if (fb)
2418                 fb_destroy(fb);
2419
2420         return 0;
2421 }
2422
2423 int lb_set_pd_fb(struct livebox *handler, const char *filename)
2424 {
2425         struct fb_info *fb;
2426
2427         if (!handler)
2428                 return -EINVAL;
2429
2430         fb = handler->pd.data.fb;
2431         if (fb && !strcmp(fb_id(fb), filename)) {
2432                 /* BUFFER is not changed, just update the content */
2433                 return -EEXIST;
2434         }
2435         handler->pd.data.fb = NULL;
2436
2437         if (!filename || filename[0] == '\0') {
2438                 if (fb)
2439                         fb_destroy(fb);
2440                 return 0;
2441         }
2442
2443         handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
2444         if (!handler->pd.data.fb) {
2445                 ErrPrint("Failed to create a FB\n");
2446                 if (fb)
2447                         fb_destroy(fb);
2448                 return -EFAULT;
2449         }
2450
2451         if (fb)
2452                 fb_destroy(fb);
2453         return 0;
2454 }
2455
2456 struct fb_info *lb_get_lb_fb(struct livebox *handler)
2457 {
2458         return handler->lb.data.fb;
2459 }
2460
2461 struct fb_info *lb_get_pd_fb(struct livebox *handler)
2462 {
2463         return handler->pd.data.fb;
2464 }
2465
2466 void lb_set_user(struct livebox *handler, int user)
2467 {
2468         handler->is_user = user;
2469 }
2470
2471 void lb_set_pinup(struct livebox *handler, int pinup_supported)
2472 {
2473         handler->lb.pinup_supported = pinup_supported;
2474 }
2475
2476 void lb_set_text_lb(struct livebox *handler)
2477 {
2478         handler->lb.type = _LB_TYPE_TEXT;
2479 }
2480
2481 void lb_set_text_pd(struct livebox *handler)
2482 {
2483         handler->pd.type = _PD_TYPE_TEXT;
2484 }
2485
2486 int lb_text_lb(struct livebox *handler)
2487 {
2488         return handler->lb.type == _LB_TYPE_TEXT;
2489 }
2490
2491 int lb_text_pd(struct livebox *handler)
2492 {
2493         return handler->pd.type == _PD_TYPE_TEXT;
2494 }
2495
2496 void lb_set_period(struct livebox *handler, double period)
2497 {
2498         handler->lb.period = period;
2499 }
2500
2501 struct livebox *lb_ref(struct livebox *handler)
2502 {
2503         if (!handler)
2504                 return NULL;
2505
2506         handler->refcnt++;
2507         return handler;
2508 }
2509
2510 struct livebox *lb_unref(struct livebox *handler)
2511 {
2512         if (!handler)
2513                 return NULL;
2514
2515         handler->refcnt--;
2516         if (handler->refcnt > 0)
2517                 return handler;
2518
2519         dlist_remove_data(s_info.livebox_list, handler);
2520
2521         handler->state = DESTROYED;
2522         free(handler->cluster);
2523         free(handler->category);
2524         free(handler->id);
2525         free(handler->pkgname);
2526         free(handler->filename);
2527         free(handler->lb.auto_launch);
2528
2529         if (handler->lb.data.fb) {
2530                 fb_destroy(handler->lb.data.fb);
2531                 handler->lb.data.fb = NULL;
2532         }
2533
2534         if (handler->pd.data.fb) {
2535                 fb_destroy(handler->pd.data.fb);
2536                 handler->pd.data.fb = NULL;
2537         }
2538
2539         free(handler);
2540         return NULL;
2541 }
2542
2543 int lb_send_delete(struct livebox *handler, ret_cb_t cb, void *data)
2544 {
2545         struct packet *packet;
2546
2547         if (!cb && !!data) {
2548                 ErrPrint("Invalid argument\n");
2549                 return -EINVAL;
2550         }
2551
2552         if (handler->deleted_cb) {
2553                 ErrPrint("Already in-progress\n");
2554                 return -EINPROGRESS;
2555         }
2556
2557         packet = packet_create("delete", "ss", handler->pkgname, handler->id);
2558         if (!packet) {
2559                 ErrPrint("Failed to build a param\n");
2560                 if (cb)
2561                         cb(handler, -EFAULT, data);
2562
2563                 return -EFAULT;
2564         }
2565
2566         if (!cb)
2567                 cb = default_delete_cb;
2568
2569         return master_rpc_async_request(handler, packet, 0, del_ret_cb, create_cb_info(cb, data));
2570 }
2571
2572 /* End of a file */