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