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