Reduce the debugging logs
[apps/livebox/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("CREATE_PD\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                                 ErrPrint("Box is not support the mouse event\n");
1425                                 return LB_STATUS_ERROR_INVALID;
1426                         }
1427
1428                         if (!handler->lb.data.fb) {
1429                                 ErrPrint("Handler is not valid\n");
1430                                 return LB_STATUS_ERROR_INVALID;
1431                         }
1432
1433                         if (type & CONTENT_EVENT_MOUSE_MOVE) {
1434                                 if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT)
1435                                         return LB_STATUS_ERROR_BUSY;
1436                         } else if (type & CONTENT_EVENT_MOUSE_SET) {
1437                                 flag = 0;
1438                         }
1439                 }
1440
1441                 if (flag) {
1442                         w = handler->lb.width;
1443                         h = handler->lb.height;
1444                         handler->lb.x = x;
1445                         handler->lb.y = y;
1446                 }
1447                 *ptr++ = 'l';
1448                 *ptr++ = 'b';
1449         } else {
1450                 ErrPrint("Invalid event type\n");
1451                 return LB_STATUS_ERROR_INVALID;
1452         }
1453
1454         /*!
1455          * Must be short than 29 bytes.
1456          */
1457         switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
1458         case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
1459                 strcpy(ptr, "_mouse_enter");
1460                 break;
1461         case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
1462                 strcpy(ptr, "_mouse_leave");
1463                 break;
1464         case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
1465                 strcpy(ptr, "_mouse_up");
1466                 break;
1467         case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
1468                 strcpy(ptr, "_mouse_down");
1469                 break;
1470         case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
1471                 strcpy(ptr, "_mouse_move");
1472                 break;
1473         case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
1474                 strcpy(ptr, "_mouse_set");
1475                 break;
1476         case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
1477                 strcpy(ptr, "_mouse_unset");
1478                 break;
1479         case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
1480                 strcpy(ptr, "_key_down");
1481                 break;
1482         case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
1483                 strcpy(ptr, "_key_up");
1484                 break;
1485         default:
1486                 ErrPrint("Invalid event type\n");
1487                 return LB_STATUS_ERROR_INVALID;
1488         }
1489
1490         return send_mouse_event(handler, cmd, x * w, y * h);
1491 }
1492
1493 EAPI const char *livebox_filename(struct livebox *handler)
1494 {
1495         if (!handler) {
1496                 ErrPrint("Handler is NIL\n");
1497                 return NULL;
1498         }
1499
1500         if (handler->state != CREATE || !handler->id) {
1501                 ErrPrint("Handler is not valid\n");
1502                 return NULL;
1503         }
1504
1505         if (handler->filename)
1506                 return handler->filename;
1507
1508         /* Oooops */
1509         return util_uri_to_path(handler->id);
1510 }
1511
1512 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
1513 {
1514         int _w;
1515         int _h;
1516
1517         if (!handler) {
1518                 ErrPrint("Handler is NIL\n");
1519                 return LB_STATUS_ERROR_INVALID;
1520         }
1521
1522         if (handler->state != CREATE || !handler->id) {
1523                 ErrPrint("Handler is not valid\n");
1524                 return LB_STATUS_ERROR_INVALID;
1525         }
1526
1527         if (!w)
1528                 w = &_w;
1529         if (!h)
1530                 h = &_h;
1531
1532         if (!handler->is_pd_created) {
1533                 *w = handler->pd.default_width;
1534                 *h = handler->pd.default_height;
1535         } else {
1536                 *w = handler->pd.width;
1537                 *h = handler->pd.height;
1538         }
1539
1540         return LB_STATUS_SUCCESS;
1541 }
1542
1543 EAPI int livebox_size(struct livebox *handler)
1544 {
1545         int w;
1546         int h;
1547
1548         if (!handler) {
1549                 ErrPrint("Handler is NIL\n");
1550                 return LB_STATUS_ERROR_INVALID;
1551         }
1552
1553         if (handler->state != CREATE || !handler->id) {
1554                 ErrPrint("Handler is not valid\n");
1555                 return LB_STATUS_ERROR_INVALID;
1556         }
1557
1558         w = handler->lb.width;
1559         h = handler->lb.height;
1560
1561         switch (handler->lb.type) {
1562         case _LB_TYPE_BUFFER:
1563         case _LB_TYPE_SCRIPT:
1564                 if (!fb_is_created(handler->lb.data.fb)) {
1565                         w = 0;
1566                         h = 0;
1567                 }
1568                 break;
1569         default:
1570                 break;
1571         }
1572
1573         return livebox_service_size_type(w, h);
1574 }
1575
1576 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
1577 {
1578         struct packet *packet;
1579         int ret;
1580
1581         if (!handler) {
1582                 ErrPrint("Handler is NIL\n");
1583                 return LB_STATUS_ERROR_INVALID;
1584         }
1585
1586         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1587                 ErrPrint("Invalid argument\n");
1588                 return LB_STATUS_ERROR_INVALID;
1589         }
1590
1591         if (handler->group_changed_cb) {
1592                 ErrPrint("Previous group changing request is not finished yet\n");
1593                 return LB_STATUS_ERROR_BUSY;
1594         }
1595
1596         if (!handler->is_user) {
1597                 ErrPrint("CA Livebox is not able to change the group\n");
1598                 return LB_STATUS_ERROR_PERMISSION;
1599         }
1600
1601         if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
1602                 DbgPrint("No changes\n");
1603                 return LB_STATUS_ERROR_ALREADY;
1604         }
1605
1606         packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
1607         if (!packet) {
1608                 ErrPrint("Failed to build a param\n");
1609                 return LB_STATUS_ERROR_FAULT;
1610         }
1611
1612         if (!cb)
1613                 cb = default_group_changed_cb;
1614
1615         ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
1616         if (ret == LB_STATUS_SUCCESS) {
1617                 handler->group_changed_cb = cb;
1618                 handler->group_cbdata = data; 
1619         }
1620
1621         return ret;
1622 }
1623
1624 EAPI int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category)
1625 {
1626         if (!handler) {
1627                 ErrPrint("Handler is NIL\n");
1628                 return LB_STATUS_ERROR_INVALID;
1629         }
1630
1631         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1632                 ErrPrint("Invalid argument\n");
1633                 return LB_STATUS_ERROR_INVALID;
1634         }
1635
1636         *cluster = handler->cluster;
1637         *category = handler->category;
1638         return LB_STATUS_SUCCESS;
1639 }
1640
1641 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
1642 {
1643         register int i;
1644         register int j;
1645
1646         if (!handler || !size_list) {
1647                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
1648                 return LB_STATUS_ERROR_INVALID;
1649         }
1650
1651         if (!cnt || handler->state != CREATE || !handler->id) {
1652                 ErrPrint("Handler is not valid\n");
1653                 return LB_STATUS_ERROR_INVALID;
1654         }
1655
1656         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
1657                 if (handler->lb.size_list & (0x01 << i)) {
1658                         if (j == *cnt)
1659                                 break;
1660
1661                         size_list[j++] = (0x01 << i);
1662                 }
1663         }
1664
1665         *cnt = j;
1666         return LB_STATUS_SUCCESS;
1667 }
1668
1669 EAPI const char *livebox_pkgname(struct livebox *handler)
1670 {
1671         if (!handler) {
1672                 ErrPrint("Handler is NIL\n");
1673                 return NULL;
1674         }
1675
1676         if (handler->state != CREATE) {
1677                 ErrPrint("Handler is not valid\n");
1678                 return NULL;
1679         }
1680
1681         return handler->pkgname;
1682 }
1683
1684 EAPI double livebox_priority(struct livebox *handler)
1685 {
1686         if (!handler) {
1687                 ErrPrint("Handler is NIL\n");
1688                 return 0.0f;
1689         }
1690
1691         if (handler->state != CREATE || !handler->id) {
1692                 ErrPrint("Handler is not valid (%p)\n", handler);
1693                 return -1.0f;
1694         }
1695
1696         return handler->lb.priority;
1697 }
1698
1699 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
1700 {
1701         struct packet *packet;
1702         struct cb_info *cbinfo;
1703         int ret;
1704
1705         packet = packet_create("delete_cluster", "s", cluster);
1706         if (!packet) {
1707                 ErrPrint("Failed to build a param\n");
1708                 return LB_STATUS_ERROR_FAULT;
1709         }
1710
1711         cbinfo = create_cb_info(cb, data);
1712         if (!cbinfo) {
1713                 packet_destroy(packet);
1714                 return LB_STATUS_ERROR_FAULT;
1715         }
1716
1717         ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
1718         if (ret < 0)
1719                 destroy_cb_info(cbinfo);
1720
1721         return ret;
1722 }
1723
1724 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
1725 {
1726         struct packet *packet;
1727         struct cb_info *cbinfo;
1728         int ret;
1729
1730         packet = packet_create("delete_category", "ss", cluster, category);
1731         if (!packet) {
1732                 ErrPrint("Failed to build a param\n");
1733                 return LB_STATUS_ERROR_FAULT;
1734         }
1735
1736         cbinfo = create_cb_info(cb, data);
1737         if (!cbinfo) {
1738                 packet_destroy(packet);
1739                 return LB_STATUS_ERROR_FAULT;
1740         }
1741
1742         ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
1743         if (ret < 0)
1744                 destroy_cb_info(cbinfo);
1745
1746         return ret;
1747 }
1748
1749 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
1750 {
1751         if (!handler) {
1752                 ErrPrint("Handler is NIL\n");
1753                 return LB_TYPE_INVALID;
1754         }
1755
1756         if (handler->state != CREATE || !handler->id) {
1757                 ErrPrint("Handler is not valid\n");
1758                 return LB_TYPE_INVALID;
1759         }
1760
1761         switch (handler->lb.type) {
1762         case _LB_TYPE_FILE:
1763                 return LB_TYPE_IMAGE;
1764         case _LB_TYPE_BUFFER:
1765         case _LB_TYPE_SCRIPT:
1766                 {
1767                         const char *id;
1768                         id = fb_id(handler->lb.data.fb);
1769                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1770                                 return LB_TYPE_PIXMAP;
1771                 }
1772                 return LB_TYPE_BUFFER;
1773         case _LB_TYPE_TEXT:
1774                 return LB_TYPE_TEXT;
1775         default:
1776                 break;
1777         }
1778
1779         return LB_TYPE_INVALID;
1780 }
1781
1782 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
1783 {
1784         if (!handler) {
1785                 ErrPrint("Handler is NIL\n");
1786                 return PD_TYPE_INVALID;
1787         }
1788
1789         if (handler->state != CREATE || !handler->id) {
1790                 ErrPrint("Handler is not valid\n");
1791                 return PD_TYPE_INVALID;
1792         }
1793
1794         switch (handler->pd.type) {
1795         case _PD_TYPE_TEXT:
1796                 return PD_TYPE_TEXT;
1797         case _PD_TYPE_BUFFER:
1798         case _PD_TYPE_SCRIPT:
1799                 {
1800                         const char *id;
1801                         id = fb_id(handler->pd.data.fb);
1802                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1803                                 return PD_TYPE_PIXMAP;
1804                 }
1805                 return PD_TYPE_BUFFER;
1806         default:
1807                 break;
1808         }
1809
1810         return PD_TYPE_INVALID;
1811 }
1812
1813 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1814 {
1815         if (!handler) {
1816                 ErrPrint("Handler is NIL\n");
1817                 return LB_STATUS_ERROR_INVALID;
1818         }
1819
1820         if (handler->state != CREATE) {
1821                 ErrPrint("Handler is not valid\n");
1822                 return LB_STATUS_ERROR_INVALID;
1823         }
1824
1825         memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
1826         return LB_STATUS_SUCCESS;
1827 }
1828
1829 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1830 {
1831         if (!handler) {
1832                 ErrPrint("Handler is NIL\n");
1833                 return LB_STATUS_ERROR_INVALID;
1834         }
1835
1836         if (handler->state != CREATE) {
1837                 ErrPrint("Handler is not valid\n");
1838                 return LB_STATUS_ERROR_INVALID;
1839         }
1840
1841         memcpy(&handler->lb.data.ops, ops, sizeof(*ops));
1842         return LB_STATUS_SUCCESS;
1843 }
1844
1845 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1846 {
1847         struct packet *packet;
1848         struct cb_info *cbinfo;
1849         const char *id;
1850         int ret;
1851
1852         if (!handler) {
1853                 ErrPrint("Handler is NIL\n");
1854                 return LB_STATUS_ERROR_INVALID;
1855         }
1856
1857         if (handler->state != CREATE || !handler->id) {
1858                 ErrPrint("Invalid handle\n");
1859                 return LB_STATUS_ERROR_INVALID;
1860         }
1861
1862         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1863                 ErrPrint("Handler is not valid type\n");
1864                 return LB_STATUS_ERROR_INVALID;
1865         }
1866
1867         id = fb_id(handler->lb.data.fb);
1868         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1869                 return LB_STATUS_ERROR_INVALID;
1870
1871         packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
1872         if (!packet) {
1873                 ErrPrint("Failed to build a param\n");
1874                 return LB_STATUS_ERROR_FAULT;
1875         }
1876
1877         cbinfo = create_cb_info(cb, data);
1878         if (!cbinfo) {
1879                 packet_destroy(packet);
1880                 return LB_STATUS_ERROR_FAULT;
1881         }
1882
1883         ret = master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, cbinfo);
1884         if (ret < 0)
1885                 destroy_cb_info(cbinfo);
1886
1887         return ret;
1888 }
1889
1890 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
1891 {
1892         struct packet *packet;
1893
1894         if (!handler) {
1895                 ErrPrint("Handler is NIL\n");
1896                 return LB_STATUS_ERROR_INVALID;
1897         }
1898
1899         if (handler->state != CREATE || !handler->id) {
1900                 ErrPrint("Invalid handle\n");
1901                 return LB_STATUS_ERROR_INVALID;
1902         }
1903
1904         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1905                 ErrPrint("Handler is not valid type\n");
1906                 return LB_STATUS_ERROR_INVALID;
1907         }
1908
1909         packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1910         if (!packet) {
1911                 ErrPrint("Failed to build a param\n");
1912                 return LB_STATUS_ERROR_INVALID;
1913         }
1914
1915         return master_rpc_request_only(handler, packet);
1916 }
1917
1918 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1919 {
1920         struct packet *packet;
1921         struct cb_info *cbinfo;
1922         const char *id;
1923         int ret;
1924
1925         if (!handler) {
1926                 ErrPrint("Handler is NIL\n");
1927                 return LB_STATUS_ERROR_INVALID;
1928         }
1929
1930         if (handler->state != CREATE || !handler->id) {
1931                 ErrPrint("Invalid handle\n");
1932                 return LB_STATUS_ERROR_INVALID;
1933         }
1934
1935         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1936                 ErrPrint("Handler is not valid type\n");
1937                 return LB_STATUS_ERROR_INVALID;
1938         }
1939
1940         id = fb_id(handler->pd.data.fb);
1941         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1942                 return LB_STATUS_ERROR_INVALID;
1943
1944         packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
1945         if (!packet) {
1946                 ErrPrint("Failed to build a param\n");
1947                 return LB_STATUS_ERROR_FAULT;
1948         }
1949
1950         cbinfo = create_cb_info(cb, data);
1951         if (!cbinfo) {
1952                 packet_destroy(packet);
1953                 return LB_STATUS_ERROR_FAULT;
1954         }
1955
1956         ret = master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, cbinfo);
1957         if (ret < 0)
1958                 destroy_cb_info(cbinfo);
1959
1960         return ret;
1961 }
1962
1963 EAPI int livebox_pd_pixmap(const struct livebox *handler)
1964 {
1965         const char *id;
1966         int pixmap = 0;
1967
1968         if (!handler) {
1969                 ErrPrint("Handler is NIL\n");
1970                 return 0;
1971         }
1972
1973         if (handler->state != CREATE || !handler->id) {
1974                 ErrPrint("Invalid handler\n");
1975                 return 0;
1976         }
1977
1978         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1979                 ErrPrint("Invalid handler\n");
1980                 return 0;
1981         }
1982
1983         id = fb_id(handler->pd.data.fb);
1984         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
1985                 ErrPrint("PIXMAP Id is not valid\n");
1986                 return 0;
1987         }
1988
1989         return pixmap;
1990 }
1991
1992 EAPI int livebox_lb_pixmap(const struct livebox *handler)
1993 {
1994         const char *id;
1995         int pixmap = 0;
1996
1997         if (!handler) {
1998                 ErrPrint("Handler is NIL\n");
1999                 return 0;
2000         }
2001
2002         if (handler->state != CREATE || !handler->id) {
2003                 ErrPrint("Invalid handler\n");
2004                 return 0;
2005         }
2006
2007         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2008                 ErrPrint("Invalid handler\n");
2009                 return 0;
2010         }
2011
2012         id = fb_id(handler->lb.data.fb);
2013         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
2014                 ErrPrint("PIXMAP Id is not valid\n");
2015                 return 0;
2016         }
2017
2018         return pixmap;
2019 }
2020
2021 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
2022 {
2023         struct packet *packet;
2024
2025         if (!handler) {
2026                 ErrPrint("Handler is NIL\n");
2027                 return LB_STATUS_ERROR_INVALID;
2028         }
2029
2030         if (handler->state != CREATE || !handler->id) {
2031                 ErrPrint("Invalid handle\n");
2032                 return LB_STATUS_ERROR_INVALID;
2033         }
2034
2035         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2036                 ErrPrint("Handler is not valid type\n");
2037                 return LB_STATUS_ERROR_INVALID;
2038         }
2039
2040         packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
2041         if (!packet) {
2042                 ErrPrint("Failed to build a param\n");
2043                 return LB_STATUS_ERROR_FAULT;
2044         }
2045
2046         return master_rpc_request_only(handler, packet);
2047 }
2048
2049 EAPI void *livebox_acquire_fb(struct livebox *handler)
2050 {
2051         if (!handler) {
2052                 ErrPrint("Handler is NIL\n");
2053                 return NULL;
2054         }
2055
2056         if (handler->state != CREATE || !handler->id) {
2057                 ErrPrint("Invalid handle\n");
2058                 return NULL;
2059         }
2060
2061         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2062                 ErrPrint("Handler is not valid type\n");
2063                 return NULL;
2064         }
2065
2066         return fb_acquire_buffer(handler->lb.data.fb);
2067 }
2068
2069 EAPI int livebox_release_fb(void *buffer)
2070 {
2071         return fb_release_buffer(buffer);
2072 }
2073
2074 EAPI int livebox_fb_refcnt(void *buffer)
2075 {
2076         return fb_refcnt(buffer);
2077 }
2078
2079 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
2080 {
2081         if (!handler) {
2082                 ErrPrint("Handler is NIL\n");
2083                 return NULL;
2084         }
2085
2086         if (handler->state != CREATE || !handler->id) {
2087                 ErrPrint("Invalid handler\n");
2088                 return NULL;
2089         }
2090
2091         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2092                 ErrPrint("Handler is not valid type\n");
2093                 return NULL;
2094         }
2095
2096         return fb_acquire_buffer(handler->pd.data.fb);
2097 }
2098
2099 EAPI int livebox_release_pdfb(void *buffer)
2100 {
2101         return fb_release_buffer(buffer);
2102 }
2103
2104 EAPI int livebox_pdfb_refcnt(void *buffer)
2105 {
2106         return fb_refcnt(buffer);
2107 }
2108
2109 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
2110 {
2111         if (!handler) {
2112                 ErrPrint("Handler is NIL\n");
2113                 return LB_STATUS_ERROR_INVALID;
2114         }
2115
2116         if (handler->state != CREATE || !handler->id) {
2117                 ErrPrint("Handler is not valid\n");
2118                 return LB_STATUS_ERROR_INVALID;
2119         }
2120
2121         return fb_size(handler->pd.data.fb);
2122 }
2123
2124 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
2125 {
2126         if (!handler) {
2127                 ErrPrint("Handler is NIL\n");
2128                 return LB_STATUS_ERROR_INVALID;
2129         }
2130
2131         if (handler->state != CREATE || !handler->id) {
2132                 ErrPrint("Handler is not valid\n");
2133                 return LB_STATUS_ERROR_INVALID;
2134         }
2135
2136         return fb_size(handler->lb.data.fb);
2137 }
2138
2139 EAPI int livebox_is_user(struct livebox *handler)
2140 {
2141         if (!handler) {
2142                 ErrPrint("Handler is NIL\n");
2143                 return LB_STATUS_ERROR_INVALID;
2144         }
2145
2146         if (handler->state != CREATE) {
2147                 ErrPrint("Handler is invalid\n");
2148                 return LB_STATUS_ERROR_INVALID;
2149         }
2150
2151         return handler->is_user;
2152 }
2153
2154 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
2155 {
2156         struct packet *packet;
2157         int ret;
2158
2159         if (!handler) {
2160                 ErrPrint("Handler is NIL\n");
2161                 return LB_STATUS_ERROR_INVALID;
2162         }
2163
2164         if (handler->state != CREATE || !handler->id) {
2165                 ErrPrint("Handler is not valid\n");
2166                 return LB_STATUS_ERROR_INVALID;
2167         }
2168
2169         if (handler->pinup_cb) {
2170                 ErrPrint("Previous pinup request is not finished\n");
2171                 return LB_STATUS_ERROR_BUSY;
2172         }
2173
2174         if (handler->is_pinned_up == flag) {
2175                 DbgPrint("No changes\n");
2176                 return LB_STATUS_ERROR_ALREADY;
2177         }
2178
2179         packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
2180         if (!packet) {
2181                 ErrPrint("Failed to build a param\n");
2182                 return LB_STATUS_ERROR_FAULT;
2183         }
2184
2185         if (!cb)
2186                 cb = default_pinup_cb;
2187
2188         ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
2189         if (ret == LB_STATUS_SUCCESS) {
2190                 handler->pinup_cb = cb;
2191                 handler->pinup_cbdata = data;
2192         }
2193
2194         return ret;
2195 }
2196
2197 EAPI int livebox_is_pinned_up(struct livebox *handler)
2198 {
2199         if (!handler) {
2200                 ErrPrint("Handler is NIL\n");
2201                 return LB_STATUS_ERROR_INVALID;
2202         }
2203
2204         if (handler->state != CREATE || !handler->id)
2205                 return LB_STATUS_ERROR_INVALID;
2206
2207         return handler->is_pinned_up;
2208 }
2209
2210 EAPI int livebox_has_pinup(struct livebox *handler)
2211 {
2212         if (!handler) {
2213                 ErrPrint("Handler is NIL\n");
2214                 return LB_STATUS_ERROR_INVALID;
2215         }
2216
2217         if (handler->state != CREATE || !handler->id)
2218                 return LB_STATUS_ERROR_INVALID;
2219
2220         return handler->lb.pinup_supported;
2221 }
2222
2223 EAPI int livebox_set_data(struct livebox *handler, void *data)
2224 {
2225         if (!handler) {
2226                 ErrPrint("Handler is NIL\n");
2227                 return LB_STATUS_ERROR_INVALID;
2228         }
2229
2230         if (handler->state != CREATE)
2231                 return LB_STATUS_ERROR_INVALID;
2232
2233         handler->data = data;
2234         return LB_STATUS_SUCCESS;
2235 }
2236
2237 EAPI void *livebox_get_data(struct livebox *handler)
2238 {
2239         if (!handler) {
2240                 ErrPrint("Handler is NIL\n");
2241                 return NULL;
2242         }
2243
2244         if (handler->state != CREATE)
2245                 return NULL;
2246
2247         return handler->data;
2248 }
2249
2250 EAPI int livebox_is_exists(const char *pkgname)
2251 {
2252         char *lb;
2253
2254         lb = lb_pkgname(pkgname);
2255         if (lb) {
2256                 free(lb);
2257                 return 1;
2258         }
2259
2260         return 0;
2261 }
2262
2263 EAPI const char *livebox_content(struct livebox *handler)
2264 {
2265         if (!handler) {
2266                 ErrPrint("Handler is NIL\n");
2267                 return NULL;
2268         }
2269
2270         if (handler->state != CREATE)
2271                 return NULL;
2272
2273         return handler->content;
2274 }
2275
2276 EAPI const char *livebox_category_title(struct livebox *handler)
2277 {
2278         if (!handler) {
2279                 ErrPrint("Handler is NIL\n");
2280                 return NULL;
2281         }
2282
2283         if (handler->state != CREATE)
2284                 return NULL;
2285
2286         return handler->title;
2287 }
2288
2289 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)
2290 {
2291         struct packet *packet;
2292         struct cb_info *cbinfo;
2293         int ret;
2294
2295         if (!handler) {
2296                 ErrPrint("Handler is NIL\n");
2297                 return LB_STATUS_ERROR_INVALID;
2298         }
2299
2300         if ((handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || handler->state != CREATE || !handler->id) {
2301                 ErrPrint("Handler is not valid\n");
2302                 return LB_STATUS_ERROR_INVALID;
2303         }
2304
2305         if (!emission)
2306                 emission = "";
2307
2308         if (!source)
2309                 source = "";
2310
2311         packet = packet_create("text_signal", "ssssdddd",
2312                                 handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
2313         if (!packet) {
2314                 ErrPrint("Failed to build a param\n");
2315                 return LB_STATUS_ERROR_FAULT;
2316         }
2317
2318         cbinfo = create_cb_info(cb, data);
2319         if (!cbinfo) {
2320                 packet_destroy(packet);
2321                 return LB_STATUS_ERROR_FAULT;
2322         }
2323
2324         ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
2325         if (ret < 0)
2326                 destroy_cb_info(cbinfo);
2327
2328         return LB_STATUS_ERROR_FAULT;
2329 }
2330
2331 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
2332 {
2333         struct packet *packet;
2334
2335         /*!
2336          * \TODO
2337          * Validate the group info using DB
2338          * If the group info is not valid, do not send this request
2339          */
2340
2341         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
2342         if (!packet) {
2343                 ErrPrint("Failed to create a packet\n");
2344                 return LB_STATUS_ERROR_FAULT;
2345         }
2346
2347         return master_rpc_request_only(NULL, packet);
2348 }
2349
2350 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
2351 {
2352         struct packet *packet;
2353
2354         /*!
2355          * \TODO
2356          * Validate the group info using DB
2357          * If the group info is not valid, do not send this request
2358          * AND Check the subscribed or not too
2359          */
2360
2361         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
2362         if (!packet) {
2363                 ErrPrint("Failed to create a packet\n");
2364                 return LB_STATUS_ERROR_FAULT;
2365         }
2366
2367         return master_rpc_request_only(NULL, packet);
2368 }
2369
2370 EAPI int livebox_refresh(struct livebox *handler)
2371 {
2372         struct packet *packet;
2373
2374         if (!handler) {
2375                 ErrPrint("Hnalder is NIL\n");
2376                 return LB_STATUS_ERROR_INVALID;
2377         }
2378
2379         if (handler->state != CREATE || !handler->id)
2380                 return LB_STATUS_ERROR_INVALID;
2381
2382         packet = packet_create_noack("update", "ss", handler->pkgname, handler->id);
2383         if (!packet) {
2384                 ErrPrint("Failed to create a packet\n");
2385                 return LB_STATUS_ERROR_FAULT;
2386         }
2387
2388         return master_rpc_request_only(handler, packet);
2389 }
2390
2391 EAPI int livebox_refresh_group(const char *cluster, const char *category)
2392 {
2393         struct packet *packet;
2394
2395         if (!cluster || !category) {
2396                 ErrPrint("Invalid argument\n");
2397                 return LB_STATUS_ERROR_INVALID;
2398         }
2399
2400         packet = packet_create_noack("refresh_group", "ss", cluster, category);
2401         if (!packet) {
2402                 ErrPrint("Failed to create a packet\n");
2403                 return LB_STATUS_ERROR_FAULT;
2404         }
2405
2406         return master_rpc_request_only(NULL, packet);
2407 }
2408
2409 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
2410 {
2411         struct packet *packet;
2412         int ret;
2413
2414         if (!handler) {
2415                 ErrPrint("Handler is NIL\n");
2416                 return LB_STATUS_ERROR_INVALID;
2417         }
2418
2419         if (handler->state != CREATE || !handler->id)
2420                 return LB_STATUS_ERROR_INVALID;
2421
2422         if (!handler->is_user) {
2423                 /* System cluster livebox cannot be changed its visible states */
2424                 if (state == LB_HIDE_WITH_PAUSE) {
2425                         ErrPrint("CA Livebox is not able to change the visibility\n");
2426                         return LB_STATUS_ERROR_PERMISSION;
2427                 }
2428         }
2429
2430         if (handler->visible == state)
2431                 return LB_STATUS_ERROR_ALREADY;
2432
2433         packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
2434         if (!packet) {
2435                 ErrPrint("Failed to create a packet\n");
2436                 return LB_STATUS_ERROR_FAULT;
2437         }
2438
2439         ret = master_rpc_request_only(handler, packet);
2440         if (ret == 0)
2441                 handler->visible = state;
2442
2443         return ret;
2444 }
2445
2446 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
2447 {
2448         if (!handler) {
2449                 ErrPrint("Handler is NIL\n");
2450                 return LB_VISIBLE_ERROR;
2451         }
2452
2453         if (handler->state != CREATE || !handler->id)
2454                 return LB_VISIBLE_ERROR;
2455
2456         return handler->visible;
2457 }
2458
2459 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
2460 {
2461         void *pc = NULL;
2462         void *ps = NULL;
2463
2464         if (cluster) {
2465                 pc = strdup(cluster);
2466                 if (!pc) {
2467                         CRITICAL_LOG("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
2468                         return LB_STATUS_ERROR_MEMORY;
2469                 }
2470         }
2471
2472         if (category) {
2473                 ps = strdup(category);
2474                 if (!ps) {
2475                         CRITICAL_LOG("Heap: %s (category: %s)\n", strerror(errno), category);
2476                         free(pc);
2477                         return LB_STATUS_ERROR_MEMORY;
2478                 }
2479         }
2480
2481         if (handler->cluster)
2482                 free(handler->cluster);
2483
2484         if (handler->category)
2485                 free(handler->category);
2486
2487         handler->cluster = pc;
2488         handler->category = ps;
2489
2490         return LB_STATUS_SUCCESS;
2491 }
2492
2493 void lb_set_size(struct livebox *handler, int w, int h)
2494 {
2495         handler->lb.width = w;
2496         handler->lb.height = h;
2497 }
2498
2499 void lb_set_update_mode(struct livebox *handle, int active_mode)
2500 {
2501         handle->is_active_update = active_mode;
2502 }
2503
2504 void lb_set_pdsize(struct livebox *handler, int w, int h)
2505 {
2506         handler->pd.width = w;
2507         handler->pd.height = h;
2508 }
2509
2510 void lb_set_default_pdsize(struct livebox *handler, int w, int h)
2511 {
2512         handler->pd.default_width = w;
2513         handler->pd.default_height = h;
2514 }
2515
2516 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
2517 {
2518         struct dlist *l;
2519         struct dlist *n;
2520         struct fault_info *info;
2521
2522         dlist_foreach_safe(s_info.fault_list, l, n, info) {
2523                 if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE)
2524                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
2525         }
2526 }
2527
2528 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
2529 {
2530         struct dlist *l;
2531         struct dlist *n;
2532         struct event_info *info;
2533
2534         dlist_foreach_safe(s_info.event_list, l, n, info) {
2535                 if (info->handler(handler, event, info->user_data) == EXIT_FAILURE)
2536                         s_info.event_list = dlist_remove(s_info.event_list, l);
2537         }
2538 }
2539
2540 struct livebox *lb_find_livebox(const char *pkgname, const char *id)
2541 {
2542         struct dlist *l;
2543         struct livebox *handler;
2544
2545         dlist_foreach(s_info.livebox_list, l, handler) {
2546                 if (!handler->id)
2547                         continue;
2548
2549                 if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id))
2550                         return handler;
2551         }
2552
2553         return NULL;
2554 }
2555
2556 struct livebox *lb_find_livebox_by_timestamp(double timestamp)
2557 {
2558         struct dlist *l;
2559         struct livebox *handler;
2560
2561         dlist_foreach(s_info.livebox_list, l, handler) {
2562                 if (handler->timestamp == timestamp)
2563                         return handler;
2564         }
2565
2566         return NULL;
2567 }
2568
2569 static inline char *get_file_kept_in_safe(const char *id)
2570 {
2571         const char *path;
2572         char *new_path;
2573         int len;
2574         int base_idx;
2575
2576         path = util_uri_to_path(id);
2577         if (!path) {
2578                 ErrPrint("Invalid URI(%s)\n", id);
2579                 return NULL;
2580         }
2581
2582         /*!
2583          * \TODO: REMOVE ME
2584          */
2585         if (s_info.prevent_overwrite) {
2586                 new_path = strdup(path);
2587                 if (!new_path)
2588                         ErrPrint("Heap: %s\n", strerror(errno));
2589
2590                 return new_path;
2591         }
2592
2593
2594         len = strlen(path);
2595         base_idx = len - 1;
2596
2597         while (base_idx > 0 && path[base_idx] != '/') base_idx--;
2598         base_idx += (path[base_idx] == '/');
2599
2600         new_path = malloc(len + 10);
2601         if (!new_path) {
2602                 ErrPrint("Heap: %s\n", strerror(errno));
2603                 return NULL;
2604         }
2605
2606         strncpy(new_path, path, base_idx);
2607         snprintf(new_path + base_idx, len + 10 - base_idx, "reader/%s", path + base_idx);
2608         return new_path;
2609 }
2610
2611 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
2612 {
2613         struct livebox *handler;
2614
2615         handler = calloc(1, sizeof(*handler));
2616         if (!handler) {
2617                 ErrPrint("Failed to create a new livebox\n");
2618                 return NULL;
2619         }
2620
2621         handler->pkgname = strdup(pkgname);
2622         if (!handler->pkgname) {
2623                 ErrPrint("%s\n", strerror(errno));
2624                 free(handler);
2625                 return NULL;
2626         }
2627
2628         handler->id = strdup(id);
2629         if (!handler->id) {
2630                 ErrPrint("%s\n", strerror(errno));
2631                 free(handler->pkgname);
2632                 free(handler);
2633                 return NULL;
2634         }
2635
2636         handler->filename = get_file_kept_in_safe(id);
2637         if (!handler->filename) {
2638                 handler->filename = strdup(util_uri_to_path(id));
2639                 if (!handler->filename)
2640                         ErrPrint("Error: %s\n", strerror(errno));
2641         }
2642
2643         handler->timestamp = timestamp;
2644         handler->lb.type = _LB_TYPE_FILE;
2645         handler->pd.type = _PD_TYPE_SCRIPT;
2646         handler->state = CREATE;
2647         handler->visible = LB_SHOW;
2648
2649         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
2650         lb_ref(handler);
2651         return handler;
2652 }
2653
2654 int lb_delete_all(void)
2655 {
2656         struct dlist *l;
2657         struct dlist *n;
2658         struct livebox *handler;
2659
2660         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
2661                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
2662                 lb_unref(handler);
2663         }
2664
2665         return LB_STATUS_SUCCESS;
2666 }
2667
2668 int lb_set_content(struct livebox *handler, const char *content)
2669 {
2670         if (handler->content) {
2671                 free(handler->content);
2672                 handler->content = NULL;
2673         }
2674
2675         if (content) {
2676                 handler->content = strdup(content);
2677                 if (!handler->content) {
2678                         CRITICAL_LOG("Heap: %s (content: %s)\n", strerror(errno), content);
2679                         return LB_STATUS_ERROR_MEMORY;
2680                 }
2681         }
2682
2683         return LB_STATUS_SUCCESS;
2684 }
2685
2686 int lb_set_title(struct livebox *handler, const char *title)
2687 {
2688         if (handler->title) {
2689                 free(handler->title);
2690                 handler->title = NULL;
2691         }
2692
2693         if (title) {
2694                 handler->title = strdup(title);
2695                 if (!handler->title) {
2696                         CRITICAL_LOG("Heap: %s (title: %s)\n", strerror(errno), title);
2697                         return LB_STATUS_ERROR_MEMORY;
2698                 }
2699         }
2700
2701         return LB_STATUS_SUCCESS;
2702 }
2703
2704 void lb_set_size_list(struct livebox *handler, int size_list)
2705 {
2706         handler->lb.size_list = size_list;
2707 }
2708
2709 void lb_set_auto_launch(struct livebox *handler, const char *auto_launch)
2710 {
2711         if (!strlen(auto_launch))
2712                 return;
2713
2714         handler->lb.auto_launch = strdup(auto_launch);
2715         if (!handler->lb.auto_launch)
2716                 ErrPrint("Heap: %s\n", strerror(errno));
2717 }
2718
2719 void lb_set_priority(struct livebox *handler, double priority)
2720 {
2721         handler->lb.priority = priority;
2722 }
2723
2724 void lb_set_id(struct livebox *handler, const char *id)
2725 {
2726         if (handler->id)
2727                 free(handler->id);
2728
2729         handler->id = strdup(id);
2730         if (!handler->id)
2731                 ErrPrint("Error: %s\n", strerror(errno));
2732
2733         if (handler->filename)
2734                 free(handler->filename);
2735
2736         handler->filename = get_file_kept_in_safe(id);
2737         if (!handler->filename) {
2738                 handler->filename = strdup(util_uri_to_path(id));
2739                 if (!handler->filename)
2740                         ErrPrint("Error: %s\n", strerror(errno));
2741         }
2742 }
2743
2744 int lb_set_lb_fb(struct livebox *handler, const char *filename)
2745 {
2746         struct fb_info *fb;
2747
2748         if (!handler)
2749                 return LB_STATUS_ERROR_INVALID;
2750
2751         fb = handler->lb.data.fb;
2752         if (fb && !strcmp(fb_id(fb), filename)) /*!< BUFFER is not changed, */
2753                 return LB_STATUS_SUCCESS;
2754
2755         handler->lb.data.fb = NULL;
2756
2757         if (!filename || filename[0] == '\0') {
2758                 if (fb)
2759                         fb_destroy(fb);
2760                 return LB_STATUS_SUCCESS;
2761         }
2762
2763         handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
2764         if (!handler->lb.data.fb) {
2765                 ErrPrint("Faield to create a FB\n");
2766                 if (fb)
2767                         fb_destroy(fb);
2768                 return LB_STATUS_ERROR_FAULT;
2769         }
2770
2771         if (fb)
2772                 fb_destroy(fb);
2773
2774         return LB_STATUS_SUCCESS;
2775 }
2776
2777 int lb_set_pd_fb(struct livebox *handler, const char *filename)
2778 {
2779         struct fb_info *fb;
2780
2781         if (!handler)
2782                 return LB_STATUS_ERROR_INVALID;
2783
2784         fb = handler->pd.data.fb;
2785         if (fb && !strcmp(fb_id(fb), filename)) {
2786                 /* BUFFER is not changed, just update the content */
2787                 return LB_STATUS_ERROR_EXIST;
2788         }
2789         handler->pd.data.fb = NULL;
2790
2791         if (!filename || filename[0] == '\0') {
2792                 if (fb)
2793                         fb_destroy(fb);
2794                 return LB_STATUS_SUCCESS;
2795         }
2796
2797         handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
2798         if (!handler->pd.data.fb) {
2799                 ErrPrint("Failed to create a FB\n");
2800                 if (fb)
2801                         fb_destroy(fb);
2802                 return LB_STATUS_ERROR_FAULT;
2803         }
2804
2805         if (fb)
2806                 fb_destroy(fb);
2807         return LB_STATUS_SUCCESS;
2808 }
2809
2810 struct fb_info *lb_get_lb_fb(struct livebox *handler)
2811 {
2812         return handler->lb.data.fb;
2813 }
2814
2815 struct fb_info *lb_get_pd_fb(struct livebox *handler)
2816 {
2817         return handler->pd.data.fb;
2818 }
2819
2820 void lb_set_user(struct livebox *handler, int user)
2821 {
2822         handler->is_user = user;
2823 }
2824
2825 void lb_set_pinup(struct livebox *handler, int pinup_supported)
2826 {
2827         handler->lb.pinup_supported = pinup_supported;
2828 }
2829
2830 void lb_set_text_lb(struct livebox *handler)
2831 {
2832         handler->lb.type = _LB_TYPE_TEXT;
2833 }
2834
2835 void lb_set_text_pd(struct livebox *handler)
2836 {
2837         handler->pd.type = _PD_TYPE_TEXT;
2838 }
2839
2840 int lb_text_lb(struct livebox *handler)
2841 {
2842         return handler->lb.type == _LB_TYPE_TEXT;
2843 }
2844
2845 int lb_text_pd(struct livebox *handler)
2846 {
2847         return handler->pd.type == _PD_TYPE_TEXT;
2848 }
2849
2850 void lb_set_period(struct livebox *handler, double period)
2851 {
2852         handler->lb.period = period;
2853 }
2854
2855 struct livebox *lb_ref(struct livebox *handler)
2856 {
2857         if (!handler)
2858                 return NULL;
2859
2860         handler->refcnt++;
2861         return handler;
2862 }
2863
2864 struct livebox *lb_unref(struct livebox *handler)
2865 {
2866         if (!handler)
2867                 return NULL;
2868
2869         handler->refcnt--;
2870         if (handler->refcnt > 0)
2871                 return handler;
2872
2873         if (handler->created_cb) {
2874                 handler->created_cb(handler, LB_STATUS_ERROR_FAULT, handler->created_cbdata);
2875                 handler->created_cb = NULL;
2876                 handler->created_cbdata = NULL;
2877         }
2878
2879         if (handler->deleted_cb) {
2880                 handler->deleted_cb(handler, LB_STATUS_ERROR_FAULT, handler->deleted_cbdata);
2881                 handler->deleted_cb = NULL;
2882                 handler->deleted_cbdata = NULL;
2883         }
2884
2885         if (handler->pinup_cb) {
2886                 handler->pinup_cb(handler, LB_STATUS_ERROR_FAULT, handler->pinup_cbdata);
2887                 handler->pinup_cb = NULL;
2888                 handler->pinup_cbdata = NULL;
2889         }
2890
2891         if (handler->group_changed_cb) {
2892                 handler->group_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->group_cbdata);
2893                 handler->group_changed_cb = NULL;
2894                 handler->group_cbdata = NULL;
2895         }
2896
2897         if (handler->period_changed_cb) {
2898                 handler->period_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->period_cbdata);
2899                 handler->period_changed_cb = NULL;
2900                 handler->period_cbdata = NULL;
2901         }
2902
2903         if (handler->size_changed_cb) {
2904                 handler->size_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->size_cbdata);
2905                 handler->size_changed_cb = NULL;
2906                 handler->size_cbdata = NULL;
2907         }
2908
2909         if (handler->pd_created_cb) {
2910                 handler->pd_created_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_created_cbdata);
2911                 handler->pd_created_cb = NULL;
2912                 handler->pd_created_cbdata = NULL;
2913         }
2914
2915         if (handler->pd_destroyed_cb) {
2916                 handler->pd_destroyed_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_destroyed_cbdata);
2917                 handler->pd_destroyed_cb = NULL;
2918                 handler->pd_destroyed_cbdata = NULL;
2919         }
2920
2921         if (handler->update_mode_cb) {
2922                 handler->update_mode_cb(handler, LB_STATUS_ERROR_FAULT, handler->update_mode_cbdata);
2923                 handler->update_mode_cb = NULL;
2924                 handler->update_mode_cbdata = NULL;
2925         }
2926
2927         if (handler->access_event_cb) {
2928                 handler->access_event_cb(handler, LB_STATUS_ERROR_FAULT, handler->access_event_cbdata);
2929                 handler->access_event_cb = NULL;
2930                 handler->access_event_cbdata = NULL;
2931         }
2932
2933         if (handler->filename)
2934                 util_unlink(handler->filename);
2935
2936         dlist_remove_data(s_info.livebox_list, handler);
2937
2938         handler->state = DESTROYED;
2939         free(handler->cluster);
2940         free(handler->category);
2941         free(handler->id);
2942         free(handler->pkgname);
2943         free(handler->filename);
2944         free(handler->lb.auto_launch);
2945
2946         if (handler->lb.data.fb) {
2947                 fb_destroy(handler->lb.data.fb);
2948                 handler->lb.data.fb = NULL;
2949         }
2950
2951         if (handler->pd.data.fb) {
2952                 fb_destroy(handler->pd.data.fb);
2953                 handler->pd.data.fb = NULL;
2954         }
2955
2956         free(handler);
2957         return NULL;
2958 }
2959
2960 int lb_send_delete(struct livebox *handler, ret_cb_t cb, void *data)
2961 {
2962         struct packet *packet;
2963         struct cb_info *cbinfo;
2964         int ret;
2965
2966         if (!cb && !!data) {
2967                 ErrPrint("Invalid argument\n");
2968                 return LB_STATUS_ERROR_INVALID;
2969         }
2970
2971         if (handler->deleted_cb) {
2972                 ErrPrint("Already in-progress\n");
2973                 return LB_STATUS_ERROR_BUSY;
2974         }
2975
2976         packet = packet_create("delete", "ss", handler->pkgname, handler->id);
2977         if (!packet) {
2978                 ErrPrint("Failed to build a param\n");
2979                 if (cb)
2980                         cb(handler, LB_STATUS_ERROR_FAULT, data);
2981
2982                 return LB_STATUS_ERROR_FAULT;
2983         }
2984
2985         if (!cb)
2986                 cb = default_delete_cb;
2987
2988         cbinfo = create_cb_info(cb, data);
2989         if (!cbinfo) {
2990                 packet_destroy(packet);
2991                 return LB_STATUS_ERROR_FAULT;
2992         }
2993
2994         ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
2995         if (ret < 0)
2996                 destroy_cb_info(cbinfo);
2997
2998         return ret;
2999 }
3000
3001 EAPI int livebox_client_paused(void)
3002 {
3003         struct packet *packet;
3004
3005         packet = packet_create_noack("client_paused", "d", util_timestamp());
3006         if (!packet) {
3007                 ErrPrint("Failed to create a pause packet\n");
3008                 return LB_STATUS_ERROR_FAULT;
3009         }
3010
3011         return master_rpc_request_only(NULL, packet);
3012 }
3013
3014 EAPI int livebox_client_resumed(void)
3015 {
3016         struct packet *packet;
3017
3018         packet = packet_create_noack("client_resumed", "d", util_timestamp());
3019         if (!packet) {
3020                 ErrPrint("Failed to create a resume packet\n");
3021                 return LB_STATUS_ERROR_FAULT;
3022         }
3023
3024         return master_rpc_request_only(NULL, packet);
3025 }
3026
3027 /* End of a file */