Update PD_Destroy request API
[platform/framework/web/livebox-viewer.git] / src / livebox.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
21 #include <math.h>
22
23 #include <aul.h>
24 #include <dlog.h>
25
26 #include <com-core_packet.h>
27 #include <packet.h>
28 #include <livebox-service.h>
29 #include <livebox-errno.h>
30
31 #include "debug.h"
32 #include "fb.h"
33 #include "livebox.h"
34 #include "livebox_internal.h"
35 #include "dlist.h"
36 #include "util.h"
37 #include "master_rpc.h"
38 #include "client.h"
39 #include "critical_log.h"
40
41 #define EAPI __attribute__((visibility("default")))
42 #define MINIMUM_EVENT   s_info.event_filter
43
44 #if defined(FLOG)
45 FILE *__file_log_fp;
46 #endif
47
48 static struct info {
49         struct dlist *livebox_list;
50         struct dlist *event_list;
51         struct dlist *fault_list;
52         int init_count;
53         int prevent_overwrite;
54         double event_filter;
55 } s_info = {
56         .livebox_list = NULL,
57         .event_list = NULL,
58         .fault_list = NULL,
59         .init_count = 0,
60         .prevent_overwrite = 0,
61         .event_filter = 0.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         timestamp = util_timestamp();
1091         DbgPrint("CLICKED: %lf\n", timestamp);
1092
1093         if (!handler) {
1094                 ErrPrint("Handler is NIL\n");
1095                 return LB_STATUS_ERROR_INVALID;
1096         }
1097
1098         if (handler->state != CREATE || !handler->id) {
1099                 ErrPrint("Handler is not valid\n");
1100                 return LB_STATUS_ERROR_INVALID;
1101         }
1102
1103         if (handler->lb.auto_launch) {
1104                 DbgPrint("Auto-launch enabled: %s\n", handler->lb.auto_launch);
1105                 if (aul_launch_app(handler->lb.auto_launch, NULL) < 0)
1106                         ErrPrint("Failed to launch app %s\n", handler->lb.auto_launch);
1107         }
1108
1109         packet = packet_create_noack("clicked", "sssddd", handler->pkgname, handler->id, "clicked", timestamp, x, y);
1110         if (!packet) {
1111                 ErrPrint("Failed to build param\n");
1112                 return LB_STATUS_ERROR_FAULT;
1113         }
1114
1115         ret = master_rpc_request_only(handler, packet);
1116         DbgPrint("Click request: %d\n", ret);
1117
1118         if (!handler->lb.mouse_event && (handler->lb.type == _LB_TYPE_BUFFER || handler->lb.type == _LB_TYPE_SCRIPT)) {
1119                 int ret; /* Shadow variable */
1120                 ret = send_mouse_event(handler, "lb_mouse_down", x * handler->lb.width, y * handler->lb.height);
1121                 if (ret < 0)
1122                         DbgPrint("Failed to send Down: %d\n", ret);
1123
1124                 ret = send_mouse_event(handler, "lb_mouse_move", x * handler->lb.width, y * handler->lb.height);
1125                 if (ret < 0)
1126                         DbgPrint("Failed to send Move: %d\n", ret);
1127
1128                 ret = send_mouse_event(handler, "lb_mouse_up", x * handler->lb.width, y * handler->lb.height);
1129                 if (ret < 0)
1130                         DbgPrint("Failed to send Up: %d\n", ret);
1131         }
1132
1133         return ret;
1134 }
1135
1136 EAPI int livebox_has_pd(struct livebox *handler)
1137 {
1138         if (!handler) {
1139                 ErrPrint("Handler is NIL\n");
1140                 return LB_STATUS_ERROR_INVALID;
1141         }
1142
1143         if (handler->state != CREATE || !handler->id) {
1144                 ErrPrint("Handler is not valid\n");
1145                 return LB_STATUS_ERROR_INVALID;
1146         }
1147
1148         return !!handler->pd.data.fb;
1149 }
1150
1151 EAPI int livebox_pd_is_created(struct livebox *handler)
1152 {
1153         if (!handler) {
1154                 ErrPrint("Handler is NIL\n");
1155                 return LB_STATUS_ERROR_INVALID;
1156         }
1157
1158         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1159                 ErrPrint("Handler is not valid\n");
1160                 return LB_STATUS_ERROR_INVALID;
1161         }
1162
1163         return handler->is_pd_created;
1164 }
1165
1166 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
1167 {
1168         return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
1169 }
1170
1171 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
1172 {
1173         struct packet *packet;
1174         int ret;
1175
1176         if (!handler) {
1177                 ErrPrint("Handler is NIL\n");
1178                 return LB_STATUS_ERROR_INVALID;
1179         }
1180
1181         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1182                 ErrPrint("Handler is not valid\n");
1183                 return LB_STATUS_ERROR_INVALID;
1184         }
1185
1186         if (handler->is_pd_created == 1) {
1187                 DbgPrint("PD already created\n");
1188                 return LB_STATUS_SUCCESS;
1189         }
1190
1191         if (handler->pd_created_cb) {
1192                 ErrPrint("Previous request is not completed yet\n");
1193                 return LB_STATUS_ERROR_BUSY;
1194         }
1195
1196         packet = packet_create("create_pd", "ssdd", handler->pkgname, handler->id, x, y);
1197         if (!packet) {
1198                 ErrPrint("Failed to build param\n");
1199                 return LB_STATUS_ERROR_FAULT;
1200         }
1201
1202         if (!cb)
1203                 cb = default_pd_created_cb;
1204
1205         handler->pd_created_cb = cb;
1206         handler->pd_created_cbdata = data;
1207
1208         ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
1209         if (ret < 0) {
1210                 handler->pd_created_cb = NULL;
1211                 handler->pd_created_cbdata = NULL;
1212         }
1213
1214         return ret;
1215 }
1216
1217 EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
1218 {
1219         struct packet *packet;
1220
1221         if (!handler) {
1222                 ErrPrint("Handler is NIL\n");
1223                 return LB_STATUS_ERROR_INVALID;
1224         }
1225
1226         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1227                 ErrPrint("Handler is not valid\n");
1228                 return LB_STATUS_ERROR_INVALID;
1229         }
1230
1231         if (!handler->is_pd_created) {
1232                 DbgPrint("PD is not created\n");
1233                 return LB_STATUS_ERROR_INVALID;
1234         }
1235
1236         packet = packet_create_noack("pd_move", "ssdd", handler->pkgname, handler->id, x, y);
1237         if (!packet) {
1238                 ErrPrint("Failed to build param\n");
1239                 return LB_STATUS_ERROR_FAULT;
1240         }
1241
1242         return master_rpc_request_only(handler, packet);
1243 }
1244
1245 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
1246 {
1247         struct packet *packet;
1248         struct cb_info *cbinfo;
1249         int ret;
1250
1251         if (!pkgname)
1252                 return LB_STATUS_ERROR_INVALID;
1253
1254         packet = packet_create("activate_package", "s", pkgname);
1255         if (!packet) {
1256                 ErrPrint("Failed to build a param\n");
1257                 return LB_STATUS_ERROR_FAULT;
1258         }
1259
1260         cbinfo = create_cb_info(cb, data);
1261         if (!cbinfo) {
1262                 ErrPrint("Unable to create cbinfo\n");
1263                 packet_destroy(packet);
1264                 return LB_STATUS_ERROR_FAULT;
1265         }
1266
1267         ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo);
1268         if (ret < 0)
1269                 destroy_cb_info(cbinfo);
1270
1271         return ret;
1272 }
1273
1274 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
1275 {
1276         struct packet *packet;
1277         struct cb_info *cbinfo;
1278         int ret;
1279
1280         if (!handler) {
1281                 ErrPrint("Handler is NIL\n");
1282                 return LB_STATUS_ERROR_INVALID;
1283         }
1284
1285         if (!handler->pd.data.fb || handler->state != CREATE || !handler->id) {
1286                 ErrPrint("Handler is not valid\n");
1287                 return LB_STATUS_ERROR_INVALID;
1288         }
1289
1290         if (!handler->is_pd_created && !handler->pd_created_cb) {
1291                 ErrPrint("PD is not created\n");
1292                 return LB_STATUS_ERROR_INVALID;
1293         }
1294
1295         packet = packet_create("destroy_pd", "ss", handler->pkgname, handler->id);
1296         if (!packet) {
1297                 ErrPrint("Failed to build a param\n");
1298                 return LB_STATUS_ERROR_FAULT;
1299         }
1300
1301         if (!cb)
1302                 cb = default_pd_destroyed_cb;
1303
1304         cbinfo = create_cb_info(cb, data);
1305         if (!cbinfo) {
1306                 packet_destroy(packet);
1307                 return LB_STATUS_ERROR_FAULT;
1308         }
1309
1310         ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo);
1311         if (ret < 0)
1312                 destroy_cb_info(cbinfo);
1313
1314         return ret;
1315 }
1316
1317 EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data)
1318 {
1319         int w = 1;
1320         int h = 1;
1321         char cmd[32] = { '\0', };
1322         char *ptr = cmd;
1323         int ret;
1324
1325         if (!handler) {
1326                 ErrPrint("Handler is NIL\n");
1327                 return LB_STATUS_ERROR_INVALID;
1328         }
1329
1330         if (handler->state != CREATE || !handler->id) {
1331                 ErrPrint("Handler is not valid\n");
1332                 return LB_STATUS_ERROR_INVALID;
1333         }
1334
1335         if (handler->access_event_cb) {
1336                 ErrPrint("Previous access event is not yet done\n");
1337                 return LB_STATUS_ERROR_BUSY;
1338         }
1339
1340         if (type & ACCESS_EVENT_PD_MASK) {
1341                 if (!handler->is_pd_created) {
1342                         ErrPrint("PD is not created\n");
1343                         return LB_STATUS_ERROR_INVALID;
1344                 }
1345                 *ptr++ = 'p';
1346                 *ptr++ = 'd';
1347                 w = handler->pd.width;
1348                 h = handler->pd.height;
1349         } else if (type & ACCESS_EVENT_LB_MASK) {
1350                 *ptr++ = 'l';
1351                 *ptr++ = 'b';
1352                 w = handler->lb.width;
1353                 h = handler->lb.height;
1354         } else {
1355                 ErrPrint("Invalid event type\n");
1356                 return LB_STATUS_ERROR_INVALID;
1357         }
1358
1359         switch (type & ~ACCESS_EVENT_PD_MASK) {
1360         case ACCESS_EVENT_HIGHLIGHT:
1361                 strcpy(ptr, "_access_hl");
1362                 break;
1363         case ACCESS_EVENT_HIGHLIGHT_NEXT:
1364                 strcpy(ptr, "_access_hl_next");
1365                 break;
1366         case ACCESS_EVENT_HIGHLIGHT_PREV:
1367                 strcpy(ptr, "_access_hl_prev");
1368                 break;
1369         case ACCESS_EVENT_ACTIVATE:
1370                 strcpy(ptr, "_access_activate");
1371                 break;
1372         case ACCESS_EVENT_ACTION_DOWN:
1373                 strcpy(ptr, "_access_action_down");
1374                 break;
1375         case ACCESS_EVENT_ACTION_UP:
1376                 strcpy(ptr, "_access_action_up");
1377                 break;
1378         case ACCESS_EVENT_UNHIGHLIGHT:
1379                 strcpy(ptr, "_access_unhighlight");
1380                 break;
1381         case ACCESS_EVENT_SCROLL_DOWN:
1382                 strcpy(ptr, "_access_scroll_down");
1383                 break;
1384         case ACCESS_EVENT_SCROLL_MOVE:
1385                 strcpy(ptr, "_access_scroll_move");
1386                 break;
1387         case ACCESS_EVENT_SCROLL_UP:
1388                 strcpy(ptr, "_access_scroll_up");
1389                 break;
1390         default:
1391                 return LB_STATUS_ERROR_INVALID;
1392         }
1393
1394         if (!cb)
1395                 cb = default_access_event_cb;
1396
1397         handler->access_event_cb = cb;
1398         handler->access_event_cbdata = data;
1399
1400         ret = send_access_event(handler, cmd, x * w, y * h);
1401         if (ret < 0) {
1402                 handler->access_event_cb = NULL;
1403                 handler->access_event_cbdata = NULL;
1404         }
1405
1406         return ret;
1407 }
1408
1409 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
1410 {
1411         int w = 1;
1412         int h = 1;
1413         char cmd[32] = { '\0', };
1414         char *ptr = cmd;
1415
1416         if (!handler) {
1417                 ErrPrint("Handler is NIL\n");
1418                 return LB_STATUS_ERROR_INVALID;
1419         }
1420
1421         if (handler->state != CREATE || !handler->id) {
1422                 ErrPrint("Handler is not valid\n");
1423                 return LB_STATUS_ERROR_INVALID;
1424         }
1425
1426         if (type & CONTENT_EVENT_PD_MASK) {
1427                 int flag = 1;
1428
1429                 if (!handler->is_pd_created) {
1430                         ErrPrint("PD is not created\n");
1431                         return LB_STATUS_ERROR_INVALID;
1432                 }
1433
1434                 if (type & CONTENT_EVENT_MOUSE_MASK) {
1435                         if (!handler->pd.data.fb) {
1436                                 ErrPrint("Handler is not valid\n");
1437                                 return LB_STATUS_ERROR_INVALID;
1438                         }
1439
1440                         if (type & CONTENT_EVENT_MOUSE_MOVE) {
1441                                 if (fabs(x - handler->pd.x) < MINIMUM_EVENT && fabs(y - handler->pd.y) < MINIMUM_EVENT)
1442                                         return LB_STATUS_ERROR_BUSY;
1443                         } else if (type & CONTENT_EVENT_MOUSE_SET) {
1444                                 flag = 0;
1445                         }
1446                 }
1447
1448                 if (flag) {
1449                         w = handler->pd.width;
1450                         h = handler->pd.height;
1451                         handler->pd.x = x;
1452                         handler->pd.y = y;
1453                 }
1454                 *ptr++ = 'p';
1455                 *ptr++ = 'd';
1456         } else if (type & CONTENT_EVENT_LB_MASK) {
1457                 int flag = 1;
1458
1459                 if (type & CONTENT_EVENT_MOUSE_MASK) {
1460                         if (!handler->lb.mouse_event) {
1461                                 ErrPrint("Box is not support the mouse event\n");
1462                                 return LB_STATUS_ERROR_INVALID;
1463                         }
1464
1465                         if (!handler->lb.data.fb) {
1466                                 ErrPrint("Handler is not valid\n");
1467                                 return LB_STATUS_ERROR_INVALID;
1468                         }
1469
1470                         if (type & CONTENT_EVENT_MOUSE_MOVE) {
1471                                 if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT)
1472                                         return LB_STATUS_ERROR_BUSY;
1473                         } else if (type & CONTENT_EVENT_MOUSE_SET) {
1474                                 flag = 0;
1475                         }
1476                 }
1477
1478                 if (flag) {
1479                         w = handler->lb.width;
1480                         h = handler->lb.height;
1481                         handler->lb.x = x;
1482                         handler->lb.y = y;
1483                 }
1484                 *ptr++ = 'l';
1485                 *ptr++ = 'b';
1486         } else {
1487                 ErrPrint("Invalid event type\n");
1488                 return LB_STATUS_ERROR_INVALID;
1489         }
1490
1491         /*!
1492          * Must be short than 29 bytes.
1493          */
1494         switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
1495         case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
1496                 strcpy(ptr, "_mouse_enter");
1497                 break;
1498         case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
1499                 strcpy(ptr, "_mouse_leave");
1500                 break;
1501         case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
1502                 strcpy(ptr, "_mouse_up");
1503                 break;
1504         case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
1505                 strcpy(ptr, "_mouse_down");
1506                 break;
1507         case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
1508                 strcpy(ptr, "_mouse_move");
1509                 break;
1510         case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
1511                 strcpy(ptr, "_mouse_set");
1512                 break;
1513         case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
1514                 strcpy(ptr, "_mouse_unset");
1515                 break;
1516         case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
1517                 strcpy(ptr, "_key_down");
1518                 break;
1519         case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
1520                 strcpy(ptr, "_key_up");
1521                 break;
1522         default:
1523                 ErrPrint("Invalid event type\n");
1524                 return LB_STATUS_ERROR_INVALID;
1525         }
1526
1527         return send_mouse_event(handler, cmd, x * w, y * h);
1528 }
1529
1530 EAPI const char *livebox_filename(struct livebox *handler)
1531 {
1532         if (!handler) {
1533                 ErrPrint("Handler is NIL\n");
1534                 return NULL;
1535         }
1536
1537         if (handler->state != CREATE || !handler->id) {
1538                 ErrPrint("Handler is not valid\n");
1539                 return NULL;
1540         }
1541
1542         if (handler->filename)
1543                 return handler->filename;
1544
1545         /* Oooops */
1546         return util_uri_to_path(handler->id);
1547 }
1548
1549 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
1550 {
1551         int _w;
1552         int _h;
1553
1554         if (!handler) {
1555                 ErrPrint("Handler is NIL\n");
1556                 return LB_STATUS_ERROR_INVALID;
1557         }
1558
1559         if (handler->state != CREATE || !handler->id) {
1560                 ErrPrint("Handler is not valid\n");
1561                 return LB_STATUS_ERROR_INVALID;
1562         }
1563
1564         if (!w)
1565                 w = &_w;
1566         if (!h)
1567                 h = &_h;
1568
1569         if (!handler->is_pd_created) {
1570                 DbgPrint("Buffer is not created yet [%dx%d]\n", *w, *h);
1571                 *w = handler->pd.default_width;
1572                 *h = handler->pd.default_height;
1573         } else {
1574                 *w = handler->pd.width;
1575                 *h = handler->pd.height;
1576         }
1577
1578         return LB_STATUS_SUCCESS;
1579 }
1580
1581 EAPI int livebox_size(struct livebox *handler)
1582 {
1583         int w;
1584         int h;
1585
1586         if (!handler) {
1587                 ErrPrint("Handler is NIL\n");
1588                 return LB_STATUS_ERROR_INVALID;
1589         }
1590
1591         if (handler->state != CREATE || !handler->id) {
1592                 ErrPrint("Handler is not valid\n");
1593                 return LB_STATUS_ERROR_INVALID;
1594         }
1595
1596         w = handler->lb.width;
1597         h = handler->lb.height;
1598
1599         switch (handler->lb.type) {
1600         case _LB_TYPE_BUFFER:
1601         case _LB_TYPE_SCRIPT:
1602                 if (!fb_is_created(handler->lb.data.fb)) {
1603                         DbgPrint("Buffer is not created yet - reset size\n");
1604                         w = 0;
1605                         h = 0;
1606                 }
1607                 break;
1608         default:
1609                 break;
1610         }
1611
1612         return livebox_service_size_type(w, h);
1613 }
1614
1615 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
1616 {
1617         struct packet *packet;
1618         int ret;
1619
1620         if (!handler) {
1621                 ErrPrint("Handler is NIL\n");
1622                 return LB_STATUS_ERROR_INVALID;
1623         }
1624
1625         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1626                 ErrPrint("Invalid argument\n");
1627                 return LB_STATUS_ERROR_INVALID;
1628         }
1629
1630         if (handler->group_changed_cb) {
1631                 ErrPrint("Previous group changing request is not finished yet\n");
1632                 return LB_STATUS_ERROR_BUSY;
1633         }
1634
1635         if (!handler->is_user) {
1636                 ErrPrint("CA Livebox is not able to change the group\n");
1637                 return LB_STATUS_ERROR_PERMISSION;
1638         }
1639
1640         if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
1641                 DbgPrint("No changes\n");
1642                 return LB_STATUS_ERROR_ALREADY;
1643         }
1644
1645         packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
1646         if (!packet) {
1647                 ErrPrint("Failed to build a param\n");
1648                 return LB_STATUS_ERROR_FAULT;
1649         }
1650
1651         if (!cb)
1652                 cb = default_group_changed_cb;
1653
1654         handler->group_changed_cb = cb;
1655         handler->group_cbdata = data; 
1656
1657         ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
1658         if (ret < 0) {
1659                 handler->group_changed_cb = NULL;
1660                 handler->group_cbdata = NULL;
1661         }
1662
1663         return ret;
1664 }
1665
1666 EAPI int livebox_get_group(struct livebox *handler, char ** const cluster, char ** const category)
1667 {
1668         if (!handler) {
1669                 ErrPrint("Handler is NIL\n");
1670                 return LB_STATUS_ERROR_INVALID;
1671         }
1672
1673         if (!cluster || !category || handler->state != CREATE || !handler->id) {
1674                 ErrPrint("Invalid argument\n");
1675                 return LB_STATUS_ERROR_INVALID;
1676         }
1677
1678         *cluster = handler->cluster;
1679         *category = handler->category;
1680         return LB_STATUS_SUCCESS;
1681 }
1682
1683 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
1684 {
1685         register int i;
1686         register int j;
1687
1688         if (!handler || !size_list) {
1689                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
1690                 return LB_STATUS_ERROR_INVALID;
1691         }
1692
1693         if (!cnt || handler->state != CREATE || !handler->id) {
1694                 ErrPrint("Handler is not valid\n");
1695                 return LB_STATUS_ERROR_INVALID;
1696         }
1697
1698         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
1699                 if (handler->lb.size_list & (0x01 << i)) {
1700                         if (j == *cnt)
1701                                 break;
1702
1703                         size_list[j++] = (0x01 << i);
1704                 }
1705         }
1706
1707         *cnt = j;
1708         return LB_STATUS_SUCCESS;
1709 }
1710
1711 EAPI const char *livebox_pkgname(struct livebox *handler)
1712 {
1713         if (!handler) {
1714                 ErrPrint("Handler is NIL\n");
1715                 return NULL;
1716         }
1717
1718         if (handler->state != CREATE) {
1719                 ErrPrint("Handler is not valid\n");
1720                 return NULL;
1721         }
1722
1723         return handler->pkgname;
1724 }
1725
1726 EAPI double livebox_priority(struct livebox *handler)
1727 {
1728         if (!handler) {
1729                 ErrPrint("Handler is NIL\n");
1730                 return 0.0f;
1731         }
1732
1733         if (handler->state != CREATE || !handler->id) {
1734                 ErrPrint("Handler is not valid (%p)\n", handler);
1735                 return -1.0f;
1736         }
1737
1738         return handler->lb.priority;
1739 }
1740
1741 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
1742 {
1743         struct packet *packet;
1744         struct cb_info *cbinfo;
1745         int ret;
1746
1747         packet = packet_create("delete_cluster", "s", cluster);
1748         if (!packet) {
1749                 ErrPrint("Failed to build a param\n");
1750                 return LB_STATUS_ERROR_FAULT;
1751         }
1752
1753         cbinfo = create_cb_info(cb, data);
1754         if (!cbinfo) {
1755                 packet_destroy(packet);
1756                 return LB_STATUS_ERROR_FAULT;
1757         }
1758
1759         ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
1760         if (ret < 0)
1761                 destroy_cb_info(cbinfo);
1762
1763         return ret;
1764 }
1765
1766 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
1767 {
1768         struct packet *packet;
1769         struct cb_info *cbinfo;
1770         int ret;
1771
1772         packet = packet_create("delete_category", "ss", cluster, category);
1773         if (!packet) {
1774                 ErrPrint("Failed to build a param\n");
1775                 return LB_STATUS_ERROR_FAULT;
1776         }
1777
1778         cbinfo = create_cb_info(cb, data);
1779         if (!cbinfo) {
1780                 packet_destroy(packet);
1781                 return LB_STATUS_ERROR_FAULT;
1782         }
1783
1784         ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
1785         if (ret < 0)
1786                 destroy_cb_info(cbinfo);
1787
1788         return ret;
1789 }
1790
1791 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
1792 {
1793         if (!handler) {
1794                 ErrPrint("Handler is NIL\n");
1795                 return LB_TYPE_INVALID;
1796         }
1797
1798         if (handler->state != CREATE || !handler->id) {
1799                 ErrPrint("Handler is not valid\n");
1800                 return LB_TYPE_INVALID;
1801         }
1802
1803         switch (handler->lb.type) {
1804         case _LB_TYPE_FILE:
1805                 return LB_TYPE_IMAGE;
1806         case _LB_TYPE_BUFFER:
1807         case _LB_TYPE_SCRIPT:
1808                 {
1809                         const char *id;
1810                         id = fb_id(handler->lb.data.fb);
1811                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1812                                 return LB_TYPE_PIXMAP;
1813                 }
1814                 return LB_TYPE_BUFFER;
1815         case _LB_TYPE_TEXT:
1816                 return LB_TYPE_TEXT;
1817         default:
1818                 break;
1819         }
1820
1821         return LB_TYPE_INVALID;
1822 }
1823
1824 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
1825 {
1826         if (!handler) {
1827                 ErrPrint("Handler is NIL\n");
1828                 return PD_TYPE_INVALID;
1829         }
1830
1831         if (handler->state != CREATE || !handler->id) {
1832                 ErrPrint("Handler is not valid\n");
1833                 return PD_TYPE_INVALID;
1834         }
1835
1836         switch (handler->pd.type) {
1837         case _PD_TYPE_TEXT:
1838                 return PD_TYPE_TEXT;
1839         case _PD_TYPE_BUFFER:
1840         case _PD_TYPE_SCRIPT:
1841                 {
1842                         const char *id;
1843                         id = fb_id(handler->pd.data.fb);
1844                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1845                                 return PD_TYPE_PIXMAP;
1846                 }
1847                 return PD_TYPE_BUFFER;
1848         default:
1849                 break;
1850         }
1851
1852         return PD_TYPE_INVALID;
1853 }
1854
1855 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1856 {
1857         if (!handler) {
1858                 ErrPrint("Handler is NIL\n");
1859                 return LB_STATUS_ERROR_INVALID;
1860         }
1861
1862         if (handler->state != CREATE) {
1863                 ErrPrint("Handler is not valid\n");
1864                 return LB_STATUS_ERROR_INVALID;
1865         }
1866
1867         memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
1868         return LB_STATUS_SUCCESS;
1869 }
1870
1871 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
1872 {
1873         if (!handler) {
1874                 ErrPrint("Handler is NIL\n");
1875                 return LB_STATUS_ERROR_INVALID;
1876         }
1877
1878         if (handler->state != CREATE) {
1879                 ErrPrint("Handler is not valid\n");
1880                 return LB_STATUS_ERROR_INVALID;
1881         }
1882
1883         memcpy(&handler->lb.data.ops, ops, sizeof(*ops));
1884         return LB_STATUS_SUCCESS;
1885 }
1886
1887 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1888 {
1889         struct packet *packet;
1890         struct cb_info *cbinfo;
1891         const char *id;
1892         int ret;
1893
1894         if (!handler) {
1895                 ErrPrint("Handler is NIL\n");
1896                 return LB_STATUS_ERROR_INVALID;
1897         }
1898
1899         if (handler->state != CREATE || !handler->id) {
1900                 ErrPrint("Invalid handle\n");
1901                 return LB_STATUS_ERROR_INVALID;
1902         }
1903
1904         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1905                 ErrPrint("Handler is not valid type\n");
1906                 return LB_STATUS_ERROR_INVALID;
1907         }
1908
1909         id = fb_id(handler->lb.data.fb);
1910         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1911                 return LB_STATUS_ERROR_INVALID;
1912
1913         packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
1914         if (!packet) {
1915                 ErrPrint("Failed to build a param\n");
1916                 return LB_STATUS_ERROR_FAULT;
1917         }
1918
1919         cbinfo = create_cb_info(cb, data);
1920         if (!cbinfo) {
1921                 packet_destroy(packet);
1922                 return LB_STATUS_ERROR_FAULT;
1923         }
1924
1925         ret = master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, cbinfo);
1926         if (ret < 0)
1927                 destroy_cb_info(cbinfo);
1928
1929         return ret;
1930 }
1931
1932 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
1933 {
1934         struct packet *packet;
1935
1936         if (!handler) {
1937                 ErrPrint("Handler is NIL\n");
1938                 return LB_STATUS_ERROR_INVALID;
1939         }
1940
1941         if (handler->state != CREATE || !handler->id) {
1942                 ErrPrint("Invalid handle\n");
1943                 return LB_STATUS_ERROR_INVALID;
1944         }
1945
1946         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
1947                 ErrPrint("Handler is not valid type\n");
1948                 return LB_STATUS_ERROR_INVALID;
1949         }
1950
1951         packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
1952         if (!packet) {
1953                 ErrPrint("Failed to build a param\n");
1954                 return LB_STATUS_ERROR_INVALID;
1955         }
1956
1957         return master_rpc_request_only(handler, packet);
1958 }
1959
1960 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
1961 {
1962         struct packet *packet;
1963         struct cb_info *cbinfo;
1964         const char *id;
1965         int ret;
1966
1967         if (!handler) {
1968                 ErrPrint("Handler is NIL\n");
1969                 return LB_STATUS_ERROR_INVALID;
1970         }
1971
1972         if (handler->state != CREATE || !handler->id) {
1973                 ErrPrint("Invalid handle\n");
1974                 return LB_STATUS_ERROR_INVALID;
1975         }
1976
1977         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
1978                 ErrPrint("Handler is not valid type\n");
1979                 return LB_STATUS_ERROR_INVALID;
1980         }
1981
1982         id = fb_id(handler->pd.data.fb);
1983         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP)))
1984                 return LB_STATUS_ERROR_INVALID;
1985
1986         packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
1987         if (!packet) {
1988                 ErrPrint("Failed to build a param\n");
1989                 return LB_STATUS_ERROR_FAULT;
1990         }
1991
1992         cbinfo = create_cb_info(cb, data);
1993         if (!cbinfo) {
1994                 packet_destroy(packet);
1995                 return LB_STATUS_ERROR_FAULT;
1996         }
1997
1998         ret = master_rpc_async_request(handler, packet, 0, pixmap_acquired_cb, cbinfo);
1999         if (ret < 0)
2000                 destroy_cb_info(cbinfo);
2001
2002         return ret;
2003 }
2004
2005 EAPI int livebox_pd_pixmap(const struct livebox *handler)
2006 {
2007         const char *id;
2008         int pixmap = 0;
2009
2010         if (!handler) {
2011                 ErrPrint("Handler is NIL\n");
2012                 return 0;
2013         }
2014
2015         if (handler->state != CREATE || !handler->id) {
2016                 ErrPrint("Invalid handler\n");
2017                 return 0;
2018         }
2019
2020         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2021                 ErrPrint("Invalid handler\n");
2022                 return 0;
2023         }
2024
2025         id = fb_id(handler->pd.data.fb);
2026         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
2027                 ErrPrint("PIXMAP Id is not valid\n");
2028                 return 0;
2029         }
2030
2031         return pixmap;
2032 }
2033
2034 EAPI int livebox_lb_pixmap(const struct livebox *handler)
2035 {
2036         const char *id;
2037         int pixmap = 0;
2038
2039         if (!handler) {
2040                 ErrPrint("Handler is NIL\n");
2041                 return 0;
2042         }
2043
2044         if (handler->state != CREATE || !handler->id) {
2045                 ErrPrint("Invalid handler\n");
2046                 return 0;
2047         }
2048
2049         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2050                 ErrPrint("Invalid handler\n");
2051                 return 0;
2052         }
2053
2054         id = fb_id(handler->lb.data.fb);
2055         if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
2056                 ErrPrint("PIXMAP Id is not valid\n");
2057                 return 0;
2058         }
2059
2060         return pixmap;
2061 }
2062
2063 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
2064 {
2065         struct packet *packet;
2066
2067         if (!handler) {
2068                 ErrPrint("Handler is NIL\n");
2069                 return LB_STATUS_ERROR_INVALID;
2070         }
2071
2072         if (handler->state != CREATE || !handler->id) {
2073                 ErrPrint("Invalid handle\n");
2074                 return LB_STATUS_ERROR_INVALID;
2075         }
2076
2077         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2078                 ErrPrint("Handler is not valid type\n");
2079                 return LB_STATUS_ERROR_INVALID;
2080         }
2081
2082         packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
2083         if (!packet) {
2084                 ErrPrint("Failed to build a param\n");
2085                 return LB_STATUS_ERROR_FAULT;
2086         }
2087
2088         return master_rpc_request_only(handler, packet);
2089 }
2090
2091 EAPI void *livebox_acquire_fb(struct livebox *handler)
2092 {
2093         if (!handler) {
2094                 ErrPrint("Handler is NIL\n");
2095                 return NULL;
2096         }
2097
2098         if (handler->state != CREATE || !handler->id) {
2099                 ErrPrint("Invalid handle\n");
2100                 return NULL;
2101         }
2102
2103         if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2104                 ErrPrint("Handler is not valid type\n");
2105                 return NULL;
2106         }
2107
2108         return fb_acquire_buffer(handler->lb.data.fb);
2109 }
2110
2111 EAPI int livebox_release_fb(void *buffer)
2112 {
2113         return fb_release_buffer(buffer);
2114 }
2115
2116 EAPI int livebox_fb_refcnt(void *buffer)
2117 {
2118         return fb_refcnt(buffer);
2119 }
2120
2121 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
2122 {
2123         if (!handler) {
2124                 ErrPrint("Handler is NIL\n");
2125                 return NULL;
2126         }
2127
2128         if (handler->state != CREATE || !handler->id) {
2129                 ErrPrint("Invalid handler\n");
2130                 return NULL;
2131         }
2132
2133         if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2134                 ErrPrint("Handler is not valid type\n");
2135                 return NULL;
2136         }
2137
2138         return fb_acquire_buffer(handler->pd.data.fb);
2139 }
2140
2141 EAPI int livebox_release_pdfb(void *buffer)
2142 {
2143         return fb_release_buffer(buffer);
2144 }
2145
2146 EAPI int livebox_pdfb_refcnt(void *buffer)
2147 {
2148         return fb_refcnt(buffer);
2149 }
2150
2151 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
2152 {
2153         if (!handler) {
2154                 ErrPrint("Handler is NIL\n");
2155                 return LB_STATUS_ERROR_INVALID;
2156         }
2157
2158         if (handler->state != CREATE || !handler->id) {
2159                 ErrPrint("Handler is not valid\n");
2160                 return LB_STATUS_ERROR_INVALID;
2161         }
2162
2163         return fb_size(handler->pd.data.fb);
2164 }
2165
2166 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
2167 {
2168         if (!handler) {
2169                 ErrPrint("Handler is NIL\n");
2170                 return LB_STATUS_ERROR_INVALID;
2171         }
2172
2173         if (handler->state != CREATE || !handler->id) {
2174                 ErrPrint("Handler is not valid\n");
2175                 return LB_STATUS_ERROR_INVALID;
2176         }
2177
2178         return fb_size(handler->lb.data.fb);
2179 }
2180
2181 EAPI int livebox_is_user(struct livebox *handler)
2182 {
2183         if (!handler) {
2184                 ErrPrint("Handler is NIL\n");
2185                 return LB_STATUS_ERROR_INVALID;
2186         }
2187
2188         if (handler->state != CREATE) {
2189                 ErrPrint("Handler is invalid\n");
2190                 return LB_STATUS_ERROR_INVALID;
2191         }
2192
2193         return handler->is_user;
2194 }
2195
2196 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
2197 {
2198         struct packet *packet;
2199         int ret;
2200
2201         if (!handler) {
2202                 ErrPrint("Handler is NIL\n");
2203                 return LB_STATUS_ERROR_INVALID;
2204         }
2205
2206         if (handler->state != CREATE || !handler->id) {
2207                 ErrPrint("Handler is not valid\n");
2208                 return LB_STATUS_ERROR_INVALID;
2209         }
2210
2211         if (handler->pinup_cb) {
2212                 ErrPrint("Previous pinup request is not finished\n");
2213                 return LB_STATUS_ERROR_BUSY;
2214         }
2215
2216         if (handler->is_pinned_up == flag) {
2217                 DbgPrint("No changes\n");
2218                 return LB_STATUS_ERROR_ALREADY;
2219         }
2220
2221         packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
2222         if (!packet) {
2223                 ErrPrint("Failed to build a param\n");
2224                 return LB_STATUS_ERROR_FAULT;
2225         }
2226
2227         if (!cb)
2228                 cb = default_pinup_cb;
2229
2230         handler->pinup_cb = cb;
2231         handler->pinup_cbdata = data;
2232
2233         ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
2234         if (ret < 0) {
2235                 handler->pinup_cb = NULL;
2236                 handler->pinup_cbdata = NULL;
2237         }
2238
2239         return ret;
2240 }
2241
2242 EAPI int livebox_is_pinned_up(struct livebox *handler)
2243 {
2244         if (!handler) {
2245                 ErrPrint("Handler is NIL\n");
2246                 return LB_STATUS_ERROR_INVALID;
2247         }
2248
2249         if (handler->state != CREATE || !handler->id)
2250                 return LB_STATUS_ERROR_INVALID;
2251
2252         return handler->is_pinned_up;
2253 }
2254
2255 EAPI int livebox_has_pinup(struct livebox *handler)
2256 {
2257         if (!handler) {
2258                 ErrPrint("Handler is NIL\n");
2259                 return LB_STATUS_ERROR_INVALID;
2260         }
2261
2262         if (handler->state != CREATE || !handler->id)
2263                 return LB_STATUS_ERROR_INVALID;
2264
2265         return handler->lb.pinup_supported;
2266 }
2267
2268 EAPI int livebox_set_data(struct livebox *handler, void *data)
2269 {
2270         if (!handler) {
2271                 ErrPrint("Handler is NIL\n");
2272                 return LB_STATUS_ERROR_INVALID;
2273         }
2274
2275         if (handler->state != CREATE)
2276                 return LB_STATUS_ERROR_INVALID;
2277
2278         handler->data = data;
2279         return LB_STATUS_SUCCESS;
2280 }
2281
2282 EAPI void *livebox_get_data(struct livebox *handler)
2283 {
2284         if (!handler) {
2285                 ErrPrint("Handler is NIL\n");
2286                 return NULL;
2287         }
2288
2289         if (handler->state != CREATE)
2290                 return NULL;
2291
2292         return handler->data;
2293 }
2294
2295 EAPI int livebox_is_exists(const char *pkgname)
2296 {
2297         char *lb;
2298
2299         lb = lb_pkgname(pkgname);
2300         if (lb) {
2301                 free(lb);
2302                 return 1;
2303         }
2304
2305         return 0;
2306 }
2307
2308 EAPI const char *livebox_content(struct livebox *handler)
2309 {
2310         if (!handler) {
2311                 ErrPrint("Handler is NIL\n");
2312                 return NULL;
2313         }
2314
2315         if (handler->state != CREATE)
2316                 return NULL;
2317
2318         return handler->content;
2319 }
2320
2321 EAPI const char *livebox_category_title(struct livebox *handler)
2322 {
2323         if (!handler) {
2324                 ErrPrint("Handler is NIL\n");
2325                 return NULL;
2326         }
2327
2328         if (handler->state != CREATE)
2329                 return NULL;
2330
2331         return handler->title;
2332 }
2333
2334 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)
2335 {
2336         struct packet *packet;
2337         struct cb_info *cbinfo;
2338         int ret;
2339
2340         if (!handler) {
2341                 ErrPrint("Handler is NIL\n");
2342                 return LB_STATUS_ERROR_INVALID;
2343         }
2344
2345         if ((handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || handler->state != CREATE || !handler->id) {
2346                 ErrPrint("Handler is not valid\n");
2347                 return LB_STATUS_ERROR_INVALID;
2348         }
2349
2350         if (!emission)
2351                 emission = "";
2352
2353         if (!source)
2354                 source = "";
2355
2356         packet = packet_create("text_signal", "ssssdddd",
2357                                 handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
2358         if (!packet) {
2359                 ErrPrint("Failed to build a param\n");
2360                 return LB_STATUS_ERROR_FAULT;
2361         }
2362
2363         cbinfo = create_cb_info(cb, data);
2364         if (!cbinfo) {
2365                 packet_destroy(packet);
2366                 return LB_STATUS_ERROR_FAULT;
2367         }
2368
2369         ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
2370         if (ret < 0)
2371                 destroy_cb_info(cbinfo);
2372
2373         return LB_STATUS_ERROR_FAULT;
2374 }
2375
2376 EAPI int livebox_subscribe_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          */
2385
2386         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
2387         if (!packet) {
2388                 ErrPrint("Failed to create a packet\n");
2389                 return LB_STATUS_ERROR_FAULT;
2390         }
2391
2392         return master_rpc_request_only(NULL, packet);
2393 }
2394
2395 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
2396 {
2397         struct packet *packet;
2398
2399         /*!
2400          * \TODO
2401          * Validate the group info using DB
2402          * If the group info is not valid, do not send this request
2403          * AND Check the subscribed or not too
2404          */
2405
2406         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
2407         if (!packet) {
2408                 ErrPrint("Failed to create a packet\n");
2409                 return LB_STATUS_ERROR_FAULT;
2410         }
2411
2412         return master_rpc_request_only(NULL, packet);
2413 }
2414
2415 EAPI int livebox_refresh(struct livebox *handler)
2416 {
2417         struct packet *packet;
2418
2419         if (!handler) {
2420                 ErrPrint("Hnalder is NIL\n");
2421                 return LB_STATUS_ERROR_INVALID;
2422         }
2423
2424         if (handler->state != CREATE || !handler->id)
2425                 return LB_STATUS_ERROR_INVALID;
2426
2427         packet = packet_create_noack("update", "ss", handler->pkgname, handler->id);
2428         if (!packet) {
2429                 ErrPrint("Failed to create a packet\n");
2430                 return LB_STATUS_ERROR_FAULT;
2431         }
2432
2433         return master_rpc_request_only(handler, packet);
2434 }
2435
2436 EAPI int livebox_refresh_group(const char *cluster, const char *category)
2437 {
2438         struct packet *packet;
2439
2440         if (!cluster || !category) {
2441                 ErrPrint("Invalid argument\n");
2442                 return LB_STATUS_ERROR_INVALID;
2443         }
2444
2445         packet = packet_create_noack("refresh_group", "ss", cluster, category);
2446         if (!packet) {
2447                 ErrPrint("Failed to create a packet\n");
2448                 return LB_STATUS_ERROR_FAULT;
2449         }
2450
2451         return master_rpc_request_only(NULL, packet);
2452 }
2453
2454 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
2455 {
2456         struct packet *packet;
2457         int ret;
2458
2459         if (!handler) {
2460                 ErrPrint("Handler is NIL\n");
2461                 return LB_STATUS_ERROR_INVALID;
2462         }
2463
2464         if (handler->state != CREATE || !handler->id)
2465                 return LB_STATUS_ERROR_INVALID;
2466
2467         if (!handler->is_user) {
2468                 /* System cluster livebox cannot be changed its visible states */
2469                 if (state == LB_HIDE_WITH_PAUSE) {
2470                         ErrPrint("CA Livebox is not able to change the visibility\n");
2471                         return LB_STATUS_ERROR_PERMISSION;
2472                 }
2473         }
2474
2475         DbgPrint("Change the visibility %d <> %d, %s\n", handler->visible, state, handler->id);
2476
2477         if (handler->visible == state)
2478                 return LB_STATUS_ERROR_ALREADY;
2479
2480         packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
2481         if (!packet) {
2482                 ErrPrint("Failed to create a packet\n");
2483                 return LB_STATUS_ERROR_FAULT;
2484         }
2485
2486         ret = master_rpc_request_only(handler, packet);
2487         if (ret == 0)
2488                 handler->visible = state;
2489
2490         return ret;
2491 }
2492
2493 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
2494 {
2495         if (!handler) {
2496                 ErrPrint("Handler is NIL\n");
2497                 return LB_VISIBLE_ERROR;
2498         }
2499
2500         if (handler->state != CREATE || !handler->id)
2501                 return LB_VISIBLE_ERROR;
2502
2503         return handler->visible;
2504 }
2505
2506 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
2507 {
2508         void *pc = NULL;
2509         void *ps = NULL;
2510
2511         if (cluster) {
2512                 pc = strdup(cluster);
2513                 if (!pc) {
2514                         CRITICAL_LOG("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
2515                         return LB_STATUS_ERROR_MEMORY;
2516                 }
2517         }
2518
2519         if (category) {
2520                 ps = strdup(category);
2521                 if (!ps) {
2522                         CRITICAL_LOG("Heap: %s (category: %s)\n", strerror(errno), category);
2523                         free(pc);
2524                         return LB_STATUS_ERROR_MEMORY;
2525                 }
2526         }
2527
2528         if (handler->cluster)
2529                 free(handler->cluster);
2530
2531         if (handler->category)
2532                 free(handler->category);
2533
2534         handler->cluster = pc;
2535         handler->category = ps;
2536
2537         return LB_STATUS_SUCCESS;
2538 }
2539
2540 void lb_set_size(struct livebox *handler, int w, int h)
2541 {
2542         handler->lb.width = w;
2543         handler->lb.height = h;
2544 }
2545
2546 void lb_set_update_mode(struct livebox *handle, int active_mode)
2547 {
2548         handle->is_active_update = active_mode;
2549 }
2550
2551 void lb_set_pdsize(struct livebox *handler, int w, int h)
2552 {
2553         handler->pd.width = w;
2554         handler->pd.height = h;
2555 }
2556
2557 void lb_set_default_pdsize(struct livebox *handler, int w, int h)
2558 {
2559         handler->pd.default_width = w;
2560         handler->pd.default_height = h;
2561 }
2562
2563 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
2564 {
2565         struct dlist *l;
2566         struct dlist *n;
2567         struct fault_info *info;
2568
2569         dlist_foreach_safe(s_info.fault_list, l, n, info) {
2570                 if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE)
2571                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
2572         }
2573 }
2574
2575 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
2576 {
2577         struct dlist *l;
2578         struct dlist *n;
2579         struct event_info *info;
2580
2581         dlist_foreach_safe(s_info.event_list, l, n, info) {
2582                 if (info->handler(handler, event, info->user_data) == EXIT_FAILURE)
2583                         s_info.event_list = dlist_remove(s_info.event_list, l);
2584         }
2585 }
2586
2587 struct livebox *lb_find_livebox(const char *pkgname, const char *id)
2588 {
2589         struct dlist *l;
2590         struct livebox *handler;
2591
2592         dlist_foreach(s_info.livebox_list, l, handler) {
2593                 if (!handler->id)
2594                         continue;
2595
2596                 if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id))
2597                         return handler;
2598         }
2599
2600         return NULL;
2601 }
2602
2603 struct livebox *lb_find_livebox_by_timestamp(double timestamp)
2604 {
2605         struct dlist *l;
2606         struct livebox *handler;
2607
2608         dlist_foreach(s_info.livebox_list, l, handler) {
2609                 if (handler->timestamp == timestamp)
2610                         return handler;
2611         }
2612
2613         return NULL;
2614 }
2615
2616 static inline char *get_file_kept_in_safe(const char *id)
2617 {
2618         const char *path;
2619         char *new_path;
2620         int len;
2621         int base_idx;
2622
2623         path = util_uri_to_path(id);
2624         if (!path) {
2625                 ErrPrint("Invalid URI(%s)\n", id);
2626                 return NULL;
2627         }
2628
2629         /*!
2630          * \TODO: REMOVE ME
2631          */
2632         if (s_info.prevent_overwrite) {
2633                 new_path = strdup(path);
2634                 if (!new_path)
2635                         ErrPrint("Heap: %s\n", strerror(errno));
2636
2637                 return new_path;
2638         }
2639
2640
2641         len = strlen(path);
2642         base_idx = len - 1;
2643
2644         while (base_idx > 0 && path[base_idx] != '/') base_idx--;
2645         base_idx += (path[base_idx] == '/');
2646
2647         new_path = malloc(len + 10);
2648         if (!new_path) {
2649                 ErrPrint("Heap: %s\n", strerror(errno));
2650                 return NULL;
2651         }
2652
2653         strncpy(new_path, path, base_idx);
2654         snprintf(new_path + base_idx, len + 10 - base_idx, "reader/%s", path + base_idx);
2655         return new_path;
2656 }
2657
2658 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
2659 {
2660         struct livebox *handler;
2661
2662         handler = calloc(1, sizeof(*handler));
2663         if (!handler) {
2664                 ErrPrint("Failed to create a new livebox\n");
2665                 return NULL;
2666         }
2667
2668         handler->pkgname = strdup(pkgname);
2669         if (!handler->pkgname) {
2670                 ErrPrint("%s\n", strerror(errno));
2671                 free(handler);
2672                 return NULL;
2673         }
2674
2675         handler->id = strdup(id);
2676         if (!handler->id) {
2677                 ErrPrint("%s\n", strerror(errno));
2678                 free(handler->pkgname);
2679                 free(handler);
2680                 return NULL;
2681         }
2682
2683         handler->filename = get_file_kept_in_safe(id);
2684         if (!handler->filename) {
2685                 handler->filename = strdup(util_uri_to_path(id));
2686                 if (!handler->filename)
2687                         ErrPrint("Error: %s\n", strerror(errno));
2688         }
2689
2690         handler->timestamp = timestamp;
2691         handler->lb.type = _LB_TYPE_FILE;
2692         handler->pd.type = _PD_TYPE_SCRIPT;
2693         handler->state = CREATE;
2694         handler->visible = LB_SHOW;
2695
2696         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
2697         lb_ref(handler);
2698         return handler;
2699 }
2700
2701 int lb_delete_all(void)
2702 {
2703         struct dlist *l;
2704         struct dlist *n;
2705         struct livebox *handler;
2706
2707         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
2708                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
2709                 lb_unref(handler);
2710         }
2711
2712         return LB_STATUS_SUCCESS;
2713 }
2714
2715 int lb_set_content(struct livebox *handler, const char *content)
2716 {
2717         if (handler->content) {
2718                 DbgPrint("Release content: %s\n", content);
2719                 free(handler->content);
2720                 handler->content = NULL;
2721         }
2722
2723         if (content) {
2724                 DbgPrint("Update Content: [%s]\n", content);
2725                 handler->content = strdup(content);
2726                 if (!handler->content) {
2727                         CRITICAL_LOG("Heap: %s (content: %s)\n", strerror(errno), content);
2728                         return LB_STATUS_ERROR_MEMORY;
2729                 }
2730         }
2731
2732         return LB_STATUS_SUCCESS;
2733 }
2734
2735 int lb_set_title(struct livebox *handler, const char *title)
2736 {
2737         if (handler->title) {
2738                 free(handler->title);
2739                 handler->title = NULL;
2740         }
2741
2742         if (title) {
2743                 handler->title = strdup(title);
2744                 if (!handler->title) {
2745                         CRITICAL_LOG("Heap: %s (title: %s)\n", strerror(errno), title);
2746                         return LB_STATUS_ERROR_MEMORY;
2747                 }
2748         }
2749
2750         return LB_STATUS_SUCCESS;
2751 }
2752
2753 void lb_set_size_list(struct livebox *handler, int size_list)
2754 {
2755         handler->lb.size_list = size_list;
2756 }
2757
2758 void lb_set_auto_launch(struct livebox *handler, const char *auto_launch)
2759 {
2760         if (!strlen(auto_launch))
2761                 return;
2762
2763         handler->lb.auto_launch = strdup(auto_launch);
2764         if (!handler->lb.auto_launch)
2765                 ErrPrint("Heap: %s\n", strerror(errno));
2766 }
2767
2768 void lb_set_priority(struct livebox *handler, double priority)
2769 {
2770         handler->lb.priority = priority;
2771 }
2772
2773 void lb_set_id(struct livebox *handler, const char *id)
2774 {
2775         if (handler->id)
2776                 free(handler->id);
2777
2778         handler->id = strdup(id);
2779         if (!handler->id)
2780                 ErrPrint("Error: %s\n", strerror(errno));
2781
2782         if (handler->filename)
2783                 free(handler->filename);
2784
2785         handler->filename = get_file_kept_in_safe(id);
2786         if (!handler->filename) {
2787                 handler->filename = strdup(util_uri_to_path(id));
2788                 if (!handler->filename)
2789                         ErrPrint("Error: %s\n", strerror(errno));
2790         }
2791 }
2792
2793 int lb_set_lb_fb(struct livebox *handler, const char *filename)
2794 {
2795         struct fb_info *fb;
2796
2797         if (!handler)
2798                 return LB_STATUS_ERROR_INVALID;
2799
2800         fb = handler->lb.data.fb;
2801         if (fb && !strcmp(fb_id(fb), filename)) /*!< BUFFER is not changed, */
2802                 return LB_STATUS_SUCCESS;
2803
2804         handler->lb.data.fb = NULL;
2805
2806         if (!filename || filename[0] == '\0') {
2807                 if (fb)
2808                         fb_destroy(fb);
2809                 return LB_STATUS_SUCCESS;
2810         }
2811
2812         handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
2813         if (!handler->lb.data.fb) {
2814                 ErrPrint("Faield to create a FB\n");
2815                 if (fb)
2816                         fb_destroy(fb);
2817                 return LB_STATUS_ERROR_FAULT;
2818         }
2819
2820         if (fb)
2821                 fb_destroy(fb);
2822
2823         return LB_STATUS_SUCCESS;
2824 }
2825
2826 int lb_set_pd_fb(struct livebox *handler, const char *filename)
2827 {
2828         struct fb_info *fb;
2829
2830         if (!handler)
2831                 return LB_STATUS_ERROR_INVALID;
2832
2833         fb = handler->pd.data.fb;
2834         if (fb && !strcmp(fb_id(fb), filename)) {
2835                 /* BUFFER is not changed, just update the content */
2836                 return LB_STATUS_ERROR_EXIST;
2837         }
2838         handler->pd.data.fb = NULL;
2839
2840         if (!filename || filename[0] == '\0') {
2841                 if (fb)
2842                         fb_destroy(fb);
2843                 return LB_STATUS_SUCCESS;
2844         }
2845
2846         handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
2847         if (!handler->pd.data.fb) {
2848                 ErrPrint("Failed to create a FB\n");
2849                 if (fb)
2850                         fb_destroy(fb);
2851                 return LB_STATUS_ERROR_FAULT;
2852         }
2853
2854         if (fb)
2855                 fb_destroy(fb);
2856         return LB_STATUS_SUCCESS;
2857 }
2858
2859 struct fb_info *lb_get_lb_fb(struct livebox *handler)
2860 {
2861         return handler->lb.data.fb;
2862 }
2863
2864 struct fb_info *lb_get_pd_fb(struct livebox *handler)
2865 {
2866         return handler->pd.data.fb;
2867 }
2868
2869 void lb_set_user(struct livebox *handler, int user)
2870 {
2871         handler->is_user = user;
2872 }
2873
2874 void lb_set_pinup(struct livebox *handler, int pinup_supported)
2875 {
2876         handler->lb.pinup_supported = pinup_supported;
2877 }
2878
2879 void lb_set_text_lb(struct livebox *handler)
2880 {
2881         handler->lb.type = _LB_TYPE_TEXT;
2882 }
2883
2884 void lb_set_text_pd(struct livebox *handler)
2885 {
2886         handler->pd.type = _PD_TYPE_TEXT;
2887 }
2888
2889 int lb_text_lb(struct livebox *handler)
2890 {
2891         return handler->lb.type == _LB_TYPE_TEXT;
2892 }
2893
2894 int lb_text_pd(struct livebox *handler)
2895 {
2896         return handler->pd.type == _PD_TYPE_TEXT;
2897 }
2898
2899 void lb_set_period(struct livebox *handler, double period)
2900 {
2901         handler->lb.period = period;
2902 }
2903
2904 struct livebox *lb_ref(struct livebox *handler)
2905 {
2906         if (!handler)
2907                 return NULL;
2908
2909         handler->refcnt++;
2910         return handler;
2911 }
2912
2913 struct livebox *lb_unref(struct livebox *handler)
2914 {
2915         if (!handler)
2916                 return NULL;
2917
2918         handler->refcnt--;
2919         if (handler->refcnt > 0)
2920                 return handler;
2921
2922         if (handler->created_cb) {
2923                 DbgPrint("Clear created event callback\n");
2924                 handler->created_cb(handler, LB_STATUS_ERROR_FAULT, handler->created_cbdata);
2925                 handler->created_cb = NULL;
2926                 handler->created_cbdata = NULL;
2927         }
2928
2929         if (handler->deleted_cb) {
2930                 DbgPrint("Clear deleted event callback\n");
2931                 handler->deleted_cb(handler, LB_STATUS_ERROR_FAULT, handler->deleted_cbdata);
2932                 handler->deleted_cb = NULL;
2933                 handler->deleted_cbdata = NULL;
2934         }
2935
2936         if (handler->pinup_cb) {
2937                 DbgPrint("Clear pinup event callback\n");
2938                 handler->pinup_cb(handler, LB_STATUS_ERROR_FAULT, handler->pinup_cbdata);
2939                 handler->pinup_cb = NULL;
2940                 handler->pinup_cbdata = NULL;
2941         }
2942
2943         if (handler->group_changed_cb) {
2944                 DbgPrint("Clear group changed event callback\n");
2945                 handler->group_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->group_cbdata);
2946                 handler->group_changed_cb = NULL;
2947                 handler->group_cbdata = NULL;
2948         }
2949
2950         if (handler->period_changed_cb) {
2951                 DbgPrint("Clear period changed event callback\n");
2952                 handler->period_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->period_cbdata);
2953                 handler->period_changed_cb = NULL;
2954                 handler->period_cbdata = NULL;
2955         }
2956
2957         if (handler->size_changed_cb) {
2958                 DbgPrint("Clear size changed event callback\n");
2959                 handler->size_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->size_cbdata);
2960                 handler->size_changed_cb = NULL;
2961                 handler->size_cbdata = NULL;
2962         }
2963
2964         if (handler->pd_created_cb) {
2965                 DbgPrint("Clear pd created event callback\n");
2966                 handler->pd_created_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_created_cbdata);
2967                 handler->pd_created_cb = NULL;
2968                 handler->pd_created_cbdata = NULL;
2969         }
2970
2971         if (handler->pd_destroyed_cb) {
2972                 DbgPrint("Clear pd destroyed event callback\n");
2973                 handler->pd_destroyed_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_destroyed_cbdata);
2974                 handler->pd_destroyed_cb = NULL;
2975                 handler->pd_destroyed_cbdata = NULL;
2976         }
2977
2978         if (handler->update_mode_cb) {
2979                 DbgPrint("Clear update mode callback\n");
2980                 handler->update_mode_cb(handler, LB_STATUS_ERROR_FAULT, handler->update_mode_cbdata);
2981                 handler->update_mode_cb = NULL;
2982                 handler->update_mode_cbdata = NULL;
2983         }
2984
2985         if (handler->access_event_cb) {
2986                 DbgPrint("Clear access status callback\n");
2987                 handler->access_event_cb(handler, LB_STATUS_ERROR_FAULT, handler->access_event_cbdata);
2988                 handler->access_event_cb = NULL;
2989                 handler->access_event_cbdata = NULL;
2990         }
2991
2992         if (handler->filename)
2993                 util_unlink(handler->filename);
2994
2995         dlist_remove_data(s_info.livebox_list, handler);
2996
2997         handler->state = DESTROYED;
2998         free(handler->cluster);
2999         free(handler->category);
3000         free(handler->id);
3001         free(handler->pkgname);
3002         free(handler->filename);
3003         free(handler->lb.auto_launch);
3004
3005         if (handler->lb.data.fb) {
3006                 fb_destroy(handler->lb.data.fb);
3007                 handler->lb.data.fb = NULL;
3008         }
3009
3010         if (handler->pd.data.fb) {
3011                 fb_destroy(handler->pd.data.fb);
3012                 handler->pd.data.fb = NULL;
3013         }
3014
3015         free(handler);
3016         return NULL;
3017 }
3018
3019 int lb_send_delete(struct livebox *handler, ret_cb_t cb, void *data)
3020 {
3021         struct packet *packet;
3022         struct cb_info *cbinfo;
3023         int ret;
3024
3025         if (!cb && !!data) {
3026                 ErrPrint("Invalid argument\n");
3027                 return LB_STATUS_ERROR_INVALID;
3028         }
3029
3030         if (handler->deleted_cb) {
3031                 ErrPrint("Already in-progress\n");
3032                 return LB_STATUS_ERROR_BUSY;
3033         }
3034
3035         packet = packet_create("delete", "ss", handler->pkgname, handler->id);
3036         if (!packet) {
3037                 ErrPrint("Failed to build a param\n");
3038                 if (cb)
3039                         cb(handler, LB_STATUS_ERROR_FAULT, data);
3040
3041                 return LB_STATUS_ERROR_FAULT;
3042         }
3043
3044         if (!cb)
3045                 cb = default_delete_cb;
3046
3047         cbinfo = create_cb_info(cb, data);
3048         if (!cbinfo) {
3049                 packet_destroy(packet);
3050                 return LB_STATUS_ERROR_FAULT;
3051         }
3052
3053         ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
3054         if (ret < 0)
3055                 destroy_cb_info(cbinfo);
3056
3057         return ret;
3058 }
3059
3060 EAPI int livebox_client_paused(void)
3061 {
3062         struct packet *packet;
3063
3064         packet = packet_create_noack("client_paused", "d", util_timestamp());
3065         if (!packet) {
3066                 ErrPrint("Failed to create a pause packet\n");
3067                 return LB_STATUS_ERROR_FAULT;
3068         }
3069
3070         return master_rpc_request_only(NULL, packet);
3071 }
3072
3073 EAPI int livebox_client_resumed(void)
3074 {
3075         struct packet *packet;
3076
3077         packet = packet_create_noack("client_resumed", "d", util_timestamp());
3078         if (!packet) {
3079                 ErrPrint("Failed to create a resume packet\n");
3080                 return LB_STATUS_ERROR_FAULT;
3081         }
3082
3083         return master_rpc_request_only(NULL, packet);
3084 }
3085
3086 /* End of a file */