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