Support wayland build
[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 <gio/gio.h>
28 #include <aul.h>
29 #include <dlog.h>
30
31 #include <com-core_packet.h>
32 #include <packet.h>
33 #include <livebox-service.h>
34 #include <livebox-errno.h>
35
36 #include "debug.h"
37 #include "fb.h"
38 #include "livebox.h"
39 #include "livebox_internal.h"
40 #include "dlist.h"
41 #include "util.h"
42 #include "master_rpc.h"
43 #include "client.h"
44 #include "conf.h"
45
46 #define EAPI __attribute__((visibility("default")))
47
48 #if defined(FLOG)
49 FILE *__file_log_fp;
50 #endif
51
52 static int default_launch_handler(struct livebox *handler, const char *appid, void *data);
53
54 enum event_state {
55         INFO_STATE_CALLBACK_IN_IDLE = 0x00,
56         INFO_STATE_CALLBACK_IN_PROCESSING = 0x01,
57 };
58
59 static struct info {
60         struct dlist *livebox_list;
61         struct dlist *livebox_common_list;
62
63         struct dlist *event_list;
64         struct dlist *fault_list;
65
66         int init_count;
67         int prevent_overwrite;
68         enum event_state event_state;
69         enum event_state fault_state;
70         guint job_timer;
71         struct dlist *job_list;
72
73         struct launch {
74                 int (*handler)(struct livebox *handler, const char *appid, void *data);
75                 void *data;
76         } launch;
77 } s_info = {
78         .livebox_list = NULL,
79         .event_list = NULL,
80         .fault_list = NULL,
81         .init_count = 0,
82         .prevent_overwrite = 0,
83         .event_state = INFO_STATE_CALLBACK_IN_IDLE,
84         .fault_state = INFO_STATE_CALLBACK_IN_IDLE,
85         .job_timer = 0,
86         .job_list = NULL,
87         .launch = {
88                 .handler = default_launch_handler,
89                 .data = NULL,
90         },
91 };
92
93 struct cb_info {
94         ret_cb_t cb;
95         void *data;
96 };
97
98 struct event_info {
99         int is_deleted;
100         int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data);
101         void *user_data;
102 };
103
104 struct fault_info {
105         int is_deleted;
106         int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data);
107         void *user_data;
108 };
109
110 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data);
111 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data);
112
113 static int default_launch_handler(struct livebox *handler, const char *appid, void *data)
114 {
115         int ret;
116
117         ret = aul_launch_app(appid, NULL);
118         if (ret <= 0) {
119                 ErrPrint("Failed to launch an app %s (%d)\n", appid, ret);
120         }
121
122 /*
123         service_h service;
124
125         DbgPrint("AUTO_LAUNCH [%s]\n", handler->common->lb.auto_launch);
126
127         ret = service_create(&service);
128         if (ret == SERVICE_ERROR_NONE) {
129                 service_set_package(service, handler->common->lb.auto_launch);
130                 service_send_launch_request(service, NULL, NULL);
131                 service_destroy(service);
132         } else {
133                 ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
134         }
135 */
136
137         return ret > 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
138 }
139
140 static inline void default_create_cb(struct livebox *handler, int ret, void *data)
141 {
142         DbgPrint("Default created event handler: %d\n", ret);
143 }
144
145 static inline void default_delete_cb(struct livebox *handler, int ret, void *data)
146 {
147         DbgPrint("Default deleted event handler: %d\n", ret);
148 }
149
150 static inline void default_pinup_cb(struct livebox *handler, int ret, void *data)
151 {
152         DbgPrint("Default pinup event handler: %d\n", ret);
153 }
154
155 static inline void default_group_changed_cb(struct livebox *handler, int ret, void *data)
156 {
157         DbgPrint("Default group changed event handler: %d\n", ret);
158 }
159
160 static inline void default_period_changed_cb(struct livebox *handler, int ret, void *data)
161 {
162         DbgPrint("Default period changed event handler: %d\n", ret);
163 }
164
165 static inline void default_pd_created_cb(struct livebox *handler, int ret, void *data)
166 {
167         DbgPrint("Default PD created event handler: %d\n", ret);
168 }
169
170 static inline void default_pd_destroyed_cb(struct livebox *handler, int ret, void *data)
171 {
172         DbgPrint("Default PD destroyed event handler: %d\n", ret);
173 }
174
175 static inline void default_lb_size_changed_cb(struct livebox *handler, int ret, void *data)
176 {
177         DbgPrint("Default LB size changed event handler: %d\n", ret);
178 }
179
180 static inline void default_update_mode_cb(struct livebox *handler, int ret, void *data)
181 {
182         DbgPrint("Default update mode set event handler: %d\n", ret);
183 }
184
185 static inline void default_access_event_cb(struct livebox *handler, int ret, void *data)
186 {
187         DbgPrint("Default access event handler: %d\n", ret);
188 }
189
190 static inline void default_key_event_cb(struct livebox *handler, int ret, void *data)
191 {
192         DbgPrint("Default key event handler: %d\n", ret);
193 }
194
195 static inline __attribute__((always_inline)) struct cb_info *create_cb_info(ret_cb_t cb, void *data)
196 {
197         struct cb_info *info;
198
199         info = malloc(sizeof(*info));
200         if (!info) {
201                 ErrPrint("Heap: %s\n", strerror(errno));
202                 return NULL;
203         }
204
205         info->cb = cb;
206         info->data = data;
207         return info;
208 }
209
210 static inline void destroy_cb_info(struct cb_info *info)
211 {
212         free(info);
213 }
214
215 static int do_fb_lock(int fd)
216 {
217         struct flock flock;
218         int ret;
219
220         flock.l_type = F_RDLCK;
221         flock.l_whence = SEEK_SET;
222         flock.l_start = 0;
223         flock.l_len = 0;
224         flock.l_pid = getpid();
225
226         do {
227                 ret = fcntl(fd, F_SETLKW, &flock);
228                 if (ret < 0) {
229                         ret = errno;
230                         ErrPrint("fcntl: %s\n", strerror(errno));
231                 }
232         } while (ret == EINTR);
233
234         return ret;
235 }
236
237 static int do_fb_unlock(int fd)
238 {
239         struct flock flock;
240         int ret;
241
242         flock.l_type = F_UNLCK;
243         flock.l_whence = SEEK_SET;
244         flock.l_start = 0;
245         flock.l_len = 0;
246         flock.l_pid = getpid();
247
248         do {
249                 ret = fcntl(fd, F_SETLKW, &flock);
250                 if (ret < 0) {
251                         ret = errno;
252                         ErrPrint("fcntl: %s\n", strerror(errno));
253                 }
254         } while (ret == EINTR);
255
256         return ret;
257 }
258
259 int lb_destroy_lock_file(struct livebox_common *common, int is_pd)
260 {
261         if (is_pd) {
262                 if (!common->pd.lock) {
263                         return LB_STATUS_ERROR_INVALID;
264                 }
265
266                 if (close(common->pd.lock_fd) < 0) {
267                         ErrPrint("close: %s\n", strerror(errno));
268                 }
269                 common->pd.lock_fd = -1;
270
271                 if (unlink(common->pd.lock) < 0) {
272                         ErrPrint("unlink: %s\n", strerror(errno));
273                 }
274
275                 free(common->pd.lock);
276                 common->pd.lock = NULL;
277         } else {
278                 if (!common->lb.lock) {
279                         return LB_STATUS_ERROR_INVALID;
280                 }
281
282                 if (close(common->lb.lock_fd) < 0) {
283                         ErrPrint("close: %s\n", strerror(errno));
284                 }
285                 common->lb.lock_fd = -1;
286
287                 if (unlink(common->lb.lock) < 0) {
288                         ErrPrint("unlink: %s\n", strerror(errno));
289                 }
290
291                 free(common->lb.lock);
292                 common->lb.lock = NULL;
293         }
294
295         return LB_STATUS_SUCCESS;
296 }
297
298 int lb_create_lock_file(struct livebox_common *common, int is_pd)
299 {
300         int len;
301         char *file;
302
303         len = strlen(common->id);
304         file = malloc(len + 20);
305         if (!file) {
306                 ErrPrint("Heap: %s\n", strerror(errno));
307                 return LB_STATUS_ERROR_MEMORY;
308         }
309
310         snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(common->id), is_pd ? "pd" : "lb");
311
312         if (is_pd) {
313                 common->pd.lock_fd = open(file, O_RDONLY);
314                 if (common->pd.lock_fd < 0) {
315                         ErrPrint("open: %s\n", strerror(errno));
316                         free(file);
317                         return LB_STATUS_ERROR_IO;
318                 }
319
320                 common->pd.lock = file;
321         } else {
322                 common->lb.lock_fd = open(file, O_RDONLY);
323                 if (common->lb.lock_fd < 0) {
324                         ErrPrint("open: %s\n", strerror(errno));
325                         free(file);
326                         return LB_STATUS_ERROR_IO;
327                 }
328
329                 common->lb.lock = file;
330         }
331
332         return LB_STATUS_SUCCESS;
333 }
334
335 static void update_mode_cb(struct livebox *handler, const struct packet *result, void *data)
336 {
337         int ret;
338
339         if (!result) {
340                 ret = LB_STATUS_ERROR_FAULT;
341                 goto errout;
342         } else if (packet_get(result, "i", &ret) != 1) {
343                 ErrPrint("Invalid argument\n");
344                 ret = LB_STATUS_ERROR_INVALID;
345                 goto errout;
346         }
347
348         if (ret < 0) {
349                 ErrPrint("Resize request is failed: %d\n", ret);
350                 goto errout;
351         }
352
353         return;
354
355 errout:
356         handler->cbs.update_mode.cb(handler, ret, handler->cbs.update_mode.data);
357         handler->cbs.update_mode.cb = NULL;
358         handler->cbs.update_mode.data = NULL;
359         handler->common->request.update_mode = 0;
360
361         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
362                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
363                 lb_unref(handler, 1);
364         }
365 }
366
367 static void resize_cb(struct livebox *handler, const struct packet *result, void *data)
368 {
369         int ret;
370
371         if (!result) {
372                 ret = LB_STATUS_ERROR_FAULT;
373                 goto errout;
374         } else if (packet_get(result, "i", &ret) != 1) {
375                 ErrPrint("Invalid argument\n");
376                 ret = LB_STATUS_ERROR_INVALID;
377                 goto errout;
378         }
379
380         /*!
381          * \note
382          * In case of resize request,
383          * The livebox handler will not have resized value right after this callback,
384          * It can only get the new size when it makes updates.
385          *
386          * So the user can only get the resized value(result) from the first update event
387          * after this request.
388          */
389         if (ret < 0) {
390                 ErrPrint("Resize request is failed: %d\n", ret);
391                 goto errout;
392         }
393
394         return;
395
396 errout:
397         handler->cbs.size_changed.cb(handler, ret, handler->cbs.size_changed.data);
398         handler->cbs.size_changed.cb = NULL;
399         handler->cbs.size_changed.data = NULL;
400         handler->common->request.size_changed = 0;
401
402         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
403                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
404                 lb_unref(handler, 1);
405         }
406 }
407
408 static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data)
409 {
410         int ret;
411         void *cbdata;
412         struct cb_info *info = data;
413         ret_cb_t cb;
414
415         cbdata = info->data;
416         cb = info->cb;
417         destroy_cb_info(info);
418
419         if (!result) {
420                 ret = LB_STATUS_ERROR_FAULT;
421         } else if (packet_get(result, "i", &ret) != 1) {
422                 ErrPrint("Invalid argument\n");
423                 ret = LB_STATUS_ERROR_INVALID;
424         }
425
426         if (cb) {
427                 cb(handler, ret, cbdata);
428         }
429         return;
430 }
431
432 static void set_group_ret_cb(struct livebox *handler, const struct packet *result, void *data)
433 {
434         int ret;
435
436         if (!result) {
437                 ret = LB_STATUS_ERROR_FAULT;
438                 goto errout;
439         } else if (packet_get(result, "i", &ret) != 1) {
440                 ErrPrint("Invalid argument\n");
441                 ret = LB_STATUS_ERROR_INVALID;
442                 goto errout;
443         }
444
445         if (ret < 0) {
446                 goto errout;
447         }
448
449         return;
450
451 errout:
452         handler->cbs.group_changed.cb(handler, ret, handler->cbs.group_changed.data);
453         handler->cbs.group_changed.cb = NULL;
454         handler->cbs.group_changed.data = NULL;
455         handler->common->request.group_changed = 0;
456
457         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
458                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
459                 lb_unref(handler, 1);
460         }
461 }
462
463 static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data)
464 {
465         int ret;
466
467         if (!result) {
468                 ret = LB_STATUS_ERROR_FAULT;
469                 goto errout;
470         } else if (packet_get(result, "i", &ret) != 1) {
471                 ErrPrint("Invalid argument\n");
472                 ret = LB_STATUS_ERROR_INVALID;
473                 goto errout;
474         }
475
476         if (ret < 0) {
477                 goto errout;
478         }
479
480         return;
481
482 errout:
483         handler->cbs.period_changed.cb(handler, ret, handler->cbs.period_changed.data);
484         handler->cbs.period_changed.cb = NULL;
485         handler->cbs.period_changed.data = NULL;
486         handler->common->request.period_changed = 0;
487
488         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
489                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
490                 lb_unref(handler, 1);
491         }
492 }
493
494 static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data)
495 {
496         struct cb_info *info = data;
497         int ret;
498         ret_cb_t cb;
499         void *cbdata;
500
501         cb = info->cb;
502         cbdata = info->data;
503         destroy_cb_info(info);
504
505         if (!result) {
506                 ErrPrint("Connection lost?\n");
507                 ret = LB_STATUS_ERROR_FAULT;
508         } else if (packet_get(result, "i", &ret) != 1) {
509                 ErrPrint("Invalid argument\n");
510                 ret = LB_STATUS_ERROR_INVALID;
511         }
512
513         if (ret == 0) {
514                 handler->cbs.deleted.cb = cb;
515                 handler->cbs.deleted.data = cbdata;
516         } else if (cb) {
517                 cb(handler, ret, cbdata);
518         }
519
520         /*!
521          * \note
522          * Do not call the deleted callback from here.
523          * master will send the "deleted" event.
524          * Then invoke this callback.
525          *
526          * if (handler->cbs.deleted.cb)
527          *      handler->cbs.deleted.cb(handler, ret, handler->cbs.deleted.data);
528          */
529 }
530
531 static void new_ret_cb(struct livebox *handler, const struct packet *result, void *data)
532 {
533         int ret;
534         struct cb_info *info = data;
535         ret_cb_t cb;
536         void *cbdata;
537
538         cb = info->cb;
539         cbdata = info->data;
540         destroy_cb_info(info);
541
542         if (!result) {
543                 ret = LB_STATUS_ERROR_FAULT;
544         } else if (packet_get(result, "i", &ret) != 1) {
545                 ret = LB_STATUS_ERROR_INVALID;
546         }
547
548         if (ret >= 0) {
549                 handler->cbs.created.cb = cb;
550                 handler->cbs.created.data = cbdata;
551
552                 /*!
553                  * \note
554                  * Don't go anymore ;)
555                  */
556                 return;
557         } else if (cb) {
558                 /*!
559                  * \note
560                  * It means the current instance is not created,
561                  * so user has to know about this.
562                  * notice it to user using "deleted" event.
563                  */
564                 cb(handler, ret, cbdata);
565         }
566
567         lb_unref(handler, 1);
568 }
569
570 static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data)
571 {
572         int ret;
573
574         if (!result) {
575                 ret = LB_STATUS_ERROR_FAULT;
576                 goto errout;
577         } else if (packet_get(result, "i", &ret) != 1) {
578                 ret = LB_STATUS_ERROR_INVALID;
579                 goto errout;
580         }
581
582         if (ret < 0) {
583                 ErrPrint("Failed to create a PD[%d]\n", ret);
584                 goto errout;
585         }
586
587         return;
588
589 errout:
590         handler->cbs.pd_created.cb(handler, ret, handler->cbs.pd_created.data);
591         handler->cbs.pd_created.cb = NULL;
592         handler->cbs.pd_created.data = NULL;
593         handler->common->request.pd_created = 0;
594
595         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
596                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
597                 lb_unref(handler, 1);
598         }
599 }
600
601 static void activated_cb(struct livebox *handler, const struct packet *result, void *data)
602 {
603         int ret;
604         struct cb_info *info = data;
605         void *cbdata;
606         ret_cb_t cb;
607         const char *pkgname = "";
608
609         cbdata = info->data;
610         cb = info->cb;
611         destroy_cb_info(info);
612
613         if (!result) {
614                 ret = LB_STATUS_ERROR_FAULT;
615         } else if (packet_get(result, "is", &ret, &pkgname) != 2) {
616                 ret = LB_STATUS_ERROR_INVALID;
617         }
618
619         if (cb) {
620                 cb(handler, ret, cbdata);
621         }
622 }
623
624 static void pd_destroy_cb(struct livebox *handler, const struct packet *result, void *data)
625 {
626         int ret;
627         ret_cb_t cb;
628         void *cbdata;
629         struct cb_info *info = data;
630
631         cbdata = info->data;
632         cb = info->cb;
633         destroy_cb_info(info);
634
635         if (!result) {
636                 ErrPrint("Result is NIL (may connection lost)\n");
637                 ret = LB_STATUS_ERROR_FAULT;
638         } else if (packet_get(result, "i", &ret) != 1) {
639                 ErrPrint("Invalid parameter\n");
640                 ret = LB_STATUS_ERROR_INVALID;
641         }
642
643         if (ret == (int)LB_STATUS_SUCCESS) {
644                 handler->cbs.pd_destroyed.cb = cb;
645                 handler->cbs.pd_destroyed.data = cbdata;
646         } else {
647                 handler->common->is_pd_created = 0;
648                 handler->common->request.pd_destroyed = 0;
649
650                 if (cb) {
651                         cb(handler, ret, cbdata);
652                 }
653         }
654 }
655
656 static void delete_cluster_cb(struct livebox *handler, const struct packet *result, void *data)
657 {
658         struct cb_info *info = data;
659         int ret;
660         ret_cb_t cb;
661         void *cbdata;
662
663         cb = info->cb;
664         cbdata = info->data;
665         destroy_cb_info(info);
666
667         if (!result) {
668                 ret = LB_STATUS_ERROR_FAULT;
669         } else if (packet_get(result, "i", &ret) != 1) {
670                 ret = LB_STATUS_ERROR_INVALID;
671         }
672
673         if (cb) {
674                 cb(handler, ret, cbdata);
675         }
676 }
677
678 static void delete_category_cb(struct livebox *handler, const struct packet *result, void *data)
679 {
680         struct cb_info *info = data;
681         int ret;
682         ret_cb_t cb;
683         void *cbdata;
684
685         cb = info->cb;
686         cbdata = info->data;
687         destroy_cb_info(info);
688
689         if (!result) {
690                 ret = LB_STATUS_ERROR_FAULT;
691         } else if (packet_get(result, "i", &ret) != 1) {
692                 ret = LB_STATUS_ERROR_INVALID;
693         }
694
695         if (cb) {
696                 cb(handler, ret, cbdata);
697         }
698 }
699
700 static int lb_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
701 {
702         struct packet *packet;
703         struct cb_info *cbinfo;
704         const char *id;
705         int ret;
706
707         id = fb_id(handler->common->lb.fb);
708         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
709                 return LB_STATUS_ERROR_INVALID;
710         }
711
712         packet = packet_create("lb_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
713         if (!packet) {
714                 ErrPrint("Failed to build a param\n");
715                 return LB_STATUS_ERROR_FAULT;
716         }
717
718         cbinfo = create_cb_info(cb, data);
719         if (!cbinfo) {
720                 packet_destroy(packet);
721                 return LB_STATUS_ERROR_FAULT;
722         }
723
724         ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo);
725         if (ret < 0) {
726                 destroy_cb_info(cbinfo);
727         }
728
729         return ret;
730 }
731
732 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
733 {
734         int pixmap;
735         int ret = LB_STATUS_ERROR_INVALID;
736         ret_cb_t cb;
737         void *cbdata;
738         struct cb_info *info = data;
739
740         cb = info->cb;
741         cbdata = info->data;
742         destroy_cb_info(info);
743
744         if (!result) {
745                 pixmap = 0; /* PIXMAP 0 means error */
746         } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
747                 pixmap = 0;
748         }
749
750         if (ret == (int)LB_STATUS_ERROR_BUSY) {
751                 ret = lb_acquire_lb_pixmap(handler, cb, cbdata);
752                 DbgPrint("Busy, Try again: %d\n", ret);
753                 /* Try again */
754         } else if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
755                 if (cb) {
756                         cb(handler, pixmap, cbdata);
757                 }
758
759                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
760                 lb_unref(handler, 1);
761         } else {
762                 if (cb) {
763                         cb(handler, pixmap, cbdata);
764                 }
765         }
766 }
767
768 static int lb_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
769 {
770         struct packet *packet;
771         struct cb_info *cbinfo;
772         const char *id;
773         int ret;
774
775         id = fb_id(handler->common->pd.fb);
776         if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
777                 return LB_STATUS_ERROR_INVALID;
778         }
779
780         packet = packet_create("pd_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
781         if (!packet) {
782                 ErrPrint("Failed to build a param\n");
783                 return LB_STATUS_ERROR_FAULT;
784         }
785
786         cbinfo = create_cb_info(cb, data);
787         if (!cbinfo) {
788                 packet_destroy(packet);
789                 return LB_STATUS_ERROR_FAULT;
790         }
791
792         ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo);
793         if (ret < 0) {
794                 /*!
795                  * \note
796                  * Packet will be destroyed by master_rpc_async_request
797                  */
798                 destroy_cb_info(cbinfo);
799         }
800
801         return ret;
802 }
803
804 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
805 {
806         int pixmap;
807         int ret;
808         ret_cb_t cb;
809         void *cbdata;
810         struct cb_info *info = data;
811
812         cb = info->cb;
813         cbdata = info->data;
814         destroy_cb_info(info);
815
816         if (!result) {
817                 pixmap = 0; /* PIXMAP 0 means error */
818                 ret = LB_STATUS_ERROR_FAULT;
819         } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
820                 pixmap = 0;
821                 ret = LB_STATUS_ERROR_INVALID;
822         }
823
824         if (ret == (int)LB_STATUS_ERROR_BUSY) {
825                 ret = lb_acquire_pd_pixmap(handler, cb, cbdata);
826                 DbgPrint("Busy, Try again: %d\n", ret);
827                 /* Try again */
828         } else if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
829                 if (cb) {
830                         cb(handler, pixmap, cbdata);
831                 }
832                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
833                 lb_unref(handler, 1);
834         } else {
835                 if (cb) {
836                         DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap);
837                         cb(handler, pixmap, cbdata);
838                 }
839         }
840 }
841
842 static void pinup_done_cb(struct livebox *handler, const struct packet *result, void *data)
843 {
844         int ret;
845
846         if (!result) {
847                 ret = LB_STATUS_ERROR_FAULT;
848                 goto errout;
849         } else if (packet_get(result, "i", &ret) != 1) {
850                 goto errout;
851         }
852
853         if (ret < 0) {
854                 goto errout;
855         }
856
857         return;
858
859 errout:
860         handler->cbs.pinup.cb(handler, ret, handler->cbs.pinup.data);
861         handler->cbs.pinup.cb = NULL;
862         handler->cbs.pinup.data = NULL;
863         handler->common->request.pinup = 0;
864
865         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
866                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
867                 lb_unref(handler, 1);
868         }
869 }
870
871 static void key_ret_cb(struct livebox *handler, const struct packet *result, void *data)
872 {
873         int ret;
874
875         if (!result) {
876                 ret = LB_STATUS_ERROR_FAULT;
877                 return;
878         }
879
880         if (packet_get(result, "i", &ret) != 1) {
881                 ret = LB_STATUS_ERROR_INVALID;
882                 return;
883         }
884
885         if (ret != LB_STATUS_SUCCESS) {
886                 goto errout;
887         }
888
889         return;
890 errout:
891         handler->cbs.key_event.cb(handler, ret, handler->cbs.key_event.data);
892         handler->cbs.key_event.cb = NULL;
893         handler->cbs.key_event.data = NULL;
894         handler->common->request.key_event = 0;
895
896         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
897                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
898                 lb_unref(handler, 1);
899         }
900 }
901
902 static void access_ret_cb(struct livebox *handler, const struct packet *result, void *data)
903 {
904         int ret;
905
906         if (!result) {
907                 ret = LB_STATUS_ERROR_FAULT;
908                 return;
909         }
910
911         if (packet_get(result, "i", &ret) != 1) {
912                 ret = LB_STATUS_ERROR_INVALID;
913                 return;
914         }
915
916         if (ret != LB_STATUS_SUCCESS) {
917                 goto errout;
918         }
919
920         return;
921
922 errout:
923         handler->cbs.access_event.cb(handler, ret, handler->cbs.access_event.data);
924         handler->cbs.access_event.cb = NULL;
925         handler->cbs.access_event.data = NULL;
926         handler->common->request.access_event = 0;
927
928         if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
929                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
930                 lb_unref(handler, 1);
931         }
932 }
933
934 static int send_access_event(struct livebox *handler, const char *event, int x, int y)
935 {
936         struct packet *packet;
937         double timestamp;
938
939         timestamp = util_timestamp();
940
941         packet = packet_create(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
942         if (!packet) {
943                 ErrPrint("Failed to build packet\n");
944                 return LB_STATUS_ERROR_FAULT;
945         }
946
947         return master_rpc_async_request(handler, packet, 0, access_ret_cb, NULL);
948 }
949
950 static int send_key_event(struct livebox *handler, const char *event, unsigned int keycode)
951 {
952         struct packet *packet;
953         double timestamp;
954
955         timestamp = util_timestamp();
956         packet = packet_create(event, "ssdi", handler->common->pkgname, handler->common->id, timestamp, keycode);
957         if (!packet) {
958                 ErrPrint("Failed to build packet\n");
959                 return LB_STATUS_ERROR_FAULT;
960         }
961
962         return master_rpc_async_request(handler, packet, 0, key_ret_cb, NULL);
963 }
964
965 static int send_mouse_event(struct livebox *handler, const char *event, int x, int y)
966 {
967         struct packet *packet;
968         double timestamp;
969
970         timestamp = util_timestamp();
971         packet = packet_create_noack(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
972         if (!packet) {
973                 ErrPrint("Failed to build param\n");
974                 return LB_STATUS_ERROR_FAULT;
975         }
976
977         return master_rpc_request_only(handler, packet);
978 }
979
980 static void initialize_livebox(void *disp, int use_thread)
981 {
982 #if defined(FLOG)
983         char filename[BUFSIZ];
984         snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid());
985         __file_log_fp = fopen(filename, "w+t");
986         if (!__file_log_fp) {
987                 __file_log_fp = fdopen(1, "w+t");
988         }
989 #endif
990         livebox_service_init();
991         fb_init(disp);
992
993         client_init(use_thread);
994
995         s_info.init_count++;
996 }
997
998 EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread)
999 {
1000         if (s_info.init_count > 0) {
1001                 s_info.init_count++;
1002                 return LB_STATUS_SUCCESS;
1003         }
1004
1005         /*!
1006          * \note
1007          * Some application doesn't want to use the environment value.
1008          * So set them using arguments.
1009          */
1010         s_info.prevent_overwrite = prevent_overwrite;
1011         conf_set_event_filter(event_filter);
1012
1013         initialize_livebox(disp, use_thread);
1014         return LB_STATUS_SUCCESS;
1015 }
1016
1017 EAPI int livebox_init(void *disp)
1018 {
1019         const char *env;
1020
1021         if (s_info.init_count > 0) {
1022                 s_info.init_count++;
1023                 return LB_STATUS_SUCCESS;
1024         }
1025
1026         env = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE");
1027         if (env && !strcasecmp(env, "true")) {
1028                 s_info.prevent_overwrite = 1;
1029         }
1030
1031         env = getenv("PROVIDER_EVENT_FILTER");
1032         if (env) {
1033                 double event_filter;
1034                 if (sscanf(env, "%lf", &event_filter) == 1) {
1035                         conf_set_event_filter(event_filter);
1036                 }
1037         }
1038
1039         initialize_livebox(disp, 0);
1040         return LB_STATUS_SUCCESS;
1041 }
1042
1043 EAPI int livebox_fini(void)
1044 {
1045         if (s_info.init_count <= 0) {
1046                 ErrPrint("Doesn't initialized\n");
1047                 return LB_STATUS_ERROR_INVALID;
1048         }
1049
1050         s_info.init_count--;
1051         if (s_info.init_count > 0) {
1052                 ErrPrint("init count : %d\n", s_info.init_count);
1053                 return LB_STATUS_SUCCESS;
1054         }
1055
1056         client_fini();
1057         fb_fini();
1058         livebox_service_fini();
1059         return LB_STATUS_SUCCESS;
1060 }
1061
1062 static inline char *lb_pkgname(const char *pkgname)
1063 {
1064         char *lb;
1065
1066         lb = livebox_service_pkgname(pkgname);
1067         if (!lb) {
1068                 if (util_validate_livebox_package(pkgname) == 0) {
1069                         return strdup(pkgname);
1070                 }
1071         }
1072
1073         return lb;
1074 }
1075
1076 static struct livebox_common *find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category)
1077 {
1078         struct dlist *l;
1079         struct livebox_common *common;
1080
1081         if (!conf_shared_content()) {
1082                 /*!
1083                  * Shared content option is turnned off.
1084                  */
1085                 return NULL;
1086         }
1087
1088         dlist_foreach(s_info.livebox_common_list, l, common) {
1089                 if (common->state != CREATE) {
1090                         continue;
1091                 }
1092
1093                 if (strcmp(common->pkgname, pkgname)) {
1094                         continue;
1095                 }
1096
1097                 if (strcmp(common->cluster, cluster)) {
1098                         DbgPrint("Cluster mismatched\n");
1099                         continue;
1100                 }
1101
1102                 if (strcmp(common->category, category)) {
1103                         DbgPrint("Category mismatched\n");
1104                         continue;
1105                 }
1106
1107                 if (common->content && content) {
1108                         if (strcmp(common->content, content)) {
1109                                 DbgPrint("%s Content ([%s] <> [%s])\n", common->pkgname, common->content, content);
1110                                 continue;       
1111                         }
1112                 } else {
1113                         int c1_len;
1114                         int c2_len;
1115
1116                         /*!
1117                          * \note
1118                          * We assumes "" (ZERO length string) to NULL
1119                          */
1120                         c1_len = common->content ? strlen(common->content) : 0;
1121                         c2_len = content ? strlen(content) : 0;
1122                         if (c1_len != c2_len) {
1123                                 DbgPrint("%s Content %p <> %p\n", common->pkgname, common->content, content);
1124                                 continue;
1125                         }
1126                 }
1127
1128                 if (common->request.size_changed) {
1129                         DbgPrint("Changing size\n");
1130                         /*!
1131                          * \note
1132                          * Do not re-use resizing instance.
1133                          * We will not use predicted size.
1134                          */
1135                         continue;
1136                 }
1137
1138                 if (common->request.created) {
1139                         DbgPrint("Creating now but re-use it (%s)\n", common->pkgname);
1140                 }
1141
1142                 if (common->lb.width != w || common->lb.height != h) {
1143                         DbgPrint("Size mismatched\n");
1144                         continue;
1145                 }
1146
1147                 DbgPrint("common handle is found: %p\n", common);
1148                 return common;
1149         }
1150
1151         return NULL;
1152 }
1153
1154 /*!
1155  * Just wrapping the livebox_add_with_size function.
1156  */
1157 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)
1158 {
1159         return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data);
1160 }
1161
1162 static gboolean job_execute_cb(void *data)
1163 {
1164         struct job_item *item;
1165         struct dlist *l;
1166
1167         l = dlist_nth(s_info.job_list, 0);
1168         if (!l) {
1169                 s_info.job_timer = 0;
1170                 return FALSE;
1171         }
1172
1173         item = dlist_data(l);
1174         s_info.job_list = dlist_remove(s_info.job_list, l);
1175
1176         if (item) {
1177                 item->cb(item->handle, item->ret, item->data);
1178                 lb_unref(item->handle, 1);
1179                 free(item);
1180         }
1181
1182         return TRUE;
1183 }
1184
1185 static int job_add(struct livebox *handle, ret_cb_t job_cb, int ret, void *data)
1186 {
1187         struct job_item *item;
1188
1189         if (!job_cb) {
1190                 ErrPrint("Invalid argument\n");
1191                 return LB_STATUS_ERROR_INVALID;
1192         }
1193
1194         item = malloc(sizeof(*item));
1195         if (!item) {
1196                 ErrPrint("Heap: %s\n", strerror(errno));
1197                 return LB_STATUS_ERROR_MEMORY;
1198         }
1199
1200         item->handle = lb_ref(handle);
1201         item->cb = job_cb;
1202         item->data = data;
1203         item->ret = ret;
1204
1205         s_info.job_list = dlist_append(s_info.job_list, item);
1206
1207         if (!s_info.job_timer) {
1208                 s_info.job_timer = g_timeout_add(1, job_execute_cb, NULL);
1209                 if (!s_info.job_timer) {
1210                         ErrPrint("Failed to create a job timer\n");
1211                 }
1212         }
1213
1214         return LB_STATUS_SUCCESS;
1215 }
1216
1217 static int create_real_instance(struct livebox *handler, ret_cb_t cb, void *data)
1218 {
1219         struct cb_info *cbinfo;
1220         struct packet *packet;
1221         struct livebox_common *common;
1222         int ret;
1223
1224         common = handler->common;
1225
1226         packet = packet_create("new", "dssssdii",
1227                                 common->timestamp, common->pkgname, common->content,
1228                                 common->cluster, common->category,
1229                                 common->lb.period, common->lb.width, common->lb.height);
1230         if (!packet) {
1231                 ErrPrint("Failed to create a new packet\n");
1232                 return LB_STATUS_ERROR_FAULT;
1233         }
1234
1235         cbinfo = create_cb_info(cb, data);
1236         if (!cbinfo) {
1237                 ErrPrint("Failed to create a cbinfo\n");
1238                 packet_destroy(packet);
1239                 return LB_STATUS_ERROR_MEMORY;
1240         }
1241
1242         /*!
1243          * \note
1244          * master_rpc_async_request will destroy the packet (decrease the refcnt)
1245          * So be aware the packet object after return from master_rpc_async_request.
1246          */
1247         ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo);
1248         if (ret < 0) {
1249                 ErrPrint("Failed to send a new packet\n");
1250                 destroy_cb_info(cbinfo);
1251                 return LB_STATUS_ERROR_FAULT;
1252         }
1253         handler->common->request.created = 1;
1254         return LB_STATUS_SUCCESS;
1255 }
1256
1257 static void create_cb(struct livebox *handle, int ret, void *data)
1258 {
1259         struct cb_info *cbinfo = data;
1260
1261         if (cbinfo->cb) {
1262                 cbinfo->cb(handle, ret, cbinfo->data);
1263         }
1264
1265         destroy_cb_info(cbinfo);
1266
1267         /*!
1268          * \note
1269          * Forcely generate "updated" event
1270          */
1271         lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
1272 }
1273
1274 static int create_fake_instance(struct livebox *handler, ret_cb_t cb, void *data)
1275 {
1276         struct cb_info *cbinfo;
1277
1278         cbinfo = create_cb_info(cb, data);
1279         if (!cbinfo) {
1280                 ErrPrint("Failed to create a cbinfo\n");
1281                 return LB_STATUS_ERROR_MEMORY;
1282         }
1283
1284         if (job_add(handler, create_cb, LB_STATUS_SUCCESS, cbinfo) != LB_STATUS_SUCCESS) {
1285                 destroy_cb_info(cbinfo);
1286         }
1287
1288         return LB_STATUS_SUCCESS;
1289 }
1290
1291 struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category)
1292 {
1293         struct livebox_common *common;
1294
1295         common = calloc(1, sizeof(*common));
1296         if (!common) {
1297                 ErrPrint("Heap: %s\n", strerror(errno));
1298                 return NULL;
1299         }
1300
1301         common->pkgname = strdup(pkgname);
1302         if (!common->pkgname) {
1303                 free(common);
1304                 return NULL;
1305         }
1306
1307         common->cluster = strdup(cluster);
1308         if (!common->cluster) {
1309                 ErrPrint("Error: %s\n", strerror(errno));
1310                 free(common->pkgname);
1311                 free(common);
1312                 return NULL;
1313         }
1314
1315         common->category = strdup(category);
1316         if (!common->category) {
1317                 ErrPrint("Error: %s\n", strerror(errno));
1318                 free(common->cluster);
1319                 free(common->pkgname);
1320                 free(common);
1321                 return NULL;
1322         }
1323
1324         /* Data provider will set this */
1325         common->lb.type = _LB_TYPE_FILE;
1326         common->pd.type = _PD_TYPE_SCRIPT;
1327
1328         /* Used for handling the mouse event on a box */
1329         common->lb.mouse_event = livebox_service_mouse_event(common->pkgname);
1330
1331         /* Cluster infomration is not determined yet */
1332         common->nr_of_sizes = 0x01;
1333
1334         common->timestamp = util_timestamp();
1335         common->is_user = 1;
1336         common->delete_type = LB_DELETE_PERMANENTLY;
1337         common->pd.lock = NULL;
1338         common->pd.lock_fd = -1;
1339         common->lb.lock = NULL;
1340         common->lb.lock_fd = -1;
1341
1342         common->state = CREATE;
1343         common->visible = LB_SHOW;
1344
1345         s_info.livebox_common_list = dlist_append(s_info.livebox_common_list, common);
1346         return common;
1347 }
1348
1349 int lb_destroy_common_handle(struct livebox_common *common)
1350 {
1351         dlist_remove_data(s_info.livebox_common_list, common);
1352
1353         common->state = DESTROYED;
1354
1355         if (common->filename) {
1356                 (void)util_unlink(common->filename);
1357         }
1358
1359         free(common->cluster);
1360         free(common->category);
1361         free(common->id);
1362         free(common->pkgname);
1363         free(common->filename);
1364         free(common->lb.auto_launch);
1365         free(common->alt.icon);
1366         free(common->alt.name);
1367
1368         if (common->lb.fb) {
1369                 fb_destroy(common->lb.fb);
1370                 common->lb.fb = NULL;
1371         }
1372
1373         if (common->pd.fb) {
1374                 fb_destroy(common->pd.fb);
1375                 common->pd.fb = NULL;
1376         }
1377
1378         return 0;
1379 }
1380
1381 int lb_common_ref(struct livebox_common *common, struct livebox *handle)
1382 {
1383         common->livebox_list = dlist_append(common->livebox_list, handle);
1384         common->refcnt++;
1385
1386         return common->refcnt;
1387 }
1388
1389 int lb_common_unref(struct livebox_common *common, struct livebox *handle)
1390 {
1391         int refcnt;
1392         dlist_remove_data(common->livebox_list, handle);
1393         refcnt = --common->refcnt;
1394
1395         return refcnt;
1396 }
1397
1398 static void refresh_for_paused_updating_cb(struct livebox *handle, int ret, void *data)
1399 {
1400         if (handle->paused_updating == 0) {
1401                 DbgPrint("Paused updates are cleared\n");
1402                 return;
1403         }
1404
1405         DbgPrint("Pending updates are found\n");
1406         lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
1407 }
1408
1409 static int lb_set_visibility(struct livebox *handler, enum livebox_visible_state state)
1410 {
1411         struct packet *packet;
1412         int need_to_add_job = 0;
1413         int ret;
1414
1415         if (handler->common->visible != LB_SHOW && state == (int)LB_SHOW) {
1416                 need_to_add_job = !!handler->paused_updating;
1417         } else if (handler->common->visible == (int)LB_SHOW && state != LB_SHOW) {
1418                 struct dlist *l;
1419                 struct livebox *item;
1420
1421                 dlist_foreach(handler->common->livebox_list, l, item) {
1422                         if (item->visible == (int)LB_SHOW) {
1423                                 DbgPrint("%s visibility is not changed\n", handler->common->pkgname);
1424                                 return LB_STATUS_SUCCESS;
1425                         }
1426                 }
1427         } else if (handler->common->visible == (int)LB_SHOW && state == (int)LB_SHOW && handler->paused_updating) {
1428                 if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1429                         ErrPrint("Unable to add a new job for refreshing box\n");
1430                 }
1431
1432                 return LB_STATUS_SUCCESS;
1433         } else {
1434                 /*!
1435                  * \brief
1436                  * No need to send this to the master
1437                  */
1438                 return LB_STATUS_SUCCESS;
1439         }
1440
1441         packet = packet_create_noack("change,visibility", "ssi", handler->common->pkgname, handler->common->id, (int)state);
1442         if (!packet) {
1443                 ErrPrint("Failed to create a packet\n");
1444                 return LB_STATUS_ERROR_FAULT;
1445         }
1446
1447         ret = master_rpc_request_only(handler, packet);
1448         if (ret == (int)LB_STATUS_SUCCESS) {
1449                 DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state);
1450                 handler->common->visible = state;
1451
1452                 if (need_to_add_job) {
1453                         if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1454                                 ErrPrint("Unable to add a new job for refreshing box\n");
1455                         }
1456                 }
1457         }
1458
1459         return ret;
1460 }
1461
1462 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)
1463 {
1464         char *lbid;
1465         struct livebox *handler;
1466         int w = 0;
1467         int h = 0;
1468
1469         if (!pkgname || !cluster || !category) {
1470                 ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
1471                                                                 pkgname, cluster, category);
1472                 return NULL;
1473         }
1474
1475         lbid = lb_pkgname(pkgname);
1476         if (!lbid) {
1477                 ErrPrint("Invalid package: %s\n", pkgname);
1478                 return NULL;
1479         }
1480
1481         if (livebox_service_is_enabled(lbid) == 0) {
1482                 DbgPrint("Livebox [%s](%s) is disabled package\n", lbid, pkgname);
1483                 free(lbid);
1484                 return NULL;
1485         }
1486
1487         if (type != LB_SIZE_TYPE_UNKNOWN) {
1488                 (void)livebox_service_get_size(type, &w, &h);
1489         }
1490
1491         handler = calloc(1, sizeof(*handler));
1492         if (!handler) {
1493                 ErrPrint("Error: %s\n", strerror(errno));
1494                 free(lbid);
1495                 return NULL;
1496         }
1497
1498         if (!cb) {
1499                 cb = default_create_cb;
1500         }
1501
1502         handler->common = find_sharable_common_handle(lbid, content, w, h, cluster, category);
1503         if (!handler->common) {
1504                 handler->common = lb_create_common_handle(handler, lbid, cluster, category);
1505                 free(lbid);
1506                 if (!handler->common) {
1507                         ErrPrint("Failed to find common handle\n");
1508                         free(handler);
1509                         return NULL;
1510                 }
1511
1512                 if (!content || !strlen(content)) {
1513                         char *pc;
1514                         /*!
1515                          * \note
1516                          * I know the content should not be modified. use it temporarly without "const"
1517                          */
1518                         pc = livebox_service_content(handler->common->pkgname);
1519                         lb_set_content(handler->common, pc);
1520                         free(pc);
1521                 } else {
1522                         lb_set_content(handler->common, content);
1523                 }
1524
1525                 lb_set_period(handler->common, period);
1526                 lb_set_size(handler->common, w, h);
1527                 lb_common_ref(handler->common, handler);
1528
1529                 if (create_real_instance(handler, cb, data) < 0) {
1530                         if (lb_common_unref(handler->common, handler) == 0) {
1531                                 /*!
1532                                  * Delete common
1533                                  */
1534                                 lb_destroy_common_handle(handler->common);
1535                                 handler->common = NULL;
1536                         }
1537                         free(handler);
1538                         return NULL;
1539                 }
1540         } else {
1541                 free(lbid);
1542
1543                 lb_common_ref(handler->common, handler);
1544
1545                 if (handler->common->request.created) {
1546                         /*!
1547                          * If a box is in creating, wait its result too
1548                          */
1549                         handler->cbs.created.cb = cb;
1550                         handler->cbs.created.data = data;
1551                 } else {
1552                         /*!
1553                          * or fire the fake created_event
1554                          */
1555                         if (create_fake_instance(handler, cb, data) < 0) {
1556                                 if (lb_common_unref(handler->common, handler) == 0) {
1557                                         /*!
1558                                          * Delete common
1559                                          */
1560                                         lb_destroy_common_handle(handler->common);
1561                                 }
1562                                 free(handler);
1563                                 return NULL;
1564                         }
1565                 }
1566         }
1567
1568         handler->visible = LB_SHOW;
1569         handler->state = CREATE;
1570         handler = lb_ref(handler);
1571
1572         if (handler->common->visible != LB_SHOW) {
1573                 lb_set_visibility(handler, LB_SHOW);
1574         }
1575
1576         return handler;
1577 }
1578
1579 EAPI double livebox_period(struct livebox *handler)
1580 {
1581         if (!handler || handler->state != CREATE) {
1582                 ErrPrint("Handler is not valid\n");
1583                 return 0.0f;
1584         }
1585
1586         if (!handler->common || handler->common->state != CREATE) {
1587                 ErrPrint("Invalid handle\n");
1588                 return 0.0f;
1589         }
1590
1591         if (!handler->common->id) {
1592                 ErrPrint("Hnalder is not valid\n");
1593                 return 0.0f;
1594         }
1595
1596         return handler->common->lb.period;
1597 }
1598
1599 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
1600 {
1601         struct packet *packet;
1602         int ret;
1603
1604         if (!handler || handler->state != CREATE) {
1605                 ErrPrint("Handler is not valid\n");
1606                 return LB_STATUS_ERROR_INVALID;
1607         }
1608
1609         if (!handler->common || handler->common->state != CREATE) {
1610                 ErrPrint("Invalid handle\n");
1611                 return LB_STATUS_ERROR_INVALID;
1612         }
1613
1614         if (!handler->common->id) {
1615                 ErrPrint("Handler is not valid\n");
1616                 return LB_STATUS_ERROR_INVALID;
1617         }
1618
1619         if (handler->common->request.period_changed) {
1620                 ErrPrint("Previous request for changing period is not finished\n");
1621                 return LB_STATUS_ERROR_BUSY;
1622         }
1623
1624         if (!handler->common->is_user) {
1625                 ErrPrint("CA Livebox is not able to change the period\n");
1626                 return LB_STATUS_ERROR_PERMISSION;
1627         }
1628
1629         if (handler->common->lb.period == period) {
1630                 DbgPrint("No changes\n");
1631                 return LB_STATUS_ERROR_ALREADY;
1632         }
1633
1634         packet = packet_create("set_period", "ssd", handler->common->pkgname, handler->common->id, period);
1635         if (!packet) {
1636                 ErrPrint("Failed to build a packet %s\n", handler->common->pkgname);
1637                 return LB_STATUS_ERROR_FAULT;
1638         }
1639
1640         if (!cb) {
1641                 cb = default_period_changed_cb;
1642         }
1643
1644         ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
1645         if (ret == (int)LB_STATUS_SUCCESS) {
1646                 handler->cbs.period_changed.cb = cb;
1647                 handler->cbs.period_changed.data = data;
1648                 handler->common->request.period_changed = 1;
1649         }
1650
1651         return ret;
1652 }
1653
1654 static void lb_update_visibility(struct livebox_common *old_common)
1655 {
1656         struct dlist *l;
1657         struct livebox *item;
1658
1659         item = NULL;
1660         dlist_foreach(old_common->livebox_list, l, item) {
1661                 if (item->visible == (int)LB_SHOW) {
1662                         break;
1663                 }
1664
1665                 item = NULL;
1666         }
1667
1668         if (!item) {
1669                 l = dlist_nth(old_common->livebox_list, 0);
1670                 item = dlist_data(l);
1671
1672                 if (item) {
1673                         lb_set_visibility(item, LB_HIDE_WITH_PAUSE);
1674                 } else {
1675                         ErrPrint("Unable to get the valid handle from common handler\n");
1676                 }
1677         } else {
1678                 lb_set_visibility(item, LB_SHOW);
1679         }
1680 }
1681
1682 /*!
1683  * \note
1684  * The second parameter should be the "return value",
1685  * But in this case, we will use it for "type of deleting instance".
1686  */
1687 static void job_del_cb(struct livebox *handle, int type, void *data)
1688 {
1689         struct cb_info *cbinfo = data;
1690         ret_cb_t cb;
1691
1692         if (handle->visible == (int)LB_SHOW) {
1693                 lb_update_visibility(handle->common);
1694         }
1695
1696         cb = cbinfo->cb;
1697         data = cbinfo->data;
1698         destroy_cb_info(cbinfo);
1699
1700         if (handle->common->state != CREATE) {
1701                 DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt);
1702                 if (cb) {
1703                         cb(handle, LB_STATUS_SUCCESS, data);
1704                 }
1705
1706                 return;
1707         }
1708
1709         if (handle->common->refcnt == 1) {
1710                 handle->common->delete_type = type;
1711                 handle->common->state = DELETE;
1712
1713                 if (!handle->common->id) {
1714                         /*!
1715                          * \note
1716                          * The id is not determined yet.
1717                          * It means a user didn't receive created event yet.
1718                          * Then just stop to delete procedure from here.
1719                          * Because the "created" event handle will release this.
1720                          * By the way, if the user adds any callback for getting return status of this,
1721                          * call it at here.
1722                          */
1723                         if (cb) {
1724                                 cb(handle, LB_STATUS_SUCCESS, data);
1725                         }
1726                 }
1727
1728                 DbgPrint("Send delete request\n");
1729                 lb_send_delete(handle, type, cb, data);
1730         } else {
1731                 if (cb) {
1732                         cb(handle, LB_STATUS_SUCCESS, data);
1733                 }
1734
1735                 DbgPrint("Before unref: %d\n", handle->common->refcnt);
1736                 lb_unref(handle, 1);
1737         }
1738 }
1739
1740 EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data)
1741 {
1742         struct cb_info *cbinfo;
1743
1744         if (!handler) {
1745                 ErrPrint("Handler is NIL\n");
1746                 return LB_STATUS_ERROR_INVALID;
1747         }
1748
1749         if (handler->state != CREATE) {
1750                 ErrPrint("Handler is already deleted\n");
1751                 return LB_STATUS_ERROR_INVALID;
1752         }
1753
1754         handler->state = DELETE;
1755
1756         cbinfo = create_cb_info(cb, data);
1757         if (!cbinfo) {
1758                 ErrPrint("Failed to create a cbinfo\n");
1759                 return LB_STATUS_ERROR_MEMORY;
1760         }
1761
1762         if (job_add(handler, job_del_cb, type, cbinfo) != LB_STATUS_SUCCESS) {
1763                 ErrPrint("Failed to add a new job\n");
1764                 destroy_cb_info(cbinfo);
1765                 return LB_STATUS_ERROR_FAULT;
1766         }
1767
1768         return LB_STATUS_SUCCESS;
1769 }
1770
1771 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
1772 {
1773         return livebox_del_NEW(handler, LB_DELETE_PERMANENTLY, cb, data);
1774 }
1775
1776 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
1777 {
1778         struct fault_info *info;
1779
1780         if (!cb) {
1781                 return LB_STATUS_ERROR_INVALID;
1782         }
1783
1784         info = malloc(sizeof(*info));
1785         if (!info) {
1786                 ErrPrint("Heap: %s\n", strerror(errno));
1787                 return LB_STATUS_ERROR_MEMORY;
1788         }
1789
1790         info->handler = cb;
1791         info->user_data = data;
1792         info->is_deleted = 0;
1793
1794         s_info.fault_list = dlist_append(s_info.fault_list, info);
1795         return LB_STATUS_SUCCESS;
1796 }
1797
1798 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
1799 {
1800         struct fault_info *info;
1801         struct dlist *l;
1802
1803         dlist_foreach(s_info.fault_list, l, info) {
1804                 if (info->handler == cb) {
1805                         void *data;
1806
1807                         data = info->user_data;
1808
1809                         if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1810                                 info->is_deleted = 1;
1811                         } else {
1812                                 s_info.fault_list = dlist_remove(s_info.fault_list, l);
1813                                 free(info);
1814                         }
1815
1816                         return data;
1817                 }
1818         }
1819
1820         return NULL;
1821 }
1822
1823 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
1824 {
1825         struct event_info *info;
1826
1827         if (!cb) {
1828                 ErrPrint("Invalid argument cb is nil\n");
1829                 return LB_STATUS_ERROR_INVALID;
1830         }
1831
1832         info = malloc(sizeof(*info));
1833         if (!info) {
1834                 ErrPrint("Heap: %s\n", strerror(errno));
1835                 return LB_STATUS_ERROR_MEMORY;
1836         }
1837
1838         info->handler = cb;
1839         info->user_data = data;
1840         info->is_deleted = 0;
1841
1842         s_info.event_list = dlist_append(s_info.event_list, info);
1843         return LB_STATUS_SUCCESS;
1844 }
1845
1846 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
1847 {
1848         struct event_info *info;
1849         struct dlist *l;
1850
1851         dlist_foreach(s_info.event_list, l, info) {
1852                 if (info->handler == cb) {
1853                         void *data;
1854
1855                         data = info->user_data;
1856
1857                         if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1858                                 info->is_deleted = 1;
1859                         } else {
1860                                 s_info.event_list = dlist_remove(s_info.event_list, l);
1861                                 free(info);
1862                         }
1863
1864                         return data;
1865                 }
1866         }
1867
1868         return NULL;
1869 }
1870
1871 EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data)
1872 {
1873         struct packet *packet;
1874         int ret;
1875
1876         if (!handler || handler->state != CREATE) {
1877                 ErrPrint("Handler is Invalid\n");
1878                 return LB_STATUS_ERROR_INVALID;
1879         }
1880
1881         if (!handler->common || handler->common->state != CREATE) {
1882                 ErrPrint("Handler is Invalid\n");
1883                 return LB_STATUS_ERROR_INVALID;
1884         }
1885
1886         if (!handler->common->id) {
1887                 ErrPrint("Handler is Invalid\n");
1888                 return LB_STATUS_ERROR_INVALID;
1889         }
1890
1891         if (handler->common->request.update_mode) {
1892                 ErrPrint("Previous update_mode cb is not finished yet\n");
1893                 return LB_STATUS_ERROR_BUSY;
1894         }
1895
1896         if (handler->common->is_active_update == active_update) {
1897                 return LB_STATUS_ERROR_ALREADY;
1898         }
1899
1900         if (!handler->common->is_user) {
1901                 return LB_STATUS_ERROR_PERMISSION;
1902         }
1903
1904         packet = packet_create("update_mode", "ssi", handler->common->pkgname, handler->common->id, active_update);
1905         if (!packet) {
1906                 return LB_STATUS_ERROR_FAULT;
1907         }
1908
1909         if (!cb) {
1910                 cb = default_update_mode_cb;
1911         }
1912
1913         ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL);
1914         if (ret == (int)LB_STATUS_SUCCESS) {
1915                 handler->cbs.update_mode.cb = cb;
1916                 handler->cbs.update_mode.data = data;
1917                 handler->common->request.update_mode = 1;
1918         }
1919
1920         return ret;
1921 }
1922
1923 EAPI int livebox_is_active_update(struct livebox *handler)
1924 {
1925         if (!handler || handler->state != CREATE) {
1926                 ErrPrint("Handler is Invalid\n");
1927                 return LB_STATUS_ERROR_INVALID;
1928         }
1929
1930         if (!handler->common || handler->common->state != CREATE) {
1931                 ErrPrint("Handler is Invalid\n");
1932                 return LB_STATUS_ERROR_INVALID;
1933         }
1934
1935         if (!handler->common->id) {
1936                 return LB_STATUS_ERROR_INVALID;
1937         }
1938
1939         return handler->common->is_active_update;
1940 }
1941
1942 static void resize_job_cb(struct livebox *handler, int ret, void *data)
1943 {
1944         struct cb_info *info = data;
1945
1946         if (info->cb) {
1947                 info->cb(handler, ret, info->data);
1948         }
1949
1950         free(info);
1951
1952         /*!
1953          * \note
1954          * Forcely update the box
1955          */
1956         lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
1957 }
1958
1959 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
1960 {
1961         struct livebox_common *common;
1962         int w;
1963         int h;
1964         int ret;
1965
1966         /*!
1967          * \TODO
1968          * If this handle is host instance or link instance,
1969          * Create a new instance or find another linkable instance.
1970          */
1971
1972         if (!handler || handler->state != CREATE) {
1973                 ErrPrint("Handler is not valid\n");
1974                 return LB_STATUS_ERROR_INVALID;
1975         }
1976
1977         if (!handler->common || handler->common->state != CREATE) {
1978                 ErrPrint("Invalid handle\n");
1979                 return LB_STATUS_ERROR_INVALID;
1980         }
1981
1982         if (!handler->common->id) {
1983                 ErrPrint("Handler is not valid\n");
1984                 return LB_STATUS_ERROR_INVALID;
1985         }
1986
1987         /*!
1988          * \note
1989          * resize operation should be separated by each handler.
1990          * If a handler is resizing, the other handler can request resize too.
1991          * So we should not use the common->request.size_changed flag.
1992          */
1993         if (handler->cbs.size_changed.cb) {
1994                 ErrPrint("Previous resize request is not finished yet\n");
1995                 return LB_STATUS_ERROR_BUSY;
1996         }
1997
1998         if (livebox_service_get_size(type, &w, &h) != 0) {
1999                 ErrPrint("Invalid size type\n");
2000                 return LB_STATUS_ERROR_INVALID;
2001         }
2002
2003         if (handler->common->lb.width == w && handler->common->lb.height == h) {
2004                 DbgPrint("No changes\n");
2005                 return LB_STATUS_ERROR_ALREADY;
2006         }
2007
2008         if (!handler->common->is_user) {
2009                 ErrPrint("CA Livebox is not able to be resized\n");
2010                 return LB_STATUS_ERROR_PERMISSION;
2011         }
2012
2013         if (handler->common->refcnt <= 1) {
2014                 struct packet *packet;
2015
2016                 /* Only 1 instance */
2017                 packet = packet_create("resize", "ssii", handler->common->pkgname, handler->common->id, w, h);
2018                 if (!packet) {
2019                         ErrPrint("Failed to build param\n");
2020                         return LB_STATUS_ERROR_FAULT;
2021                 }
2022
2023                 if (!cb) {
2024                         cb = default_lb_size_changed_cb;
2025                 }
2026
2027                 ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
2028                 if (ret == (int)LB_STATUS_SUCCESS) {
2029                         handler->cbs.size_changed.cb = cb;
2030                         handler->cbs.size_changed.data = data;
2031                         handler->common->request.size_changed = 1;
2032                 }
2033         } else {
2034                 common = find_sharable_common_handle(handler->common->pkgname, handler->common->content, w, h, handler->common->cluster, handler->common->category);
2035                 if (!common) {
2036                         struct livebox_common *old_common;
2037                         /*!
2038                          * \note
2039                          * If the common handler is in resizing,
2040                          * if user tries to resize a hander, then simply create new one even if the requested size is same with this.
2041
2042                         if (handler->common->request.size_changed) {
2043                         }
2044
2045                          */
2046
2047                         old_common = handler->common;
2048
2049                         common = lb_create_common_handle(handler, old_common->pkgname, old_common->cluster, old_common->category);
2050                         if (!common) {
2051                                 ErrPrint("Failed to create common handle\n");
2052                                 return LB_STATUS_ERROR_FAULT;
2053                         }
2054
2055                         lb_set_size(common, w, h);
2056                         lb_set_content(common, old_common->content);
2057                         lb_set_period(common, old_common->lb.period);
2058
2059                         /*!
2060                          * \note
2061                          * Disconnecting from old one.
2062                          */
2063                         if (lb_common_unref(old_common, handler) == 0) {
2064                                 /*!
2065                                  * \note
2066                                  * Impossible
2067                                  */
2068                                 ErrPrint("Common has no associated handler\n");
2069                         }
2070
2071                         lb_common_ref(common, handler);
2072
2073                         /*!
2074                          * Connect to a new one
2075                          */
2076                         handler->common = common;
2077
2078                         /*!
2079                          * \TODO
2080                          * Need to care, if it fails to create a common handle,
2081                          * the resize operation will be failed.
2082                          * in that case, we should reuse the old common handle
2083                          */
2084                         ret = create_real_instance(handler, cb, data);
2085                         if (ret < 0) {
2086                                 lb_common_unref(common, handler);
2087                                 lb_destroy_common_handle(common);
2088
2089                                 lb_common_ref(old_common, handler);
2090                                 handler->common = old_common;
2091                         } else {
2092                                 /*!
2093                                  * In this case, we should update visibility of old_common's liveboxes
2094                                  */
2095                                 if (handler->visible == (int)LB_SHOW) {
2096                                         lb_update_visibility(old_common);
2097                                 }
2098                         }
2099                 } else {
2100                         struct cb_info *cbinfo;
2101
2102                         cbinfo = create_cb_info(cb, data);
2103                         if (!cbinfo) {
2104                                 ErrPrint("Failed to create a cbinfo\n");
2105                                 ret = LB_STATUS_ERROR_MEMORY;
2106                         } else {
2107                                 ret = job_add(handler, resize_job_cb, LB_STATUS_SUCCESS, cbinfo);
2108                                 if (ret == (int)LB_STATUS_SUCCESS) {
2109                                         struct livebox_common *old_common;
2110
2111                                         old_common = handler->common;
2112
2113                                         if (lb_common_unref(handler->common, handler) == 0) {
2114                                                 ErrPrint("Old common has no associated handler\n");
2115                                         }
2116
2117                                         lb_common_ref(common, handler);
2118                                         handler->common = common;
2119
2120                                         if (handler->visible == (int)LB_SHOW) {
2121                                                 lb_update_visibility(old_common); /* To update visibility: Show --> Paused */
2122                                                 lb_update_visibility(common);   /* To update visibility: Paused --> Show */
2123                                         }
2124                                 } else {
2125                                         destroy_cb_info(cbinfo);
2126                                 }
2127                         }
2128                 }
2129         }
2130
2131         return ret;
2132 }
2133
2134 EAPI int livebox_click(struct livebox *handler, double x, double y)
2135 {
2136         struct packet *packet;
2137         double timestamp;
2138         int ret;
2139
2140         if (!handler || handler->state != CREATE) {
2141                 ErrPrint("Handler is invalid\n");
2142                 return LB_STATUS_ERROR_INVALID;
2143         }
2144
2145         if (!handler->common || handler->common->state != CREATE) {
2146                 ErrPrint("Handler is invalid\n");
2147                 return LB_STATUS_ERROR_INVALID;
2148         }
2149
2150         if (!handler->common->id) {
2151                 ErrPrint("Handler is not valid\n");
2152                 return LB_STATUS_ERROR_INVALID;
2153         }
2154
2155         if (handler->common->lb.auto_launch) {
2156                 if (s_info.launch.handler) {
2157                         ret = s_info.launch.handler(handler, handler->common->lb.auto_launch, s_info.launch.data);
2158                         if (ret < 0) {
2159                                 ErrPrint("launch handler app %s (%d)\n", handler->common->lb.auto_launch, ret);
2160                         }
2161                 }
2162         }
2163
2164         timestamp = util_timestamp();
2165         DbgPrint("CLICKED: %lf\n", timestamp);
2166
2167         packet = packet_create_noack("clicked", "sssddd", handler->common->pkgname, handler->common->id, "clicked", timestamp, x, y);
2168         if (!packet) {
2169                 ErrPrint("Failed to build param\n");
2170                 return LB_STATUS_ERROR_FAULT;
2171         }
2172
2173         ret = master_rpc_request_only(handler, packet);
2174
2175         if (!handler->common->lb.mouse_event && (handler->common->lb.type == _LB_TYPE_BUFFER || handler->common->lb.type == _LB_TYPE_SCRIPT)) {
2176                 int ret; /* Shadow variable */
2177                 ret = send_mouse_event(handler, "lb_mouse_down", x * handler->common->lb.width, y * handler->common->lb.height);
2178                 if (ret < 0) {
2179                         ErrPrint("Failed to send Down: %d\n", ret);
2180                 }
2181
2182                 ret = send_mouse_event(handler, "lb_mouse_move", x * handler->common->lb.width, y * handler->common->lb.height);
2183                 if (ret < 0) {
2184                         ErrPrint("Failed to send Move: %d\n", ret);
2185                 }
2186
2187                 ret = send_mouse_event(handler, "lb_mouse_up", x * handler->common->lb.width, y * handler->common->lb.height);
2188                 if (ret < 0) {
2189                         ErrPrint("Failed to send Up: %d\n", ret);
2190                 }
2191         }
2192
2193         return ret;
2194 }
2195
2196 EAPI int livebox_has_pd(struct livebox *handler)
2197 {
2198         if (!handler || handler->state != CREATE) {
2199                 ErrPrint("Handler is invalid\n");
2200                 return LB_STATUS_ERROR_INVALID;
2201         }
2202
2203         if (!handler->common || handler->common->state != CREATE) {
2204                 ErrPrint("Handler is invalid\n");
2205                 return LB_STATUS_ERROR_INVALID;
2206         }
2207
2208         if (!handler->common->id) {
2209                 ErrPrint("Handler is not valid\n");
2210                 return LB_STATUS_ERROR_INVALID;
2211         }
2212
2213         return !!handler->common->pd.fb;
2214 }
2215
2216 EAPI int livebox_pd_is_created(struct livebox *handler)
2217 {
2218         if (!handler || handler->state != CREATE) {
2219                 ErrPrint("Handler is invalid\n");
2220                 return LB_STATUS_ERROR_INVALID;
2221         }
2222
2223         if (!handler->common || handler->common->state != CREATE) {
2224                 ErrPrint("Handler is invalid\n");
2225                 return LB_STATUS_ERROR_INVALID;
2226         }
2227
2228         if (!handler->common->pd.fb || !handler->common->id) {
2229                 ErrPrint("Handler is not valid\n");
2230                 return LB_STATUS_ERROR_INVALID;
2231         }
2232
2233         return handler->common->is_pd_created;
2234 }
2235
2236 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
2237 {
2238         return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
2239 }
2240
2241 static void turn_off_pd_destroyed_flag_cb(struct livebox *handler, int ret, void *data)
2242 {
2243         if (handler->common->request.pd_destroyed) {
2244                 ret_cb_t cb;
2245                 void *data;
2246
2247                 DbgPrint("pd_destroyed request is canceled\n");
2248                 handler->common->request.pd_destroyed = 0;
2249                 cb = handler->cbs.pd_destroyed.cb;
2250                 data = handler->cbs.pd_destroyed.data;
2251                 handler->cbs.pd_destroyed.cb = NULL;
2252                 handler->cbs.pd_destroyed.data = NULL;
2253
2254                 if (cb) {
2255                         cb(handler, ret, data);
2256                 }
2257         }
2258 }
2259
2260 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
2261 {
2262         struct packet *packet;
2263         int ret;
2264
2265         if (!handler || handler->state != CREATE) {
2266                 ErrPrint("Handler is invalid\n");
2267                 return LB_STATUS_ERROR_INVALID;
2268         }
2269
2270         if (!handler->common || handler->common->state != CREATE) {
2271                 ErrPrint("Handler is invalid\n");
2272                 return LB_STATUS_ERROR_INVALID;
2273         }
2274
2275         if (!handler->common->pd.fb || !handler->common->id) {
2276                 ErrPrint("Handler is not valid\n");
2277                 return LB_STATUS_ERROR_INVALID;
2278         }
2279
2280         /*!
2281          * \note
2282          * Only one handler can have a PD
2283          */
2284         if (handler->common->is_pd_created) {
2285                 DbgPrint("PD is already created\n");
2286                 return LB_STATUS_SUCCESS;
2287         }
2288
2289         if (handler->common->request.pd_created) {
2290                 ErrPrint("Previous request is not completed yet\n");
2291                 return LB_STATUS_ERROR_BUSY;
2292         }
2293
2294         /*!
2295          * \note
2296          * Turn off the pd_destroyed request flag
2297          */
2298         if (handler->common->request.pd_destroyed) {
2299                 if (job_add(handler, turn_off_pd_destroyed_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2300                         ErrPrint("Failed to add pd_destroyed job\n");
2301                 }
2302         }
2303
2304         packet = packet_create("create_pd", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2305         if (!packet) {
2306                 ErrPrint("Failed to build param\n");
2307                 return LB_STATUS_ERROR_FAULT;
2308         }
2309
2310         if (!cb) {
2311                 cb = default_pd_created_cb;
2312         }
2313
2314         DbgPrint("PERF_DBOX\n");
2315         ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
2316         if (ret == (int)LB_STATUS_SUCCESS) {
2317                 handler->cbs.pd_created.cb = cb;
2318                 handler->cbs.pd_created.data = data;
2319                 handler->common->request.pd_created = 1;
2320         }
2321
2322         return ret;
2323 }
2324
2325 EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
2326 {
2327         struct packet *packet;
2328
2329         if (!handler || handler->state != CREATE) {
2330                 ErrPrint("Handler is invalid\n");
2331                 return LB_STATUS_ERROR_INVALID;
2332         }
2333
2334         if (!handler->common || handler->common->state != CREATE) {
2335                 ErrPrint("Handler is invalid\n");
2336                 return LB_STATUS_ERROR_INVALID;
2337         }
2338
2339         if (!handler->common->pd.fb || !handler->common->id) {
2340                 ErrPrint("Handler is not valid\n");
2341                 return LB_STATUS_ERROR_INVALID;
2342         }
2343
2344         if (!handler->common->is_pd_created) {
2345                 ErrPrint("PD is not created\n");
2346                 return LB_STATUS_ERROR_INVALID;
2347         }
2348
2349         packet = packet_create_noack("pd_move", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2350         if (!packet) {
2351                 ErrPrint("Failed to build param\n");
2352                 return LB_STATUS_ERROR_FAULT;
2353         }
2354
2355         return master_rpc_request_only(handler, packet);
2356 }
2357
2358 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
2359 {
2360         struct packet *packet;
2361         struct cb_info *cbinfo;
2362         int ret;
2363
2364         if (!pkgname) {
2365                 return LB_STATUS_ERROR_INVALID;
2366         }
2367
2368         packet = packet_create("activate_package", "s", pkgname);
2369         if (!packet) {
2370                 ErrPrint("Failed to build a param\n");
2371                 return LB_STATUS_ERROR_FAULT;
2372         }
2373
2374         cbinfo = create_cb_info(cb, data);
2375         if (!cbinfo) {
2376                 ErrPrint("Unable to create cbinfo\n");
2377                 packet_destroy(packet);
2378                 return LB_STATUS_ERROR_FAULT;
2379         }
2380
2381         ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo);
2382         if (ret < 0) {
2383                 destroy_cb_info(cbinfo);
2384         }
2385
2386         return ret;
2387 }
2388
2389 static void turn_off_pd_created_flag_cb(struct livebox *handler, int ret, void *data)
2390 {
2391         if (handler->common->request.pd_created) {
2392                 ret_cb_t cb;
2393                 void *data;
2394
2395                 DbgPrint("pd_created request is canceled\n");
2396                 handler->common->request.pd_created = 0;
2397                 cb = handler->cbs.pd_created.cb;
2398                 data = handler->cbs.pd_created.data;
2399                 handler->cbs.pd_created.cb = NULL;
2400                 handler->cbs.pd_created.data = NULL;
2401
2402                 if (cb) {
2403                         cb(handler, ret, data);
2404                 }
2405         }
2406 }
2407
2408 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
2409 {
2410         struct packet *packet;
2411         struct cb_info *cbinfo;
2412         int ret;
2413
2414         if (!handler || handler->state != CREATE) {
2415                 ErrPrint("Handler is invalid\n");
2416                 return LB_STATUS_ERROR_INVALID;
2417         }
2418
2419         if (!handler->common || handler->common->state != CREATE) {
2420                 ErrPrint("Handler is invalid\n");
2421                 return LB_STATUS_ERROR_INVALID;
2422         }
2423
2424         if (!handler->common->pd.fb || !handler->common->id) {
2425                 ErrPrint("Handler is not valid\n");
2426                 return LB_STATUS_ERROR_INVALID;
2427         }
2428
2429         /*!
2430          * \FIXME
2431          * Replace the callback check code.
2432          * Use the flag instead of callback.
2433          * the flag should be in the ADT "common"
2434          */
2435         if (!handler->common->is_pd_created && !handler->common->request.pd_created) {
2436                 ErrPrint("PD is not created\n");
2437                 return LB_STATUS_ERROR_INVALID;
2438         }
2439
2440         if (handler->common->request.pd_destroyed) {
2441                 ErrPrint("PD destroy request is already sent\n");
2442                 return LB_STATUS_ERROR_ALREADY;
2443         }
2444
2445         /*!
2446          * \note
2447          * Disable the pd_created request flag
2448          */
2449         if (handler->common->request.pd_created) {
2450                 if (job_add(handler, turn_off_pd_created_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2451                         ErrPrint("Failed to add a new job\n");
2452                 }
2453         }
2454
2455         DbgPrint("[%s]\n", handler->common->pkgname);
2456
2457         packet = packet_create("destroy_pd", "ss", handler->common->pkgname, handler->common->id);
2458         if (!packet) {
2459                 ErrPrint("Failed to build a param\n");
2460                 return LB_STATUS_ERROR_FAULT;
2461         }
2462
2463         if (!cb) {
2464                 cb = default_pd_destroyed_cb;
2465         }
2466
2467         cbinfo = create_cb_info(cb, data);
2468         if (!cbinfo) {
2469                 packet_destroy(packet);
2470                 return LB_STATUS_ERROR_FAULT;
2471         }
2472
2473         ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo);
2474         if (ret < 0) {
2475                 destroy_cb_info(cbinfo);
2476         } else {
2477                 handler->common->request.pd_destroyed = 1;
2478         }
2479
2480         return ret;
2481 }
2482
2483 EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data)
2484 {
2485         int w = 1;
2486         int h = 1;
2487         char cmd[32] = { '\0', };
2488         char *ptr = cmd;
2489         int ret;
2490
2491         if (!handler || handler->state != CREATE) {
2492                 ErrPrint("Handler is invalid\n");
2493                 return LB_STATUS_ERROR_INVALID;
2494         }
2495
2496         if (!handler->common || handler->common->state != CREATE) {
2497                 ErrPrint("Handler is invalid\n");
2498                 return LB_STATUS_ERROR_INVALID;
2499         }
2500
2501         if (!handler->common->id) {
2502                 ErrPrint("Handler is not valid\n");
2503                 return LB_STATUS_ERROR_INVALID;
2504         }
2505
2506         if (handler->common->request.access_event) {
2507                 ErrPrint("Previous access event is not yet done\n");
2508                 return LB_STATUS_ERROR_BUSY;
2509         }
2510
2511         if (type & ACCESS_EVENT_PD_MASK) {
2512                 if (!handler->common->is_pd_created) {
2513                         ErrPrint("PD is not created\n");
2514                         return LB_STATUS_ERROR_INVALID;
2515                 }
2516                 *ptr++ = 'p';
2517                 *ptr++ = 'd';
2518                 w = handler->common->pd.width;
2519                 h = handler->common->pd.height;
2520         } else if (type & ACCESS_EVENT_LB_MASK) {
2521                 *ptr++ = 'l';
2522                 *ptr++ = 'b';
2523                 w = handler->common->lb.width;
2524                 h = handler->common->lb.height;
2525         } else {
2526                 ErrPrint("Invalid event type\n");
2527                 return LB_STATUS_ERROR_INVALID;
2528         }
2529
2530         switch (type & ~ACCESS_EVENT_PD_MASK) {
2531         case ACCESS_EVENT_HIGHLIGHT:
2532                 strcpy(ptr, "_access_hl");
2533                 break;
2534         case ACCESS_EVENT_HIGHLIGHT_NEXT:
2535                 strcpy(ptr, "_access_hl_next");
2536                 break;
2537         case ACCESS_EVENT_HIGHLIGHT_PREV:
2538                 strcpy(ptr, "_access_hl_prev");
2539                 break;
2540         case ACCESS_EVENT_ACTIVATE:
2541                 strcpy(ptr, "_access_activate");
2542                 break;
2543         case ACCESS_EVENT_ACTION_DOWN:
2544                 strcpy(ptr, "_access_action_down");
2545                 break;
2546         case ACCESS_EVENT_ACTION_UP:
2547                 strcpy(ptr, "_access_action_up");
2548                 break;
2549         case ACCESS_EVENT_UNHIGHLIGHT:
2550                 strcpy(ptr, "_access_unhighlight");
2551                 break;
2552         case ACCESS_EVENT_SCROLL_DOWN:
2553                 strcpy(ptr, "_access_scroll_down");
2554                 break;
2555         case ACCESS_EVENT_SCROLL_MOVE:
2556                 strcpy(ptr, "_access_scroll_move");
2557                 break;
2558         case ACCESS_EVENT_SCROLL_UP:
2559                 strcpy(ptr, "_access_scroll_up");
2560                 break;
2561         default:
2562                 return LB_STATUS_ERROR_INVALID;
2563         }
2564
2565         if (!cb) {
2566                 cb = default_access_event_cb;
2567         }
2568
2569         ret = send_access_event(handler, cmd, x * w, y * h);
2570         if (ret == (int)LB_STATUS_SUCCESS) {
2571                 handler->cbs.access_event.cb = cb;
2572                 handler->cbs.access_event.data = data;
2573                 handler->common->request.access_event = 1;
2574         }
2575
2576         return ret;
2577 }
2578
2579 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
2580 {
2581         return livebox_mouse_event(handler, type, x, y);
2582 }
2583
2584 EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y)
2585 {
2586         int w = 1;
2587         int h = 1;
2588         char cmd[32] = { '\0', };
2589         char *ptr = cmd;
2590
2591         if (!handler || handler->state != CREATE) {
2592                 ErrPrint("Handler is invalid\n");
2593                 return LB_STATUS_ERROR_INVALID;
2594         }
2595
2596         if (!handler->common || handler->common->state != CREATE) {
2597                 ErrPrint("Handler is invalid\n");
2598                 return LB_STATUS_ERROR_INVALID;
2599         }
2600
2601         if (!handler->common->id) {
2602                 ErrPrint("Handler is not valid\n");
2603                 return LB_STATUS_ERROR_INVALID;
2604         }
2605
2606         if (!(type & CONTENT_EVENT_MOUSE_MASK)) {
2607                 ErrPrint("Invalid content event is used\n");
2608                 return LB_STATUS_ERROR_INVALID;
2609         }
2610
2611         if (type & CONTENT_EVENT_PD_MASK) {
2612                 int flag = 1;
2613
2614                 if (!handler->common->is_pd_created) {
2615                         ErrPrint("PD is not created\n");
2616                         return LB_STATUS_ERROR_INVALID;
2617                 }
2618
2619                 if (!handler->common->pd.fb) {
2620                         ErrPrint("Handler is not valid\n");
2621                         return LB_STATUS_ERROR_INVALID;
2622                 }
2623
2624                 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2625                         if (fabs(x - handler->common->pd.x) < conf_event_filter() && fabs(y - handler->common->pd.y) < conf_event_filter()) {
2626                                 return LB_STATUS_ERROR_BUSY;
2627                         }
2628                 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2629                         flag = 0;
2630                 }
2631
2632                 if (flag) {
2633                         w = handler->common->pd.width;
2634                         h = handler->common->pd.height;
2635                         handler->common->pd.x = x;
2636                         handler->common->pd.y = y;
2637                 }
2638                 *ptr++ = 'p';
2639                 *ptr++ = 'd';
2640         } else if (type & CONTENT_EVENT_LB_MASK) {
2641                 int flag = 1;
2642
2643                 if (!handler->common->lb.mouse_event) {
2644                         return LB_STATUS_ERROR_INVALID;
2645                 }
2646
2647                 if (!handler->common->lb.fb) {
2648                         ErrPrint("Handler is not valid\n");
2649                         return LB_STATUS_ERROR_INVALID;
2650                 }
2651
2652                 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2653                         if (fabs(x - handler->common->lb.x) < conf_event_filter() && fabs(y - handler->common->lb.y) < conf_event_filter()) {
2654                                 return LB_STATUS_ERROR_BUSY;
2655                         }
2656                 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2657                         flag = 0;
2658                 }
2659
2660                 if (flag) {
2661                         w = handler->common->lb.width;
2662                         h = handler->common->lb.height;
2663                         handler->common->lb.x = x;
2664                         handler->common->lb.y = y;
2665                 }
2666                 *ptr++ = 'l';
2667                 *ptr++ = 'b';
2668         } else {
2669                 ErrPrint("Invalid event type\n");
2670                 return LB_STATUS_ERROR_INVALID;
2671         }
2672
2673         /*!
2674          * Must be short than 29 bytes.
2675          */
2676         switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2677         case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
2678                 strcpy(ptr, "_mouse_enter");
2679                 break;
2680         case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
2681                 strcpy(ptr, "_mouse_leave");
2682                 break;
2683         case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
2684                 strcpy(ptr, "_mouse_up");
2685                 break;
2686         case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
2687                 strcpy(ptr, "_mouse_down");
2688                 break;
2689         case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
2690                 strcpy(ptr, "_mouse_move");
2691                 break;
2692         case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
2693                 strcpy(ptr, "_mouse_set");
2694                 break;
2695         case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
2696                 strcpy(ptr, "_mouse_unset");
2697                 break;
2698         default:
2699                 ErrPrint("Invalid event type\n");
2700                 return LB_STATUS_ERROR_INVALID;
2701         }
2702
2703         return send_mouse_event(handler, cmd, x * w, y * h);
2704 }
2705
2706 EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data)
2707 {
2708         char cmd[32] = { '\0', };
2709         char *ptr = cmd;
2710         int ret;
2711
2712         if (!handler || handler->state != CREATE) {
2713                 ErrPrint("Handler is invalid\n");
2714                 return LB_STATUS_ERROR_INVALID;
2715         }
2716
2717         if (!handler->common || handler->common->state != CREATE) {
2718                 ErrPrint("Handler is invalid\n");
2719                 return LB_STATUS_ERROR_INVALID;
2720         }
2721
2722         if (!handler->common->id) {
2723                 ErrPrint("Handler is not valid\n");
2724                 return LB_STATUS_ERROR_INVALID;
2725         }
2726
2727         if (!(type & CONTENT_EVENT_KEY_MASK)) {
2728                 ErrPrint("Invalid key event is used\n");
2729                 return LB_STATUS_ERROR_INVALID;
2730         }
2731
2732         if (handler->common->request.key_event) {
2733                 ErrPrint("Previous key event is not completed yet\n");
2734                 return LB_STATUS_ERROR_BUSY;
2735         }
2736
2737         if (type & CONTENT_EVENT_PD_MASK) {
2738                 if (!handler->common->is_pd_created) {
2739                         ErrPrint("PD is not created\n");
2740                         return LB_STATUS_ERROR_INVALID;
2741                 }
2742
2743                 if (!handler->common->pd.fb) {
2744                         ErrPrint("Handler is not valid\n");
2745                         return LB_STATUS_ERROR_INVALID;
2746                 }
2747
2748                 if (type & CONTENT_EVENT_KEY_DOWN) {
2749                         /*!
2750                          * \TODO
2751                          * filtering the reproduced events if it is too fast
2752                          */
2753                 } else if (type & CONTENT_EVENT_KEY_SET) {
2754                         /*!
2755                          * \TODO
2756                          * What can I do for this case?
2757                          */
2758                 }
2759
2760                 *ptr++ = 'p';
2761                 *ptr++ = 'd';
2762         } else if (type & CONTENT_EVENT_LB_MASK) {
2763                 if (!handler->common->lb.mouse_event) {
2764                         return LB_STATUS_ERROR_INVALID;
2765                 }
2766
2767                 if (!handler->common->lb.fb) {
2768                         ErrPrint("Handler is not valid\n");
2769                         return LB_STATUS_ERROR_INVALID;
2770                 }
2771
2772                 if (type & CONTENT_EVENT_KEY_DOWN) {
2773                         /*!
2774                          * \TODO
2775                          * filtering the reproduced events if it is too fast
2776                          */
2777                 } else if (type & CONTENT_EVENT_KEY_SET) {
2778                         /*!
2779                          * What can I do for this case?
2780                          */
2781                 }
2782
2783                 *ptr++ = 'l';
2784                 *ptr++ = 'b';
2785         } else {
2786                 ErrPrint("Invalid event type\n");
2787                 return LB_STATUS_ERROR_INVALID;
2788         }
2789
2790         /*!
2791          * Must be short than 29 bytes.
2792          */
2793         switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2794         case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK:
2795                 strcpy(ptr, "_key_focus_in");
2796                 break;
2797         case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK:
2798                 strcpy(ptr, "_key_focus_out");
2799                 break;
2800         case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
2801                 strcpy(ptr, "_key_up");
2802                 break;
2803         case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
2804                 strcpy(ptr, "_key_down");
2805                 break;
2806         case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK:
2807                 strcpy(ptr, "_key_set");
2808                 break;
2809         case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK:
2810                 strcpy(ptr, "_key_unset");
2811                 break;
2812         default:
2813                 ErrPrint("Invalid event type\n");
2814                 return LB_STATUS_ERROR_INVALID;
2815         }
2816
2817         if (!cb) {
2818                 cb = default_key_event_cb;
2819         }
2820
2821         ret = send_key_event(handler, cmd, keycode);
2822         if (ret == (int)LB_STATUS_SUCCESS) {
2823                 handler->cbs.key_event.cb = cb;
2824                 handler->cbs.key_event.data = data;
2825                 handler->common->request.key_event = 1;
2826         }
2827
2828         return ret;
2829 }
2830
2831 EAPI const char *livebox_filename(struct livebox *handler)
2832 {
2833         if (!handler || handler->state != CREATE) {
2834                 ErrPrint("Handler is invalid\n");
2835                 return NULL;
2836         }
2837
2838         if (!handler->common || handler->common->state != CREATE) {
2839                 ErrPrint("Handler is invalid\n");
2840                 return NULL;
2841         }
2842
2843         if (!handler->common->id) {
2844                 ErrPrint("Handler is not valid\n");
2845                 return NULL;
2846         }
2847
2848         if (handler->common->filename) {
2849                 return handler->common->filename;
2850         }
2851
2852         /* Oooops */
2853         return util_uri_to_path(handler->common->id);
2854 }
2855
2856 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
2857 {
2858         int _w;
2859         int _h;
2860
2861         if (!handler || handler->state != CREATE) {
2862                 ErrPrint("Handler is invalid\n");
2863                 return LB_STATUS_ERROR_INVALID;
2864         }
2865
2866         if (!handler->common || handler->common->state != CREATE) {
2867                 ErrPrint("Handler is invalid\n");
2868                 return LB_STATUS_ERROR_INVALID;
2869         }
2870
2871         if (!handler->common->id) {
2872                 ErrPrint("Handler is not valid\n");
2873                 return LB_STATUS_ERROR_INVALID;
2874         }
2875
2876         if (!w) {
2877                 w = &_w;
2878         }
2879         if (!h) {
2880                 h = &_h;
2881         }
2882
2883         if (!handler->common->is_pd_created) {
2884                 *w = handler->common->pd.default_width;
2885                 *h = handler->common->pd.default_height;
2886         } else {
2887                 *w = handler->common->pd.width;
2888                 *h = handler->common->pd.height;
2889         }
2890
2891         return LB_STATUS_SUCCESS;
2892 }
2893
2894 EAPI int livebox_size(struct livebox *handler)
2895 {
2896         int w;
2897         int h;
2898
2899         if (!handler || handler->state != CREATE) {
2900                 ErrPrint("Handler is invalid\n");
2901                 return LB_STATUS_ERROR_INVALID;
2902         }
2903
2904         if (!handler->common || handler->common->state != CREATE) {
2905                 ErrPrint("Handler is invalid\n");
2906                 return LB_STATUS_ERROR_INVALID;
2907         }
2908
2909         if (!handler->common->id) {
2910                 ErrPrint("Handler is not valid\n");
2911                 return LB_STATUS_ERROR_INVALID;
2912         }
2913
2914         w = handler->common->lb.width;
2915         h = handler->common->lb.height;
2916
2917         switch (handler->common->lb.type) {
2918         case _LB_TYPE_BUFFER:
2919         case _LB_TYPE_SCRIPT:
2920                 if (!fb_is_created(handler->common->lb.fb)) {
2921                         w = 0;
2922                         h = 0;
2923                 }
2924                 break;
2925         default:
2926                 break;
2927         }
2928
2929         return livebox_service_size_type(w, h);
2930 }
2931
2932 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
2933 {
2934         struct packet *packet;
2935         int ret;
2936
2937         if (!handler) {
2938                 ErrPrint("Handler is NIL\n");
2939                 return LB_STATUS_ERROR_INVALID;
2940         }
2941
2942         if (!cluster || !category || handler->state != CREATE) {
2943                 ErrPrint("Invalid argument\n");
2944                 return LB_STATUS_ERROR_INVALID;
2945         }
2946
2947         if (!handler->common || handler->common->state != CREATE) {
2948                 ErrPrint("Invalid argument\n");
2949                 return LB_STATUS_ERROR_INVALID;
2950         }
2951
2952         if (!handler->common->id) {
2953                 ErrPrint("Invalid argument\n");
2954                 return LB_STATUS_ERROR_INVALID;
2955         }
2956
2957         if (handler->common->request.group_changed) {
2958                 ErrPrint("Previous group changing request is not finished yet\n");
2959                 return LB_STATUS_ERROR_BUSY;
2960         }
2961
2962         if (!handler->common->is_user) {
2963                 ErrPrint("CA Livebox is not able to change the group\n");
2964                 return LB_STATUS_ERROR_PERMISSION;
2965         }
2966
2967         if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) {
2968                 DbgPrint("No changes\n");
2969                 return LB_STATUS_ERROR_ALREADY;
2970         }
2971
2972         packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category);
2973         if (!packet) {
2974                 ErrPrint("Failed to build a param\n");
2975                 return LB_STATUS_ERROR_FAULT;
2976         }
2977
2978         if (!cb) {
2979                 cb = default_group_changed_cb;
2980         }
2981
2982         ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
2983         if (ret == (int)LB_STATUS_SUCCESS) {
2984                 handler->cbs.group_changed.cb = cb;
2985                 handler->cbs.group_changed.data = data; 
2986                 handler->common->request.group_changed = 1;
2987         }
2988
2989         return ret;
2990 }
2991
2992 EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category)
2993 {
2994         if (!handler) {
2995                 ErrPrint("Handler is NIL\n");
2996                 return LB_STATUS_ERROR_INVALID;
2997         }
2998
2999         if (!cluster || !category || handler->state != CREATE) {
3000                 ErrPrint("Invalid argument\n");
3001                 return LB_STATUS_ERROR_INVALID;
3002         }
3003
3004         if (!handler->common || handler->common->state != CREATE) {
3005                 ErrPrint("Invalid argument\n");
3006                 return LB_STATUS_ERROR_INVALID;
3007         }
3008
3009         if (!handler->common->id) {
3010                 ErrPrint("Invalid argument\n");
3011                 return LB_STATUS_ERROR_INVALID;
3012         }
3013
3014         *cluster = handler->common->cluster;
3015         *category = handler->common->category;
3016         return LB_STATUS_SUCCESS;
3017 }
3018
3019 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
3020 {
3021         register int i;
3022         register int j;
3023
3024         if (!handler || !size_list) {
3025                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
3026                 return LB_STATUS_ERROR_INVALID;
3027         }
3028
3029         if (!cnt || handler->state != CREATE) {
3030                 ErrPrint("Handler is not valid\n");
3031                 return LB_STATUS_ERROR_INVALID;
3032         }
3033
3034         if (!handler->common || handler->common->state != CREATE) {
3035                 ErrPrint("Handler is not valid\n");
3036                 return LB_STATUS_ERROR_INVALID;
3037         }
3038
3039         if (!handler->common->id) {
3040                 ErrPrint("Handler is not valid\n");
3041                 return LB_STATUS_ERROR_INVALID;
3042         }
3043
3044         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
3045                 if (handler->common->lb.size_list & (0x01 << i)) {
3046                         if (j == *cnt) {
3047                                 break;
3048                         }
3049
3050                         size_list[j++] = (0x01 << i);
3051                 }
3052         }
3053
3054         *cnt = j;
3055         return LB_STATUS_SUCCESS;
3056 }
3057
3058 EAPI const char *livebox_pkgname(struct livebox *handler)
3059 {
3060         if (!handler) {
3061                 ErrPrint("Handler is NIL\n");
3062                 return NULL;
3063         }
3064
3065         if (handler->state != CREATE) {
3066                 ErrPrint("Handler is not valid\n");
3067                 return NULL;
3068         }
3069
3070         if (!handler->common || handler->common->state != CREATE) {
3071                 ErrPrint("Handler is not valid\n");
3072                 return NULL;
3073         }
3074
3075         return handler->common->pkgname;
3076 }
3077
3078 EAPI double livebox_priority(struct livebox *handler)
3079 {
3080         if (!handler || handler->state != CREATE) {
3081                 ErrPrint("Handler is invalid\n");
3082                 return -1.0f;
3083         }
3084
3085         if (!handler->common || handler->common->state != CREATE) {
3086                 ErrPrint("Handler is invalid\n");
3087                 return -1.0f;
3088         }
3089
3090         if (!handler->common->id) {
3091                 ErrPrint("Handler is not valid (%p)\n", handler);
3092                 return -1.0f;
3093         }
3094
3095         return handler->common->lb.priority;
3096 }
3097
3098 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
3099 {
3100         struct packet *packet;
3101         struct cb_info *cbinfo;
3102         int ret;
3103
3104         packet = packet_create("delete_cluster", "s", cluster);
3105         if (!packet) {
3106                 ErrPrint("Failed to build a param\n");
3107                 return LB_STATUS_ERROR_FAULT;
3108         }
3109
3110         cbinfo = create_cb_info(cb, data);
3111         if (!cbinfo) {
3112                 packet_destroy(packet);
3113                 return LB_STATUS_ERROR_FAULT;
3114         }
3115
3116         ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
3117         if (ret < 0) {
3118                 destroy_cb_info(cbinfo);
3119         }
3120
3121         return ret;
3122 }
3123
3124 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
3125 {
3126         struct packet *packet;
3127         struct cb_info *cbinfo;
3128         int ret;
3129
3130         packet = packet_create("delete_category", "ss", cluster, category);
3131         if (!packet) {
3132                 ErrPrint("Failed to build a param\n");
3133                 return LB_STATUS_ERROR_FAULT;
3134         }
3135
3136         cbinfo = create_cb_info(cb, data);
3137         if (!cbinfo) {
3138                 packet_destroy(packet);
3139                 return LB_STATUS_ERROR_FAULT;
3140         }
3141
3142         ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
3143         if (ret < 0) {
3144                 destroy_cb_info(cbinfo);
3145         }
3146
3147         return ret;
3148 }
3149
3150 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
3151 {
3152         if (!handler || handler->state != CREATE) {
3153                 ErrPrint("Handler is invalid\n");
3154                 return LB_TYPE_INVALID;
3155         }
3156
3157         if (!handler->common || handler->common->state != CREATE) {
3158                 ErrPrint("Handler is invalid\n");
3159                 return LB_TYPE_INVALID;
3160         }
3161
3162         if (!handler->common->id) {
3163                 ErrPrint("Handler is not valid\n");
3164                 return LB_TYPE_INVALID;
3165         }
3166
3167         switch (handler->common->lb.type) {
3168         case _LB_TYPE_FILE:
3169                 return LB_TYPE_IMAGE;
3170         case _LB_TYPE_BUFFER:
3171         case _LB_TYPE_SCRIPT:
3172                 {
3173                         const char *id;
3174                         id = fb_id(handler->common->lb.fb);
3175                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3176                                 return LB_TYPE_PIXMAP;
3177                         }
3178                 }
3179                 return LB_TYPE_BUFFER;
3180         case _LB_TYPE_TEXT:
3181                 return LB_TYPE_TEXT;
3182         default:
3183                 break;
3184         }
3185
3186         return LB_TYPE_INVALID;
3187 }
3188
3189 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
3190 {
3191         if (!handler || handler->state != CREATE) {
3192                 ErrPrint("Handler is invalid\n");
3193                 return PD_TYPE_INVALID;
3194         }
3195
3196         if (!handler->common || handler->common->state != CREATE) {
3197                 ErrPrint("Handler is invalid\n");
3198                 return PD_TYPE_INVALID;
3199         }
3200
3201         if (!handler->common->id) {
3202                 ErrPrint("Handler is not valid\n");
3203                 return PD_TYPE_INVALID;
3204         }
3205
3206         switch (handler->common->pd.type) {
3207         case _PD_TYPE_TEXT:
3208                 return PD_TYPE_TEXT;
3209         case _PD_TYPE_BUFFER:
3210         case _PD_TYPE_SCRIPT:
3211                 {
3212                         const char *id;
3213                         id = fb_id(handler->common->pd.fb);
3214                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3215                                 return PD_TYPE_PIXMAP;
3216                         }
3217                 }
3218                 return PD_TYPE_BUFFER;
3219         default:
3220                 break;
3221         }
3222
3223         return PD_TYPE_INVALID;
3224 }
3225
3226 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3227 {
3228         if (!handler) {
3229                 ErrPrint("Handler is NIL\n");
3230                 return LB_STATUS_ERROR_INVALID;
3231         }
3232
3233         if (handler->state != CREATE) {
3234                 ErrPrint("Handler is not valid\n");
3235                 return LB_STATUS_ERROR_INVALID;
3236         }
3237
3238         memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops));
3239         return LB_STATUS_SUCCESS;
3240 }
3241
3242 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3243 {
3244         if (!handler) {
3245                 ErrPrint("Handler is NIL\n");
3246                 return LB_STATUS_ERROR_INVALID;
3247         }
3248
3249         if (handler->state != CREATE) {
3250                 ErrPrint("Handler is not valid\n");
3251                 return LB_STATUS_ERROR_INVALID;
3252         }
3253
3254         memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops));
3255         return LB_STATUS_SUCCESS;
3256 }
3257
3258 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3259 {
3260         if (!handler || handler->state != CREATE) {
3261                 ErrPrint("Handler is invalid\n");
3262                 return LB_STATUS_ERROR_INVALID;
3263         }
3264
3265         if (!handler->common || handler->common->state != CREATE) {
3266                 ErrPrint("Handler is invalid\n");
3267                 return LB_STATUS_ERROR_INVALID;
3268         }
3269
3270         if (!handler->common->id) {
3271                 ErrPrint("Invalid handle\n");
3272                 return LB_STATUS_ERROR_INVALID;
3273         }
3274
3275         if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3276                 ErrPrint("Handler is not valid type\n");
3277                 return LB_STATUS_ERROR_INVALID;
3278         }
3279
3280         return lb_acquire_lb_pixmap(handler, cb, data);
3281 }
3282
3283 /*!
3284  * \note
3285  * Do not check the state of handler and common-handler.
3286  * If this function is used in the deleted callback,
3287  * the handler and common-handler's state would be DELETE
3288  * if this function check the state of handles,
3289  * user cannot release the pixmap.
3290  */
3291 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
3292 {
3293         struct packet *packet;
3294         const char *pkgname;
3295         const char *id;
3296
3297         if (pixmap == 0 /* || handler->state != CREATE */ ) {
3298                 ErrPrint("Handler is invalid [%d]\n", pixmap);
3299                 return LB_STATUS_ERROR_INVALID;
3300         }
3301
3302         if (!handler) {
3303                 /*!
3304                  * \note
3305                  * Even though the handler is NULL, we should send the release request to the master.
3306                  * Because the pixmap resource can be released after the handler is destroyed.
3307                  * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3308                  * In some cases, the pixmap can be released after the handler is deleted.
3309                  *
3310                  * Its implementation is up to the viewer app.
3311                  * But we cannot force it to use only with valid handler.
3312                  */
3313                 DbgPrint("Using NULL handler\n");
3314                 pkgname = NULL;
3315                 id = NULL;
3316                 /*!
3317                  * \note
3318                  * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3319                  */
3320         } else {
3321                 if (!handler->common /* || handler->common->state != CREATE */) {
3322                         ErrPrint("Handler is invalid\n");
3323                         return LB_STATUS_ERROR_INVALID;
3324                 }
3325
3326                 if (!handler->common->id) {
3327                         ErrPrint("Invalid handle\n");
3328                         return LB_STATUS_ERROR_INVALID;
3329                 }
3330
3331                 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3332                         ErrPrint("Handler is not valid type\n");
3333                         return LB_STATUS_ERROR_INVALID;
3334                 }
3335
3336                 pkgname = handler->common->pkgname;
3337                 id = handler->common->id;
3338         }
3339
3340         packet = packet_create_noack("lb_release_pixmap", "ssi", pkgname, id, pixmap);
3341         if (!packet) {
3342                 ErrPrint("Failed to build a param\n");
3343                 return LB_STATUS_ERROR_INVALID;
3344         }
3345
3346         return master_rpc_request_only(handler, packet);
3347 }
3348
3349 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3350 {
3351         if (!handler || handler->state != CREATE) {
3352                 ErrPrint("Handler is invalid\n");
3353                 return LB_STATUS_ERROR_INVALID;
3354         }
3355
3356         if (!handler->common || handler->common->state != CREATE) {
3357                 ErrPrint("Handler is invalid\n");
3358                 return LB_STATUS_ERROR_INVALID;
3359         }
3360
3361         if (!handler->common->id) {
3362                 ErrPrint("Invalid handle\n");
3363                 return LB_STATUS_ERROR_INVALID;
3364         }
3365
3366         if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3367                 ErrPrint("Handler is not valid type\n");
3368                 return LB_STATUS_ERROR_INVALID;
3369         }
3370
3371         return lb_acquire_pd_pixmap(handler, cb, data);
3372 }
3373
3374 EAPI int livebox_pd_pixmap(const struct livebox *handler)
3375 {
3376         const char *id;
3377         int pixmap = 0;
3378
3379         if (!handler || handler->state != CREATE) {
3380                 ErrPrint("Handler is invalid\n");
3381                 return 0;
3382         }
3383
3384         if (!handler->common || handler->common->state != CREATE) {
3385                 ErrPrint("Handler is invalid\n");
3386                 return 0;
3387         }
3388
3389         if (!handler->common->id) {
3390                 ErrPrint("Invalid handler\n");
3391                 return 0;
3392         }
3393
3394         if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3395                 ErrPrint("Invalid handler\n");
3396                 return 0;
3397         }
3398
3399         id = fb_id(handler->common->pd.fb);
3400         if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3401                 ErrPrint("PIXMAP Id is not valid\n");
3402                 return 0;
3403         }
3404
3405         return pixmap;
3406 }
3407
3408 EAPI int livebox_lb_pixmap(const struct livebox *handler)
3409 {
3410         const char *id;
3411         int pixmap = 0;
3412
3413         if (!handler || handler->state != CREATE) {
3414                 ErrPrint("Handler is invalid\n");
3415                 return 0;
3416         }
3417
3418         if (!handler->common || handler->common->state != CREATE) {
3419                 ErrPrint("Handler is invalid\n");
3420                 return 0;
3421         }
3422
3423         if (!handler->common->id) {
3424                 ErrPrint("Invalid handler\n");
3425                 return 0;
3426         }
3427
3428         if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3429                 ErrPrint("Invalid handler\n");
3430                 return 0;
3431         }
3432
3433         id = fb_id(handler->common->lb.fb);
3434         if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3435                 ErrPrint("PIXMAP Id is not valid\n");
3436                 return 0;
3437         }
3438
3439         return pixmap;
3440 }
3441
3442 /*!
3443  * \note
3444  * Do not check the state of handler and common-handler.
3445  * If this function is used in the deleted callback,
3446  * the handler and common-handler's state would be DELETE
3447  * if this function check the state of handles,
3448  * user cannot release the pixmap.
3449  */
3450 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
3451 {
3452         struct packet *packet;
3453         const char *pkgname;
3454         const char *id;
3455
3456         if (pixmap == 0 /* || handler->state != CREATE */) {
3457                 ErrPrint("Pixmap is invalid [%d]\n", pixmap);
3458                 return LB_STATUS_ERROR_INVALID;
3459         }
3460
3461         if (!handler) {
3462                 /*!
3463                  * \note
3464                  * Even though the handler is NULL, we should send the release request to the master.
3465                  * Because the pixmap resource can be released after the handler is destroyed.
3466                  * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3467                  * In some cases, the pixmap can be released after the handler is deleted.
3468                  *
3469                  * Its implementation is up to the viewer app.
3470                  * But we cannot force it to use only with valid handler.
3471                  */
3472                 DbgPrint("Using NULL handler\n");
3473                 pkgname = NULL;
3474                 id = NULL;
3475                 /*!
3476                  * \note
3477                  * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3478                  */
3479         } else {
3480                 if (!handler->common /* || handler-common->state != CREATE */) {
3481                         ErrPrint("Handler is invalid\n");
3482                         return LB_STATUS_ERROR_INVALID;
3483                 }
3484
3485                 if (!handler->common->id) {
3486                         ErrPrint("Invalid handle\n");
3487                         return LB_STATUS_ERROR_INVALID;
3488                 }
3489
3490                 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3491                         ErrPrint("Handler is not valid type\n");
3492                         return LB_STATUS_ERROR_INVALID;
3493                 }
3494
3495                 pkgname = handler->common->pkgname;
3496                 id = handler->common->id;
3497         }
3498
3499         packet = packet_create_noack("pd_release_pixmap", "ssi", pkgname, id, pixmap);
3500         if (!packet) {
3501                 ErrPrint("Failed to build a param\n");
3502                 return LB_STATUS_ERROR_FAULT;
3503         }
3504
3505         return master_rpc_request_only(handler, packet);
3506 }
3507
3508 EAPI void *livebox_acquire_fb(struct livebox *handler)
3509 {
3510         if (!handler || handler->state != CREATE) {
3511                 ErrPrint("Handler is invalid\n");
3512                 return NULL;
3513         }
3514
3515         if (!handler->common || handler->common->state != CREATE) {
3516                 ErrPrint("Handler is invalid\n");
3517                 return NULL;
3518         }
3519
3520         if (!handler->common->id) {
3521                 ErrPrint("Invalid handle\n");
3522                 return NULL;
3523         }
3524
3525         if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3526                 ErrPrint("Handler is not valid type\n");
3527                 return NULL;
3528         }
3529
3530         return fb_acquire_buffer(handler->common->lb.fb);
3531 }
3532
3533 EAPI int livebox_release_fb(void *buffer)
3534 {
3535         return fb_release_buffer(buffer);
3536 }
3537
3538 EAPI int livebox_fb_refcnt(void *buffer)
3539 {
3540         return fb_refcnt(buffer);
3541 }
3542
3543 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
3544 {
3545         if (!handler || handler->state != CREATE) {
3546                 ErrPrint("Handler is invalid\n");
3547                 return NULL;
3548         }
3549
3550         if (!handler->common || handler->common->state != CREATE) {
3551                 ErrPrint("Handler is invalid\n");
3552                 return NULL;
3553         }
3554
3555         if (!handler->common->id) {
3556                 ErrPrint("Invalid handler\n");
3557                 return NULL;
3558         }
3559
3560         if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3561                 ErrPrint("Handler is not valid type\n");
3562                 return NULL;
3563         }
3564
3565         return fb_acquire_buffer(handler->common->pd.fb);
3566 }
3567
3568 EAPI int livebox_release_pdfb(void *buffer)
3569 {
3570         return fb_release_buffer(buffer);
3571 }
3572
3573 EAPI int livebox_pdfb_refcnt(void *buffer)
3574 {
3575         return fb_refcnt(buffer);
3576 }
3577
3578 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
3579 {
3580         if (!handler || handler->state != CREATE) {
3581                 ErrPrint("Handler is invalid\n");
3582                 return LB_STATUS_ERROR_INVALID;
3583         }
3584
3585         if (!handler->common || handler->common->state != CREATE) {
3586                 ErrPrint("Handler is invalid\n");
3587                 return LB_STATUS_ERROR_INVALID;
3588         }
3589
3590         if (!handler->common->id) {
3591                 ErrPrint("Invalid handler\n");
3592                 return LB_STATUS_ERROR_INVALID;
3593         }
3594
3595         return fb_size(handler->common->pd.fb);
3596 }
3597
3598 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
3599 {
3600         if (!handler || handler->state != CREATE) {
3601                 ErrPrint("Handler is invalid\n");
3602                 return LB_STATUS_ERROR_INVALID;
3603         }
3604
3605         if (!handler->common || handler->common->state != CREATE) {
3606                 ErrPrint("Handler is invalid\n");
3607                 return LB_STATUS_ERROR_INVALID;
3608         }
3609
3610         if (!handler->common->id) {
3611                 ErrPrint("Invalid handler\n");
3612                 return LB_STATUS_ERROR_INVALID;
3613         }
3614
3615         return fb_size(handler->common->lb.fb);
3616 }
3617
3618 EAPI int livebox_is_user(struct livebox *handler)
3619 {
3620         if (!handler || handler->state != CREATE) {
3621                 ErrPrint("Handler is invalid\n");
3622                 return LB_STATUS_ERROR_INVALID;
3623         }
3624
3625         if (!handler->common || handler->common->state != CREATE) {
3626                 ErrPrint("Handler is invalid\n");
3627                 return LB_STATUS_ERROR_INVALID;
3628         }
3629
3630         if (!handler->common->id) {
3631                 ErrPrint("Invalid handler\n");
3632                 return LB_STATUS_ERROR_INVALID;
3633         }
3634
3635         return handler->common->is_user;
3636 }
3637
3638 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
3639 {
3640         struct packet *packet;
3641         int ret;
3642
3643         if (!handler || handler->state != CREATE) {
3644                 ErrPrint("Handler is invalid\n");
3645                 return LB_STATUS_ERROR_INVALID;
3646         }
3647
3648         if (!handler->common || handler->common->state != CREATE) {
3649                 ErrPrint("Handler is invalid\n");
3650                 return LB_STATUS_ERROR_INVALID;
3651         }
3652
3653         if (!handler->common->id) {
3654                 ErrPrint("Invalid handler\n");
3655                 return LB_STATUS_ERROR_INVALID;
3656         }
3657
3658         if (handler->common->request.pinup) {
3659                 ErrPrint("Previous pinup request is not finished\n");
3660                 return LB_STATUS_ERROR_BUSY;
3661         }
3662
3663         if (handler->common->is_pinned_up == flag) {
3664                 DbgPrint("No changes\n");
3665                 return LB_STATUS_ERROR_ALREADY;
3666         }
3667
3668         packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
3669         if (!packet) {
3670                 ErrPrint("Failed to build a param\n");
3671                 return LB_STATUS_ERROR_FAULT;
3672         }
3673
3674         if (!cb) {
3675                 cb = default_pinup_cb;
3676         }
3677
3678         ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
3679         if (ret == (int)LB_STATUS_SUCCESS) {
3680                 handler->cbs.pinup.cb = cb;
3681                 handler->cbs.pinup.data = data;
3682                 handler->common->request.pinup = 1;
3683         }
3684
3685         return ret;
3686 }
3687
3688 EAPI int livebox_is_pinned_up(struct livebox *handler)
3689 {
3690         if (!handler || handler->state != CREATE) {
3691                 ErrPrint("Handler is invalid\n");
3692                 return LB_STATUS_ERROR_INVALID;
3693         }
3694
3695         if (!handler->common || handler->common->state != CREATE) {
3696                 ErrPrint("Handler is invalid\n");
3697                 return LB_STATUS_ERROR_INVALID;
3698         }
3699
3700         if (!handler->common->id) {
3701                 ErrPrint("Invalid handler\n");
3702                 return LB_STATUS_ERROR_INVALID;
3703         }
3704
3705         return handler->common->is_pinned_up;
3706 }
3707
3708 EAPI int livebox_has_pinup(struct livebox *handler)
3709 {
3710         if (!handler || handler->state != CREATE) {
3711                 ErrPrint("Handler is invalid\n");
3712                 return LB_STATUS_ERROR_INVALID;
3713         }
3714
3715         if (!handler->common || handler->common->state != CREATE) {
3716                 ErrPrint("Handler is invalid\n");
3717                 return LB_STATUS_ERROR_INVALID;
3718         }
3719
3720         if (!handler->common->id) {
3721                 ErrPrint("Invalid handler\n");
3722                 return LB_STATUS_ERROR_INVALID;
3723         }
3724
3725         return handler->common->lb.pinup_supported;
3726 }
3727
3728 EAPI int livebox_set_data(struct livebox *handler, void *data)
3729 {
3730         if (!handler) {
3731                 ErrPrint("Handler is NIL\n");
3732                 return LB_STATUS_ERROR_INVALID;
3733         }
3734
3735         if (handler->state != CREATE) {
3736                 ErrPrint("Handler is invalid\n");
3737                 return LB_STATUS_ERROR_INVALID;
3738         }
3739
3740         handler->data = data;
3741         return LB_STATUS_SUCCESS;
3742 }
3743
3744 EAPI void *livebox_get_data(struct livebox *handler)
3745 {
3746         if (!handler) {
3747                 ErrPrint("Handler is NIL\n");
3748                 return NULL;
3749         }
3750
3751         if (handler->state != CREATE) {
3752                 ErrPrint("Handler is invalid\n");
3753                 return NULL;
3754         }
3755
3756         return handler->data;
3757 }
3758
3759 EAPI int livebox_is_exists(const char *pkgname)
3760 {
3761         char *lb;
3762
3763         lb = lb_pkgname(pkgname);
3764         if (lb) {
3765                 free(lb);
3766                 return 1;
3767         }
3768
3769         return 0;
3770 }
3771
3772 EAPI const char *livebox_content(struct livebox *handler)
3773 {
3774         if (!handler || handler->state != CREATE) {
3775                 ErrPrint("Handler is invalid\n");
3776                 return NULL;
3777         }
3778
3779         if (!handler->common || handler->common->state != CREATE) {
3780                 ErrPrint("Invalid handle\n");
3781                 return NULL;
3782         }
3783
3784         return handler->common->content;
3785 }
3786
3787 EAPI const char *livebox_category_title(struct livebox *handler)
3788 {
3789         if (!handler || handler->state != CREATE) {
3790                 ErrPrint("Handler is invalid\n");
3791                 return NULL;
3792         }
3793
3794         if (!handler->common || handler->common->state != CREATE) {
3795                 ErrPrint("Invalid handle\n");
3796                 return NULL;
3797         }
3798
3799         return handler->common->title;
3800 }
3801
3802 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)
3803 {
3804         struct packet *packet;
3805         struct cb_info *cbinfo;
3806         int ret;
3807
3808         if (!handler || handler->state != CREATE) {
3809                 ErrPrint("Handler is invalid\n");
3810                 return LB_STATUS_ERROR_INVALID;
3811         }
3812
3813         if (!handler->common || handler->common->state != CREATE) {
3814                 ErrPrint("Handler is invalid\n");
3815                 return LB_STATUS_ERROR_INVALID;
3816         }
3817
3818         if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
3819                 ErrPrint("Handler is not valid\n");
3820                 return LB_STATUS_ERROR_INVALID;
3821         }
3822
3823         if (!emission) {
3824                 emission = "";
3825         }
3826
3827         if (!source) {
3828                 source = "";
3829         }
3830
3831         packet = packet_create("text_signal", "ssssdddd",
3832                                 handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
3833         if (!packet) {
3834                 ErrPrint("Failed to build a param\n");
3835                 return LB_STATUS_ERROR_FAULT;
3836         }
3837
3838         cbinfo = create_cb_info(cb, data);
3839         if (!cbinfo) {
3840                 packet_destroy(packet);
3841                 return LB_STATUS_ERROR_FAULT;
3842         }
3843
3844         ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
3845         if (ret < 0) {
3846                 destroy_cb_info(cbinfo);
3847         }
3848
3849         return ret;
3850 }
3851
3852 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
3853 {
3854         struct packet *packet;
3855
3856         /*!
3857          * \todo
3858          * Validate the group info using DB
3859          * If the group info is not valid, do not send this request
3860          */
3861
3862         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
3863         if (!packet) {
3864                 ErrPrint("Failed to create a packet\n");
3865                 return LB_STATUS_ERROR_FAULT;
3866         }
3867
3868         return master_rpc_request_only(NULL, packet);
3869 }
3870
3871 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
3872 {
3873         struct packet *packet;
3874
3875         /*!
3876          * \todo
3877          * Validate the group info using DB
3878          * If the group info is not valid, do not send this request
3879          * AND Check the subscribed or not too
3880          */
3881
3882         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
3883         if (!packet) {
3884                 ErrPrint("Failed to create a packet\n");
3885                 return LB_STATUS_ERROR_FAULT;
3886         }
3887
3888         return master_rpc_request_only(NULL, packet);
3889 }
3890
3891 EAPI int livebox_refresh(struct livebox *handler, int force)
3892 {
3893         struct packet *packet;
3894
3895         if (!handler || handler->state != CREATE) {
3896                 ErrPrint("Handler is invalid\n");
3897                 return LB_STATUS_ERROR_INVALID;
3898         }
3899
3900         if (!handler->common || handler->common->state != CREATE) {
3901                 ErrPrint("Handler is not valid\n");
3902                 return LB_STATUS_ERROR_INVALID;
3903         }
3904
3905         if (!handler->common->id) {
3906                 ErrPrint("Handler is not valid\n");
3907                 return LB_STATUS_ERROR_INVALID;
3908         }
3909
3910         packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
3911         if (!packet) {
3912                 ErrPrint("Failed to create a packet\n");
3913                 return LB_STATUS_ERROR_FAULT;
3914         }
3915
3916         return master_rpc_request_only(handler, packet);
3917 }
3918
3919 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
3920 {
3921         struct packet *packet;
3922
3923         if (!cluster || !category) {
3924                 ErrPrint("Invalid argument\n");
3925                 return LB_STATUS_ERROR_INVALID;
3926         }
3927
3928         packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
3929         if (!packet) {
3930                 ErrPrint("Failed to create a packet\n");
3931                 return LB_STATUS_ERROR_FAULT;
3932         }
3933
3934         return master_rpc_request_only(NULL, packet);
3935 }
3936
3937 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
3938 {
3939         int old_state;
3940         int ret;
3941
3942         if (!handler || handler->state != CREATE) {
3943                 ErrPrint("Handler is invalid\n");
3944                 return LB_STATUS_ERROR_INVALID;
3945         }
3946
3947         if (!handler->common || handler->common->state != CREATE) {
3948                 ErrPrint("Handler is not valid\n");
3949                 return LB_STATUS_ERROR_INVALID;
3950         }
3951
3952         if (!handler->common->id) {
3953                 ErrPrint("Handler is not valid\n");
3954                 return LB_STATUS_ERROR_INVALID;
3955         }
3956
3957         if (!handler->common->is_user) {
3958                 /* System cluster livebox cannot be changed its visible states */
3959                 if (state == (int)LB_HIDE_WITH_PAUSE) {
3960                         ErrPrint("CA Livebox is not able to change the visibility\n");
3961                         return LB_STATUS_ERROR_PERMISSION;
3962                 }
3963         }
3964
3965         DbgPrint("[%s] Change visiblity to 0x%x\n", handler->common->pkgname, state);
3966
3967         if (handler->visible == state) {
3968                 DbgPrint("%s has no changes\n", handler->common->pkgname);
3969                 return LB_STATUS_ERROR_ALREADY;
3970         }
3971
3972         old_state = handler->visible;
3973         handler->visible = state;
3974
3975         ret = lb_set_visibility(handler, state);
3976         if (ret < 0) {
3977                 handler->visible = old_state;
3978         }
3979
3980         return ret;
3981 }
3982
3983 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
3984 {
3985         if (!handler || handler->state != CREATE) {
3986                 ErrPrint("Handler is invalid\n");
3987                 return LB_VISIBLE_ERROR;
3988         }
3989
3990         if (!handler->common || handler->common->state != CREATE) {
3991                 ErrPrint("Handler is not valid\n");
3992                 return LB_VISIBLE_ERROR;
3993         }
3994
3995         if (!handler->common->id) {
3996                 ErrPrint("Handler is not valid\n");
3997                 return LB_VISIBLE_ERROR;
3998         }
3999
4000         return handler->visible;
4001 }
4002
4003 int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
4004 {
4005         void *pc = NULL;
4006         void *ps = NULL;
4007
4008         if (cluster) {
4009                 pc = strdup(cluster);
4010                 if (!pc) {
4011                         ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
4012                         return LB_STATUS_ERROR_MEMORY;
4013                 }
4014         }
4015
4016         if (category) {
4017                 ps = strdup(category);
4018                 if (!ps) {
4019                         ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
4020                         free(pc);
4021                         return LB_STATUS_ERROR_MEMORY;
4022                 }
4023         }
4024
4025         if (common->cluster) {
4026                 free(common->cluster);
4027         }
4028
4029         if (common->category) {
4030                 free(common->category);
4031         }
4032
4033         common->cluster = pc;
4034         common->category = ps;
4035
4036         return LB_STATUS_SUCCESS;
4037 }
4038
4039 void lb_set_size(struct livebox_common *common, int w, int h)
4040 {
4041         common->lb.width = w;
4042         common->lb.height = h;
4043 }
4044
4045 void lb_set_update_mode(struct livebox_common *common, int active_mode)
4046 {
4047         common->is_active_update = active_mode;
4048 }
4049
4050 void lb_set_pdsize(struct livebox_common *common, int w, int h)
4051 {
4052         common->pd.width = w;
4053         common->pd.height = h;
4054 }
4055
4056 void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
4057 {
4058         common->pd.default_width = w;
4059         common->pd.default_height = h;
4060 }
4061
4062 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
4063 {
4064         struct dlist *l;
4065         struct dlist *n;
4066         struct fault_info *info;
4067
4068         s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4069
4070         dlist_foreach_safe(s_info.fault_list, l, n, info) {
4071                 if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
4072                         info->is_deleted = 1;
4073                 }
4074
4075                 if (info->is_deleted) {
4076                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
4077                         free(info);
4078                 }
4079         }
4080
4081         s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4082 }
4083
4084 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
4085 {
4086         struct dlist *l;
4087         struct dlist *n;
4088         struct event_info *info;
4089
4090         if (event == (int)LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
4091                 if (handler->visible != LB_SHOW) {
4092                         DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
4093                         handler->paused_updating++;
4094                         return;
4095                 } else {
4096                         handler->paused_updating = 0;
4097                 }
4098         }
4099
4100         s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4101
4102         dlist_foreach_safe(s_info.event_list, l, n, info) {
4103                 if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
4104                         DbgPrint("Event handler returns EXIT_FAILURE\n");
4105                         info->is_deleted = 1;
4106                 }
4107
4108                 if (info->is_deleted) {
4109                         s_info.event_list = dlist_remove(s_info.event_list, l);
4110                         free(info);
4111                 }
4112         }
4113
4114         s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4115 }
4116
4117 struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
4118 {
4119         struct dlist *l;
4120         struct livebox_common *common;
4121
4122         dlist_foreach(s_info.livebox_common_list, l, common) {
4123                 if (!common->id) {
4124                         continue;
4125                 }
4126
4127                 if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
4128                         return common;
4129                 }
4130         }
4131
4132         return NULL;
4133 }
4134
4135 struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
4136 {
4137         struct dlist *l;
4138         struct livebox_common *common;
4139
4140         dlist_foreach(s_info.livebox_common_list, l, common) {
4141                 if (common->timestamp == timestamp) {
4142                         return common;
4143                 }
4144         }
4145
4146         return NULL;
4147 }
4148
4149 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
4150 {
4151         struct livebox *handler;
4152
4153         handler = calloc(1, sizeof(*handler));
4154         if (!handler) {
4155                 ErrPrint("Failed to create a new livebox\n");
4156                 return NULL;
4157         }
4158
4159         handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
4160         if (!handler->common) {
4161                 ErrPrint("Heap: %s\n", strerror(errno));
4162                 free(handler);
4163                 return NULL;
4164         }
4165
4166         lb_common_ref(handler->common, handler);
4167         lb_set_id(handler->common, id);
4168         handler->common->timestamp = timestamp;
4169         handler->common->state = CREATE;
4170         handler->visible = LB_SHOW;
4171         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
4172
4173         return lb_ref(handler);
4174 }
4175
4176 int lb_delete_all(void)
4177 {
4178         struct dlist *l;
4179         struct dlist *n;
4180         struct livebox *handler;
4181
4182         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
4183                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
4184                 lb_unref(handler, 1);
4185         }
4186
4187         return LB_STATUS_SUCCESS;
4188 }
4189
4190 int lb_set_content(struct livebox_common *common, const char *content)
4191 {
4192         char *pc = NULL;
4193
4194         if (content) {
4195                 pc = strdup(content);
4196                 if (!pc) {
4197                         ErrPrint("heap: %s [%s]\n", strerror(errno), content);
4198                         return LB_STATUS_ERROR_MEMORY;
4199                 }
4200         }
4201
4202         free(common->content);
4203         common->content = pc;
4204         return LB_STATUS_SUCCESS;
4205 }
4206
4207 int lb_set_title(struct livebox_common *common, const char *title)
4208 {
4209         char *pt = NULL;
4210
4211         if (title) {
4212                 pt = strdup(title);
4213                 if (!pt) {
4214                         ErrPrint("heap: %s [%s]\n", strerror(errno), title);
4215                         return LB_STATUS_ERROR_MEMORY;
4216                 }
4217         }
4218
4219         free(common->title);
4220         common->title = pt;
4221         return LB_STATUS_SUCCESS;
4222 }
4223
4224 void lb_set_size_list(struct livebox_common *common, int size_list)
4225 {
4226         common->lb.size_list = size_list;
4227 }
4228
4229 void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
4230 {
4231         char *pa = NULL;
4232
4233         if (!auto_launch || !strlen(auto_launch)) {
4234                 return;
4235         }
4236
4237         pa = strdup(auto_launch);
4238         if (!pa) {
4239                 ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
4240                 return;
4241         }
4242
4243         free(common->lb.auto_launch);
4244         common->lb.auto_launch = pa;
4245 }
4246
4247 void lb_set_priority(struct livebox_common *common, double priority)
4248 {
4249         common->lb.priority = priority;
4250 }
4251
4252 void lb_set_id(struct livebox_common *common, const char *id)
4253 {
4254         char *pi = NULL;
4255
4256         if (id) {
4257                 pi = strdup(id);
4258                 if (!pi) {
4259                         ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
4260                         return;
4261                 }
4262         }
4263
4264         free(common->id);
4265         common->id = pi;
4266 }
4267
4268 void lb_set_filename(struct livebox_common *common, const char *filename)
4269 {
4270         if (common->filename) {
4271                 if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
4272                         if (common->filename[0] && unlink(common->filename) < 0) {
4273                                 ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
4274                         }
4275                 }
4276
4277                 free(common->filename);
4278         }
4279
4280         common->filename = strdup(filename);
4281         if (!common->filename) {
4282                 ErrPrint("Heap: %s\n", strerror(errno));
4283         }
4284 }
4285
4286 void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
4287 {
4288         char *_icon = NULL;
4289         char *_name = NULL;
4290
4291         if (icon && strlen(icon)) {
4292                 _icon = strdup(icon);
4293                 if (!_icon) {
4294                         ErrPrint("Heap: %s\n", strerror(errno));
4295                 }
4296         }
4297
4298         if (name && strlen(name)) {
4299                 _name = strdup(name);
4300                 if (!_name) {
4301                         ErrPrint("Heap: %s\n", strerror(errno));
4302                 }
4303         }
4304
4305         free(common->alt.icon);
4306         common->alt.icon = _icon;
4307
4308         free(common->alt.name);
4309         common->alt.name = _name;
4310 }
4311
4312 int lb_set_lb_fb(struct livebox_common *common, const char *filename)
4313 {
4314         struct fb_info *fb;
4315
4316         if (!common) {
4317                 return LB_STATUS_ERROR_INVALID;
4318         }
4319
4320         fb = common->lb.fb;
4321         if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
4322                 return LB_STATUS_SUCCESS;
4323         }
4324
4325         common->lb.fb = NULL;
4326
4327         if (!filename || filename[0] == '\0') {
4328                 if (fb) {
4329                         fb_destroy(fb);
4330                 }
4331                 return LB_STATUS_SUCCESS;
4332         }
4333
4334         common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
4335         if (!common->lb.fb) {
4336                 ErrPrint("Faield to create a FB\n");
4337                 if (fb) {
4338                         fb_destroy(fb);
4339                 }
4340                 return LB_STATUS_ERROR_FAULT;
4341         }
4342
4343         if (fb) {
4344                 fb_destroy(fb);
4345         }
4346
4347         return LB_STATUS_SUCCESS;
4348 }
4349
4350 int lb_set_pd_fb(struct livebox_common *common, const char *filename)
4351 {
4352         struct fb_info *fb;
4353
4354         if (!common || common->state != CREATE) {
4355                 return LB_STATUS_ERROR_INVALID;
4356         }
4357
4358         fb = common->pd.fb;
4359         if (fb && !strcmp(fb_id(fb), filename)) {
4360                 /* BUFFER is not changed, just update the content */
4361                 return LB_STATUS_ERROR_EXIST;
4362         }
4363         common->pd.fb = NULL;
4364
4365         if (!filename || filename[0] == '\0') {
4366                 if (fb) {
4367                         fb_destroy(fb);
4368                 }
4369                 return LB_STATUS_SUCCESS;
4370         }
4371
4372         common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
4373         if (!common->pd.fb) {
4374                 ErrPrint("Failed to create a FB\n");
4375                 if (fb) {
4376                         fb_destroy(fb);
4377                 }
4378                 return LB_STATUS_ERROR_FAULT;
4379         }
4380
4381         if (fb) {
4382                 fb_destroy(fb);
4383         }
4384         return LB_STATUS_SUCCESS;
4385 }
4386
4387 struct fb_info *lb_get_lb_fb(struct livebox_common *common)
4388 {
4389         return common->lb.fb;
4390 }
4391
4392 struct fb_info *lb_get_pd_fb(struct livebox_common *common)
4393 {
4394         return common->pd.fb;
4395 }
4396
4397 void lb_set_user(struct livebox_common *common, int user)
4398 {
4399         common->is_user = user;
4400 }
4401
4402 void lb_set_pinup(struct livebox_common *common, int pinup_supported)
4403 {
4404         common->lb.pinup_supported = pinup_supported;
4405 }
4406
4407 void lb_set_text_lb(struct livebox_common *common)
4408 {
4409         common->lb.type = _LB_TYPE_TEXT;
4410 }
4411
4412 void lb_set_text_pd(struct livebox_common *common)
4413 {
4414         common->pd.type = _PD_TYPE_TEXT;
4415 }
4416
4417 int lb_text_lb(struct livebox_common *common)
4418 {
4419         return common->lb.type == _LB_TYPE_TEXT;
4420 }
4421
4422 int lb_text_pd(struct livebox_common *common)
4423 {
4424         return common->pd.type == _PD_TYPE_TEXT;
4425 }
4426
4427 void lb_set_period(struct livebox_common *common, double period)
4428 {
4429         common->lb.period = period;
4430 }
4431
4432 struct livebox *lb_ref(struct livebox *handler)
4433 {
4434         if (!handler) {
4435                 return NULL;
4436         }
4437
4438         handler->refcnt++;
4439         return handler;
4440 }
4441
4442 struct livebox *lb_unref(struct livebox *handler, int destroy_common)
4443 {
4444         if (!handler) {
4445                 return NULL;
4446         }
4447
4448         handler->refcnt--;
4449         if (handler->refcnt > 0) {
4450                 return handler;
4451         }
4452
4453         if (handler->cbs.created.cb) {
4454                 handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
4455                 handler->cbs.created.cb = NULL;
4456                 handler->cbs.created.data = NULL;
4457         }
4458
4459         if (handler->cbs.deleted.cb) {
4460                 handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
4461                 handler->cbs.deleted.cb = NULL;
4462                 handler->cbs.deleted.data = NULL;
4463         }
4464
4465         if (handler->cbs.pinup.cb) {
4466                 handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
4467                 handler->cbs.pinup.cb = NULL;
4468                 handler->cbs.pinup.data = NULL;
4469         }
4470
4471         if (handler->cbs.group_changed.cb) {
4472                 handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
4473                 handler->cbs.group_changed.cb = NULL;
4474                 handler->cbs.group_changed.data = NULL;
4475         }
4476
4477         if (handler->cbs.period_changed.cb) {
4478                 handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
4479                 handler->cbs.period_changed.cb = NULL;
4480                 handler->cbs.period_changed.data = NULL;
4481         }
4482
4483         if (handler->cbs.size_changed.cb) {
4484                 handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
4485                 handler->cbs.size_changed.cb = NULL;
4486                 handler->cbs.size_changed.data = NULL;
4487         }
4488
4489         if (handler->cbs.pd_created.cb) {
4490                 handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
4491                 handler->cbs.pd_created.cb = NULL;
4492                 handler->cbs.pd_created.data = NULL;
4493         }
4494
4495         if (handler->cbs.pd_destroyed.cb) {
4496                 handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
4497                 handler->cbs.pd_destroyed.cb = NULL;
4498                 handler->cbs.pd_destroyed.data = NULL;
4499         }
4500
4501         if (handler->cbs.update_mode.cb) {
4502                 handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
4503                 handler->cbs.update_mode.cb = NULL;
4504                 handler->cbs.update_mode.data = NULL;
4505         }
4506
4507         if (handler->cbs.access_event.cb) {
4508                 handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
4509                 handler->cbs.access_event.cb = NULL;
4510                 handler->cbs.access_event.data = NULL;
4511         }
4512
4513         if (handler->cbs.key_event.cb) {
4514                 handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
4515                 handler->cbs.key_event.cb = NULL;
4516                 handler->cbs.key_event.data = NULL;
4517         }
4518
4519         dlist_remove_data(s_info.livebox_list, handler);
4520
4521         handler->state = DESTROYED;
4522         if (lb_common_unref(handler->common, handler) == 0) {
4523                 if (destroy_common) {
4524                         /*!
4525                          * \note
4526                          * Lock file should be deleted after all callbacks are processed.
4527                          */
4528                         lb_destroy_lock_file(handler->common, 0);
4529                         lb_destroy_common_handle(handler->common);
4530                 }
4531         }
4532         free(handler);
4533         DbgPrint("Handler is released\n");
4534         return NULL;
4535 }
4536
4537 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
4538 {
4539         struct packet *packet;
4540         struct cb_info *cbinfo;
4541         int ret;
4542
4543         if (handler->common->request.deleted) {
4544                 ErrPrint("Already in-progress\n");
4545                 if (cb) {
4546                         cb(handler, LB_STATUS_SUCCESS, data);
4547                 }
4548                 return LB_STATUS_ERROR_BUSY;
4549         }
4550
4551         if (!cb) {
4552                 cb = default_delete_cb;
4553         }
4554
4555         packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp);
4556         if (!packet) {
4557                 ErrPrint("Failed to build a param\n");
4558                 if (cb) {
4559                         cb(handler, LB_STATUS_ERROR_FAULT, data);
4560                 }
4561
4562                 return LB_STATUS_ERROR_FAULT;
4563         }
4564
4565         cbinfo = create_cb_info(cb, data);
4566         if (!cbinfo) {
4567                 packet_destroy(packet);
4568                 ErrPrint("Failed to create cbinfo\n");
4569                 if (cb) {
4570                         cb(handler, LB_STATUS_ERROR_FAULT, data);
4571                 }
4572
4573                 return LB_STATUS_ERROR_FAULT;
4574         }
4575
4576         ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
4577         if (ret < 0) {
4578                 /*!
4579                  * Packet is destroyed by master_rpc_async_request.
4580                  */
4581                 destroy_cb_info(cbinfo);
4582
4583                 if (cb) {
4584                         cb(handler, LB_STATUS_ERROR_FAULT, data);
4585                 }
4586         } else {
4587                 handler->common->request.deleted = 1;
4588         }
4589
4590         return ret;
4591 }
4592
4593 EAPI int livebox_client_paused(void)
4594 {
4595         struct packet *packet;
4596
4597         packet = packet_create_noack("client_paused", "d", util_timestamp());
4598         if (!packet) {
4599                 ErrPrint("Failed to create a pause packet\n");
4600                 return LB_STATUS_ERROR_FAULT;
4601         }
4602
4603         return master_rpc_request_only(NULL, packet);
4604 }
4605
4606 EAPI int livebox_client_resumed(void)
4607 {
4608         struct packet *packet;
4609
4610         packet = packet_create_noack("client_resumed", "d", util_timestamp());
4611         if (!packet) {
4612                 ErrPrint("Failed to create a resume packet\n");
4613                 return LB_STATUS_ERROR_FAULT;
4614         }
4615
4616         return master_rpc_request_only(NULL, packet);
4617 }
4618
4619 EAPI int livebox_sync_lb_fb(struct livebox *handler)
4620 {
4621         if (!handler || handler->state != CREATE) {
4622                 ErrPrint("Invalid handle\n");
4623                 return LB_STATUS_ERROR_INVALID;
4624         }
4625
4626         if (!handler->common || handler->common->state != CREATE) {
4627                 ErrPrint("Invalid handle\n");
4628                 return LB_STATUS_ERROR_INVALID;
4629         }
4630
4631         if (!handler->common->id) {
4632                 return LB_STATUS_ERROR_INVALID;
4633         }
4634
4635         return lb_sync_lb_fb(handler->common);
4636 }
4637
4638 int lb_sync_lb_fb(struct livebox_common *common)
4639 {
4640         int ret;
4641
4642         if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
4643                 (void)do_fb_lock(common->lb.lock_fd);
4644                 ret = fb_sync(lb_get_lb_fb(common));
4645                 (void)do_fb_unlock(common->lb.lock_fd);
4646         } else {
4647                 ret = fb_sync(lb_get_lb_fb(common));
4648         }
4649
4650         return ret;
4651 }
4652
4653 int lb_sync_pd_fb(struct livebox_common *common)
4654 {
4655         int ret;
4656
4657         if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
4658                 (void)do_fb_lock(common->pd.lock_fd);
4659                 ret = fb_sync(lb_get_pd_fb(common));
4660                 (void)do_fb_unlock(common->pd.lock_fd);
4661         } else {
4662                 ret = fb_sync(lb_get_pd_fb(common));
4663         }
4664
4665         return ret;
4666 }
4667
4668 EAPI int livebox_sync_pd_fb(struct livebox *handler)
4669 {
4670         if (!handler || handler->state != CREATE) {
4671                 ErrPrint("Invalid handle\n");
4672                 return LB_STATUS_ERROR_INVALID;
4673         }
4674
4675         if (!handler->common || handler->common->state != CREATE) {
4676                 ErrPrint("Invalid handle\n");
4677                 return LB_STATUS_ERROR_INVALID;
4678         }
4679
4680         if (!handler->common->id) {
4681                 ErrPrint("Invalid handle\n");
4682                 return LB_STATUS_ERROR_INVALID;
4683         }
4684
4685         return lb_sync_pd_fb(handler->common);
4686 }
4687
4688 EAPI const char *livebox_alt_icon(struct livebox *handler)
4689 {
4690         if (!handler || handler->state != CREATE) {
4691                 ErrPrint("Handler is not valid[%p]\n", handler);
4692                 return NULL;
4693         }
4694
4695         if (!handler->common || handler->common->state != CREATE) {
4696                 ErrPrint("Handler is not valid\n");
4697                 return NULL;
4698         }
4699
4700         return handler->common->alt.icon;
4701 }
4702
4703 EAPI const char *livebox_alt_name(struct livebox *handler)
4704 {
4705         if (!handler || handler->state != CREATE) {
4706                 ErrPrint("Handler is not valid[%p]\n", handler);
4707                 return NULL;
4708         }
4709
4710         if (!handler->common || handler->common->state != CREATE) {
4711                 ErrPrint("Handler is not valid\n");
4712                 return NULL;
4713         }
4714
4715         return handler->common->alt.name;
4716 }
4717
4718 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
4719 {
4720         int ret = LB_STATUS_SUCCESS;
4721         int fd;
4722
4723         if (!handler || handler->state != CREATE) {
4724                 ErrPrint("Handler is not valid[%p]\n", handler);
4725                 return LB_STATUS_ERROR_INVALID;
4726         }
4727
4728         if (!handler->common || handler->common->state != CREATE) {
4729                 ErrPrint("Handler is not valid\n");
4730                 return LB_STATUS_ERROR_INVALID;
4731         }
4732
4733         if (!handler->common->id) {
4734                 ErrPrint("Handler is not valid[%p]\n", handler);
4735                 return LB_STATUS_ERROR_INVALID;
4736         }
4737
4738         if (is_pd) {
4739                 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4740                         DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4741                         return LB_STATUS_ERROR_INVALID;
4742                 }
4743
4744                 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4745                         return LB_STATUS_SUCCESS;
4746                 }
4747
4748                 fd = handler->common->pd.lock_fd;
4749         } else {
4750                 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4751                         DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4752                         return LB_STATUS_ERROR_INVALID;
4753                 }
4754
4755                 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4756                         return LB_STATUS_SUCCESS;
4757                 }
4758
4759                 fd = handler->common->lb.lock_fd;
4760         }
4761
4762         ret = do_fb_lock(fd);
4763
4764         return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4765 }
4766
4767 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
4768 {
4769         int ret = LB_STATUS_SUCCESS;
4770         int fd;
4771
4772         if (!handler || handler->state != CREATE) {
4773                 ErrPrint("Invalid handle\n");
4774                 return LB_STATUS_ERROR_INVALID;
4775         }
4776
4777         if (!handler->common || handler->common->state != CREATE) {
4778                 ErrPrint("Invalid handle\n");
4779                 return LB_STATUS_ERROR_INVALID;
4780         }
4781
4782         if (!handler->common->id) {
4783                 ErrPrint("Handler is not valid[%p]\n", handler);
4784                 return LB_STATUS_ERROR_INVALID;
4785         }
4786
4787         if (is_pd) {
4788                 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4789                         DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4790                         return LB_STATUS_ERROR_INVALID;
4791                 }
4792
4793                 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4794                         return LB_STATUS_SUCCESS;
4795                 }
4796
4797                 fd = handler->common->pd.lock_fd;
4798         } else {
4799                 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4800                         DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4801                         return LB_STATUS_ERROR_INVALID;
4802                 }
4803
4804                 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4805                         return LB_STATUS_SUCCESS;
4806                 }
4807
4808                 fd = handler->common->lb.lock_fd;
4809         }
4810
4811         ret = do_fb_unlock(fd);
4812
4813         return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4814 }
4815
4816 EAPI int livebox_set_option(enum livebox_option_type option, int state)
4817 {
4818         int ret = LB_STATUS_SUCCESS;
4819
4820         switch (option) {
4821         case LB_OPTION_MANUAL_SYNC:
4822                 conf_set_manual_sync(state);
4823                 break;
4824         case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4825                 conf_set_frame_drop_for_resizing(state);
4826                 break;
4827         case LB_OPTION_SHARED_CONTENT:
4828                 conf_set_shared_content(state);
4829                 break;
4830         default:
4831                 ret = LB_STATUS_ERROR_INVALID;
4832                 break;
4833         }
4834
4835         return ret;
4836 }
4837
4838 EAPI int livebox_option(enum livebox_option_type option)
4839 {
4840         int ret;
4841
4842         switch (option) {
4843         case LB_OPTION_MANUAL_SYNC:
4844                 ret = conf_manual_sync();
4845                 break;
4846         case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4847                 ret = conf_frame_drop_for_resizing();
4848                 break;
4849         case LB_OPTION_SHARED_CONTENT:
4850                 ret = conf_shared_content();
4851                 break;
4852         default:
4853                 ret = LB_STATUS_ERROR_INVALID;
4854                 break;
4855         }
4856
4857         return ret;
4858 }
4859
4860 EAPI int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data)
4861 {
4862         s_info.launch.handler = launch_handler;
4863         s_info.launch.data = data;
4864
4865         return LB_STATUS_SUCCESS;
4866 }
4867
4868 /* End of a file */