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