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