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