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