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