Initialize Tizen 2.3
[apps/livebox/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 = 0;
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 == LB_SHOW) {
1416                 need_to_add_job = !!handler->paused_updating;
1417         } else if (handler->common->visible == 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 == 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 == LB_SHOW && state == 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 == 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 == 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 == 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 == 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 shorter 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         case CONTENT_EVENT_ON_SCROLL | CONTENT_EVENT_MOUSE_MASK:
2699                 strcpy(ptr, "_mouse_on_scroll");
2700                 break;
2701         case CONTENT_EVENT_ON_HOLD | CONTENT_EVENT_MOUSE_MASK:
2702                 strcpy(ptr, "_mouse_on_hold");
2703                 break;
2704         case CONTENT_EVENT_OFF_SCROLL | CONTENT_EVENT_MOUSE_MASK:
2705                 strcpy(ptr, "_mouse_off_scroll");
2706                 break;
2707         case CONTENT_EVENT_OFF_HOLD | CONTENT_EVENT_MOUSE_MASK:
2708                 strcpy(ptr, "_mouse_off_hold");
2709                 break;
2710         default:
2711                 ErrPrint("Invalid event type\n");
2712                 return LB_STATUS_ERROR_INVALID;
2713         }
2714
2715         return send_mouse_event(handler, cmd, x * w, y * h);
2716 }
2717
2718 EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data)
2719 {
2720         char cmd[32] = { '\0', };
2721         char *ptr = cmd;
2722         int ret;
2723
2724         if (!handler || handler->state != CREATE) {
2725                 ErrPrint("Handler is invalid\n");
2726                 return LB_STATUS_ERROR_INVALID;
2727         }
2728
2729         if (!handler->common || handler->common->state != CREATE) {
2730                 ErrPrint("Handler is invalid\n");
2731                 return LB_STATUS_ERROR_INVALID;
2732         }
2733
2734         if (!handler->common->id) {
2735                 ErrPrint("Handler is not valid\n");
2736                 return LB_STATUS_ERROR_INVALID;
2737         }
2738
2739         if (!(type & CONTENT_EVENT_KEY_MASK)) {
2740                 ErrPrint("Invalid key event is used\n");
2741                 return LB_STATUS_ERROR_INVALID;
2742         }
2743
2744         if (handler->common->request.key_event) {
2745                 ErrPrint("Previous key event is not completed yet\n");
2746                 return LB_STATUS_ERROR_BUSY;
2747         }
2748
2749         if (type & CONTENT_EVENT_PD_MASK) {
2750                 if (!handler->common->is_pd_created) {
2751                         ErrPrint("PD is not created\n");
2752                         return LB_STATUS_ERROR_INVALID;
2753                 }
2754
2755                 if (!handler->common->pd.fb) {
2756                         ErrPrint("Handler is not valid\n");
2757                         return LB_STATUS_ERROR_INVALID;
2758                 }
2759
2760                 if (type & CONTENT_EVENT_KEY_DOWN) {
2761                         /*!
2762                          * \TODO
2763                          * filtering the reproduced events if it is too fast
2764                          */
2765                 } else if (type & CONTENT_EVENT_KEY_SET) {
2766                         /*!
2767                          * \TODO
2768                          * What can I do for this case?
2769                          */
2770                 }
2771
2772                 *ptr++ = 'p';
2773                 *ptr++ = 'd';
2774         } else if (type & CONTENT_EVENT_LB_MASK) {
2775                 if (!handler->common->lb.mouse_event) {
2776                         return LB_STATUS_ERROR_INVALID;
2777                 }
2778
2779                 if (!handler->common->lb.fb) {
2780                         ErrPrint("Handler is not valid\n");
2781                         return LB_STATUS_ERROR_INVALID;
2782                 }
2783
2784                 if (type & CONTENT_EVENT_KEY_DOWN) {
2785                         /*!
2786                          * \TODO
2787                          * filtering the reproduced events if it is too fast
2788                          */
2789                 } else if (type & CONTENT_EVENT_KEY_SET) {
2790                         /*!
2791                          * What can I do for this case?
2792                          */
2793                 }
2794
2795                 *ptr++ = 'l';
2796                 *ptr++ = 'b';
2797         } else {
2798                 ErrPrint("Invalid event type\n");
2799                 return LB_STATUS_ERROR_INVALID;
2800         }
2801
2802         /*!
2803          * Must be short than 29 bytes.
2804          */
2805         switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2806         case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK:
2807                 strcpy(ptr, "_key_focus_in");
2808                 break;
2809         case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK:
2810                 strcpy(ptr, "_key_focus_out");
2811                 break;
2812         case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
2813                 strcpy(ptr, "_key_up");
2814                 break;
2815         case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
2816                 strcpy(ptr, "_key_down");
2817                 break;
2818         case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK:
2819                 strcpy(ptr, "_key_set");
2820                 break;
2821         case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK:
2822                 strcpy(ptr, "_key_unset");
2823                 break;
2824         default:
2825                 ErrPrint("Invalid event type\n");
2826                 return LB_STATUS_ERROR_INVALID;
2827         }
2828
2829         if (!cb) {
2830                 cb = default_key_event_cb;
2831         }
2832
2833         ret = send_key_event(handler, cmd, keycode);
2834         if (ret == (int)LB_STATUS_SUCCESS) {
2835                 handler->cbs.key_event.cb = cb;
2836                 handler->cbs.key_event.data = data;
2837                 handler->common->request.key_event = 1;
2838         }
2839
2840         return ret;
2841 }
2842
2843 EAPI const char *livebox_filename(struct livebox *handler)
2844 {
2845         if (!handler || handler->state != CREATE) {
2846                 ErrPrint("Handler is invalid\n");
2847                 return NULL;
2848         }
2849
2850         if (!handler->common || handler->common->state != CREATE) {
2851                 ErrPrint("Handler is invalid\n");
2852                 return NULL;
2853         }
2854
2855         if (!handler->common->id) {
2856                 ErrPrint("Handler is not valid\n");
2857                 return NULL;
2858         }
2859
2860         if (handler->common->filename) {
2861                 return handler->common->filename;
2862         }
2863
2864         /* Oooops */
2865         return util_uri_to_path(handler->common->id);
2866 }
2867
2868 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
2869 {
2870         int _w;
2871         int _h;
2872
2873         if (!handler || handler->state != CREATE) {
2874                 ErrPrint("Handler is invalid\n");
2875                 return LB_STATUS_ERROR_INVALID;
2876         }
2877
2878         if (!handler->common || handler->common->state != CREATE) {
2879                 ErrPrint("Handler is invalid\n");
2880                 return LB_STATUS_ERROR_INVALID;
2881         }
2882
2883         if (!handler->common->id) {
2884                 ErrPrint("Handler is not valid\n");
2885                 return LB_STATUS_ERROR_INVALID;
2886         }
2887
2888         if (!w) {
2889                 w = &_w;
2890         }
2891         if (!h) {
2892                 h = &_h;
2893         }
2894
2895         if (!handler->common->is_pd_created) {
2896                 *w = handler->common->pd.default_width;
2897                 *h = handler->common->pd.default_height;
2898         } else {
2899                 *w = handler->common->pd.width;
2900                 *h = handler->common->pd.height;
2901         }
2902
2903         return LB_STATUS_SUCCESS;
2904 }
2905
2906 EAPI int livebox_size(struct livebox *handler)
2907 {
2908         int w;
2909         int h;
2910
2911         if (!handler || handler->state != CREATE) {
2912                 ErrPrint("Handler is invalid\n");
2913                 return LB_STATUS_ERROR_INVALID;
2914         }
2915
2916         if (!handler->common || handler->common->state != CREATE) {
2917                 ErrPrint("Handler is invalid\n");
2918                 return LB_STATUS_ERROR_INVALID;
2919         }
2920
2921         if (!handler->common->id) {
2922                 ErrPrint("Handler is not valid\n");
2923                 return LB_STATUS_ERROR_INVALID;
2924         }
2925
2926         w = handler->common->lb.width;
2927         h = handler->common->lb.height;
2928
2929         switch (handler->common->lb.type) {
2930         case _LB_TYPE_BUFFER:
2931         case _LB_TYPE_SCRIPT:
2932                 if (!fb_is_created(handler->common->lb.fb)) {
2933                         w = 0;
2934                         h = 0;
2935                 }
2936                 break;
2937         default:
2938                 break;
2939         }
2940
2941         return livebox_service_size_type(w, h);
2942 }
2943
2944 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
2945 {
2946         struct packet *packet;
2947         int ret;
2948
2949         if (!handler) {
2950                 ErrPrint("Handler is NIL\n");
2951                 return LB_STATUS_ERROR_INVALID;
2952         }
2953
2954         if (!cluster || !category || handler->state != CREATE) {
2955                 ErrPrint("Invalid argument\n");
2956                 return LB_STATUS_ERROR_INVALID;
2957         }
2958
2959         if (!handler->common || handler->common->state != CREATE) {
2960                 ErrPrint("Invalid argument\n");
2961                 return LB_STATUS_ERROR_INVALID;
2962         }
2963
2964         if (!handler->common->id) {
2965                 ErrPrint("Invalid argument\n");
2966                 return LB_STATUS_ERROR_INVALID;
2967         }
2968
2969         if (handler->common->request.group_changed) {
2970                 ErrPrint("Previous group changing request is not finished yet\n");
2971                 return LB_STATUS_ERROR_BUSY;
2972         }
2973
2974         if (!handler->common->is_user) {
2975                 ErrPrint("CA Livebox is not able to change the group\n");
2976                 return LB_STATUS_ERROR_PERMISSION;
2977         }
2978
2979         if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) {
2980                 DbgPrint("No changes\n");
2981                 return LB_STATUS_ERROR_ALREADY;
2982         }
2983
2984         packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category);
2985         if (!packet) {
2986                 ErrPrint("Failed to build a param\n");
2987                 return LB_STATUS_ERROR_FAULT;
2988         }
2989
2990         if (!cb) {
2991                 cb = default_group_changed_cb;
2992         }
2993
2994         ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
2995         if (ret == (int)LB_STATUS_SUCCESS) {
2996                 handler->cbs.group_changed.cb = cb;
2997                 handler->cbs.group_changed.data = data; 
2998                 handler->common->request.group_changed = 1;
2999         }
3000
3001         return ret;
3002 }
3003
3004 EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category)
3005 {
3006         if (!handler) {
3007                 ErrPrint("Handler is NIL\n");
3008                 return LB_STATUS_ERROR_INVALID;
3009         }
3010
3011         if (!cluster || !category || handler->state != CREATE) {
3012                 ErrPrint("Invalid argument\n");
3013                 return LB_STATUS_ERROR_INVALID;
3014         }
3015
3016         if (!handler->common || handler->common->state != CREATE) {
3017                 ErrPrint("Invalid argument\n");
3018                 return LB_STATUS_ERROR_INVALID;
3019         }
3020
3021         if (!handler->common->id) {
3022                 ErrPrint("Invalid argument\n");
3023                 return LB_STATUS_ERROR_INVALID;
3024         }
3025
3026         *cluster = handler->common->cluster;
3027         *category = handler->common->category;
3028         return LB_STATUS_SUCCESS;
3029 }
3030
3031 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
3032 {
3033         register int i;
3034         register int j;
3035
3036         if (!handler || !size_list) {
3037                 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
3038                 return LB_STATUS_ERROR_INVALID;
3039         }
3040
3041         if (!cnt || handler->state != CREATE) {
3042                 ErrPrint("Handler is not valid\n");
3043                 return LB_STATUS_ERROR_INVALID;
3044         }
3045
3046         if (!handler->common || handler->common->state != CREATE) {
3047                 ErrPrint("Handler is not valid\n");
3048                 return LB_STATUS_ERROR_INVALID;
3049         }
3050
3051         if (!handler->common->id) {
3052                 ErrPrint("Handler is not valid\n");
3053                 return LB_STATUS_ERROR_INVALID;
3054         }
3055
3056         for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
3057                 if (handler->common->lb.size_list & (0x01 << i)) {
3058                         if (j == *cnt) {
3059                                 break;
3060                         }
3061
3062                         size_list[j++] = (0x01 << i);
3063                 }
3064         }
3065
3066         *cnt = j;
3067         return LB_STATUS_SUCCESS;
3068 }
3069
3070 EAPI const char *livebox_pkgname(struct livebox *handler)
3071 {
3072         if (!handler) {
3073                 ErrPrint("Handler is NIL\n");
3074                 return NULL;
3075         }
3076
3077         if (handler->state != CREATE) {
3078                 ErrPrint("Handler is not valid\n");
3079                 return NULL;
3080         }
3081
3082         if (!handler->common || handler->common->state != CREATE) {
3083                 ErrPrint("Handler is not valid\n");
3084                 return NULL;
3085         }
3086
3087         return handler->common->pkgname;
3088 }
3089
3090 EAPI double livebox_priority(struct livebox *handler)
3091 {
3092         if (!handler || handler->state != CREATE) {
3093                 ErrPrint("Handler is invalid\n");
3094                 return -1.0f;
3095         }
3096
3097         if (!handler->common || handler->common->state != CREATE) {
3098                 ErrPrint("Handler is invalid\n");
3099                 return -1.0f;
3100         }
3101
3102         if (!handler->common->id) {
3103                 ErrPrint("Handler is not valid (%p)\n", handler);
3104                 return -1.0f;
3105         }
3106
3107         return handler->common->lb.priority;
3108 }
3109
3110 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
3111 {
3112         struct packet *packet;
3113         struct cb_info *cbinfo;
3114         int ret;
3115
3116         packet = packet_create("delete_cluster", "s", cluster);
3117         if (!packet) {
3118                 ErrPrint("Failed to build a param\n");
3119                 return LB_STATUS_ERROR_FAULT;
3120         }
3121
3122         cbinfo = create_cb_info(cb, data);
3123         if (!cbinfo) {
3124                 packet_destroy(packet);
3125                 return LB_STATUS_ERROR_FAULT;
3126         }
3127
3128         ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
3129         if (ret < 0) {
3130                 destroy_cb_info(cbinfo);
3131         }
3132
3133         return ret;
3134 }
3135
3136 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
3137 {
3138         struct packet *packet;
3139         struct cb_info *cbinfo;
3140         int ret;
3141
3142         packet = packet_create("delete_category", "ss", cluster, category);
3143         if (!packet) {
3144                 ErrPrint("Failed to build a param\n");
3145                 return LB_STATUS_ERROR_FAULT;
3146         }
3147
3148         cbinfo = create_cb_info(cb, data);
3149         if (!cbinfo) {
3150                 packet_destroy(packet);
3151                 return LB_STATUS_ERROR_FAULT;
3152         }
3153
3154         ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
3155         if (ret < 0) {
3156                 destroy_cb_info(cbinfo);
3157         }
3158
3159         return ret;
3160 }
3161
3162 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
3163 {
3164         if (!handler || handler->state != CREATE) {
3165                 ErrPrint("Handler is invalid\n");
3166                 return LB_TYPE_INVALID;
3167         }
3168
3169         if (!handler->common || handler->common->state != CREATE) {
3170                 ErrPrint("Handler is invalid\n");
3171                 return LB_TYPE_INVALID;
3172         }
3173
3174         if (!handler->common->id) {
3175                 ErrPrint("Handler is not valid\n");
3176                 return LB_TYPE_INVALID;
3177         }
3178
3179         switch (handler->common->lb.type) {
3180         case _LB_TYPE_FILE:
3181                 return LB_TYPE_IMAGE;
3182         case _LB_TYPE_BUFFER:
3183         case _LB_TYPE_SCRIPT:
3184                 {
3185                         const char *id;
3186                         id = fb_id(handler->common->lb.fb);
3187                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3188                                 return LB_TYPE_PIXMAP;
3189                         }
3190                 }
3191                 return LB_TYPE_BUFFER;
3192         case _LB_TYPE_TEXT:
3193                 return LB_TYPE_TEXT;
3194         default:
3195                 break;
3196         }
3197
3198         return LB_TYPE_INVALID;
3199 }
3200
3201 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
3202 {
3203         if (!handler || handler->state != CREATE) {
3204                 ErrPrint("Handler is invalid\n");
3205                 return PD_TYPE_INVALID;
3206         }
3207
3208         if (!handler->common || handler->common->state != CREATE) {
3209                 ErrPrint("Handler is invalid\n");
3210                 return PD_TYPE_INVALID;
3211         }
3212
3213         if (!handler->common->id) {
3214                 ErrPrint("Handler is not valid\n");
3215                 return PD_TYPE_INVALID;
3216         }
3217
3218         switch (handler->common->pd.type) {
3219         case _PD_TYPE_TEXT:
3220                 return PD_TYPE_TEXT;
3221         case _PD_TYPE_BUFFER:
3222         case _PD_TYPE_SCRIPT:
3223                 {
3224                         const char *id;
3225                         id = fb_id(handler->common->pd.fb);
3226                         if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3227                                 return PD_TYPE_PIXMAP;
3228                         }
3229                 }
3230                 return PD_TYPE_BUFFER;
3231         default:
3232                 break;
3233         }
3234
3235         return PD_TYPE_INVALID;
3236 }
3237
3238 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3239 {
3240         if (!handler) {
3241                 ErrPrint("Handler is NIL\n");
3242                 return LB_STATUS_ERROR_INVALID;
3243         }
3244
3245         if (handler->state != CREATE) {
3246                 ErrPrint("Handler is not valid\n");
3247                 return LB_STATUS_ERROR_INVALID;
3248         }
3249
3250         memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops));
3251         return LB_STATUS_SUCCESS;
3252 }
3253
3254 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3255 {
3256         if (!handler) {
3257                 ErrPrint("Handler is NIL\n");
3258                 return LB_STATUS_ERROR_INVALID;
3259         }
3260
3261         if (handler->state != CREATE) {
3262                 ErrPrint("Handler is not valid\n");
3263                 return LB_STATUS_ERROR_INVALID;
3264         }
3265
3266         memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops));
3267         return LB_STATUS_SUCCESS;
3268 }
3269
3270 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3271 {
3272         if (!handler || handler->state != CREATE) {
3273                 ErrPrint("Handler is invalid\n");
3274                 return LB_STATUS_ERROR_INVALID;
3275         }
3276
3277         if (!handler->common || handler->common->state != CREATE) {
3278                 ErrPrint("Handler is invalid\n");
3279                 return LB_STATUS_ERROR_INVALID;
3280         }
3281
3282         if (!handler->common->id) {
3283                 ErrPrint("Invalid handle\n");
3284                 return LB_STATUS_ERROR_INVALID;
3285         }
3286
3287         if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3288                 ErrPrint("Handler is not valid type\n");
3289                 return LB_STATUS_ERROR_INVALID;
3290         }
3291
3292         return lb_acquire_lb_pixmap(handler, cb, data);
3293 }
3294
3295 /*!
3296  * \note
3297  * Do not check the state of handler and common-handler.
3298  * If this function is used in the deleted callback,
3299  * the handler and common-handler's state would be DELETE
3300  * if this function check the state of handles,
3301  * user cannot release the pixmap.
3302  */
3303 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
3304 {
3305         struct packet *packet;
3306         const char *pkgname;
3307         const char *id;
3308
3309         if (pixmap == 0 /* || handler->state != CREATE */ ) {
3310                 ErrPrint("Handler is invalid [%d]\n", pixmap);
3311                 return LB_STATUS_ERROR_INVALID;
3312         }
3313
3314         if (!handler) {
3315                 /*!
3316                  * \note
3317                  * Even though the handler is NULL, we should send the release request to the master.
3318                  * Because the pixmap resource can be released after the handler is destroyed.
3319                  * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3320                  * In some cases, the pixmap can be released after the handler is deleted.
3321                  *
3322                  * Its implementation is up to the viewer app.
3323                  * But we cannot force it to use only with valid handler.
3324                  */
3325                 DbgPrint("Using NULL handler\n");
3326                 pkgname = NULL;
3327                 id = NULL;
3328                 /*!
3329                  * \note
3330                  * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3331                  */
3332         } else {
3333                 if (!handler->common /* || handler->common->state != CREATE */) {
3334                         ErrPrint("Handler is invalid\n");
3335                         return LB_STATUS_ERROR_INVALID;
3336                 }
3337
3338                 if (!handler->common->id) {
3339                         ErrPrint("Invalid handle\n");
3340                         return LB_STATUS_ERROR_INVALID;
3341                 }
3342
3343                 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3344                         ErrPrint("Handler is not valid type\n");
3345                         return LB_STATUS_ERROR_INVALID;
3346                 }
3347
3348                 pkgname = handler->common->pkgname;
3349                 id = handler->common->id;
3350         }
3351
3352         packet = packet_create_noack("lb_release_pixmap", "ssi", pkgname, id, pixmap);
3353         if (!packet) {
3354                 ErrPrint("Failed to build a param\n");
3355                 return LB_STATUS_ERROR_INVALID;
3356         }
3357
3358         return master_rpc_request_only(handler, packet);
3359 }
3360
3361 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3362 {
3363         if (!handler || handler->state != CREATE) {
3364                 ErrPrint("Handler is invalid\n");
3365                 return LB_STATUS_ERROR_INVALID;
3366         }
3367
3368         if (!handler->common || handler->common->state != CREATE) {
3369                 ErrPrint("Handler is invalid\n");
3370                 return LB_STATUS_ERROR_INVALID;
3371         }
3372
3373         if (!handler->common->id) {
3374                 ErrPrint("Invalid handle\n");
3375                 return LB_STATUS_ERROR_INVALID;
3376         }
3377
3378         if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3379                 ErrPrint("Handler is not valid type\n");
3380                 return LB_STATUS_ERROR_INVALID;
3381         }
3382
3383         return lb_acquire_pd_pixmap(handler, cb, data);
3384 }
3385
3386 EAPI int livebox_pd_pixmap(const struct livebox *handler)
3387 {
3388         const char *id;
3389         int pixmap = 0;
3390
3391         if (!handler || handler->state != CREATE) {
3392                 ErrPrint("Handler is invalid\n");
3393                 return 0;
3394         }
3395
3396         if (!handler->common || handler->common->state != CREATE) {
3397                 ErrPrint("Handler is invalid\n");
3398                 return 0;
3399         }
3400
3401         if (!handler->common->id) {
3402                 ErrPrint("Invalid handler\n");
3403                 return 0;
3404         }
3405
3406         if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3407                 ErrPrint("Invalid handler\n");
3408                 return 0;
3409         }
3410
3411         id = fb_id(handler->common->pd.fb);
3412         if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3413                 ErrPrint("PIXMAP Id is not valid\n");
3414                 return 0;
3415         }
3416
3417         return pixmap;
3418 }
3419
3420 EAPI int livebox_lb_pixmap(const struct livebox *handler)
3421 {
3422         const char *id;
3423         int pixmap = 0;
3424
3425         if (!handler || handler->state != CREATE) {
3426                 ErrPrint("Handler is invalid\n");
3427                 return 0;
3428         }
3429
3430         if (!handler->common || handler->common->state != CREATE) {
3431                 ErrPrint("Handler is invalid\n");
3432                 return 0;
3433         }
3434
3435         if (!handler->common->id) {
3436                 ErrPrint("Invalid handler\n");
3437                 return 0;
3438         }
3439
3440         if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3441                 ErrPrint("Invalid handler\n");
3442                 return 0;
3443         }
3444
3445         id = fb_id(handler->common->lb.fb);
3446         if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3447                 ErrPrint("PIXMAP Id is not valid\n");
3448                 return 0;
3449         }
3450
3451         return pixmap;
3452 }
3453
3454 /*!
3455  * \note
3456  * Do not check the state of handler and common-handler.
3457  * If this function is used in the deleted callback,
3458  * the handler and common-handler's state would be DELETE
3459  * if this function check the state of handles,
3460  * user cannot release the pixmap.
3461  */
3462 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
3463 {
3464         struct packet *packet;
3465         const char *pkgname;
3466         const char *id;
3467
3468         if (pixmap == 0 /* || handler->state != CREATE */) {
3469                 ErrPrint("Pixmap is invalid [%d]\n", pixmap);
3470                 return LB_STATUS_ERROR_INVALID;
3471         }
3472
3473         if (!handler) {
3474                 /*!
3475                  * \note
3476                  * Even though the handler is NULL, we should send the release request to the master.
3477                  * Because the pixmap resource can be released after the handler is destroyed.
3478                  * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3479                  * In some cases, the pixmap can be released after the handler is deleted.
3480                  *
3481                  * Its implementation is up to the viewer app.
3482                  * But we cannot force it to use only with valid handler.
3483                  */
3484                 DbgPrint("Using NULL handler\n");
3485                 pkgname = NULL;
3486                 id = NULL;
3487                 /*!
3488                  * \note
3489                  * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3490                  */
3491         } else {
3492                 if (!handler->common /* || handler-common->state != CREATE */) {
3493                         ErrPrint("Handler is invalid\n");
3494                         return LB_STATUS_ERROR_INVALID;
3495                 }
3496
3497                 if (!handler->common->id) {
3498                         ErrPrint("Invalid handle\n");
3499                         return LB_STATUS_ERROR_INVALID;
3500                 }
3501
3502                 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3503                         ErrPrint("Handler is not valid type\n");
3504                         return LB_STATUS_ERROR_INVALID;
3505                 }
3506
3507                 pkgname = handler->common->pkgname;
3508                 id = handler->common->id;
3509         }
3510
3511         packet = packet_create_noack("pd_release_pixmap", "ssi", pkgname, id, pixmap);
3512         if (!packet) {
3513                 ErrPrint("Failed to build a param\n");
3514                 return LB_STATUS_ERROR_FAULT;
3515         }
3516
3517         return master_rpc_request_only(handler, packet);
3518 }
3519
3520 EAPI void *livebox_acquire_fb(struct livebox *handler)
3521 {
3522         if (!handler || handler->state != CREATE) {
3523                 ErrPrint("Handler is invalid\n");
3524                 return NULL;
3525         }
3526
3527         if (!handler->common || handler->common->state != CREATE) {
3528                 ErrPrint("Handler is invalid\n");
3529                 return NULL;
3530         }
3531
3532         if (!handler->common->id) {
3533                 ErrPrint("Invalid handle\n");
3534                 return NULL;
3535         }
3536
3537         if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3538                 ErrPrint("Handler is not valid type\n");
3539                 return NULL;
3540         }
3541
3542         return fb_acquire_buffer(handler->common->lb.fb);
3543 }
3544
3545 EAPI int livebox_release_fb(void *buffer)
3546 {
3547         return fb_release_buffer(buffer);
3548 }
3549
3550 EAPI int livebox_fb_refcnt(void *buffer)
3551 {
3552         return fb_refcnt(buffer);
3553 }
3554
3555 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
3556 {
3557         if (!handler || handler->state != CREATE) {
3558                 ErrPrint("Handler is invalid\n");
3559                 return NULL;
3560         }
3561
3562         if (!handler->common || handler->common->state != CREATE) {
3563                 ErrPrint("Handler is invalid\n");
3564                 return NULL;
3565         }
3566
3567         if (!handler->common->id) {
3568                 ErrPrint("Invalid handler\n");
3569                 return NULL;
3570         }
3571
3572         if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3573                 ErrPrint("Handler is not valid type\n");
3574                 return NULL;
3575         }
3576
3577         return fb_acquire_buffer(handler->common->pd.fb);
3578 }
3579
3580 EAPI int livebox_release_pdfb(void *buffer)
3581 {
3582         return fb_release_buffer(buffer);
3583 }
3584
3585 EAPI int livebox_pdfb_refcnt(void *buffer)
3586 {
3587         return fb_refcnt(buffer);
3588 }
3589
3590 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
3591 {
3592         if (!handler || handler->state != CREATE) {
3593                 ErrPrint("Handler is invalid\n");
3594                 return LB_STATUS_ERROR_INVALID;
3595         }
3596
3597         if (!handler->common || handler->common->state != CREATE) {
3598                 ErrPrint("Handler is invalid\n");
3599                 return LB_STATUS_ERROR_INVALID;
3600         }
3601
3602         if (!handler->common->id) {
3603                 ErrPrint("Invalid handler\n");
3604                 return LB_STATUS_ERROR_INVALID;
3605         }
3606
3607         return fb_size(handler->common->pd.fb);
3608 }
3609
3610 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
3611 {
3612         if (!handler || handler->state != CREATE) {
3613                 ErrPrint("Handler is invalid\n");
3614                 return LB_STATUS_ERROR_INVALID;
3615         }
3616
3617         if (!handler->common || handler->common->state != CREATE) {
3618                 ErrPrint("Handler is invalid\n");
3619                 return LB_STATUS_ERROR_INVALID;
3620         }
3621
3622         if (!handler->common->id) {
3623                 ErrPrint("Invalid handler\n");
3624                 return LB_STATUS_ERROR_INVALID;
3625         }
3626
3627         return fb_size(handler->common->lb.fb);
3628 }
3629
3630 EAPI int livebox_is_user(struct livebox *handler)
3631 {
3632         if (!handler || handler->state != CREATE) {
3633                 ErrPrint("Handler is invalid\n");
3634                 return LB_STATUS_ERROR_INVALID;
3635         }
3636
3637         if (!handler->common || handler->common->state != CREATE) {
3638                 ErrPrint("Handler is invalid\n");
3639                 return LB_STATUS_ERROR_INVALID;
3640         }
3641
3642         if (!handler->common->id) {
3643                 ErrPrint("Invalid handler\n");
3644                 return LB_STATUS_ERROR_INVALID;
3645         }
3646
3647         return handler->common->is_user;
3648 }
3649
3650 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
3651 {
3652         struct packet *packet;
3653         int ret;
3654
3655         if (!handler || handler->state != CREATE) {
3656                 ErrPrint("Handler is invalid\n");
3657                 return LB_STATUS_ERROR_INVALID;
3658         }
3659
3660         if (!handler->common || handler->common->state != CREATE) {
3661                 ErrPrint("Handler is invalid\n");
3662                 return LB_STATUS_ERROR_INVALID;
3663         }
3664
3665         if (!handler->common->id) {
3666                 ErrPrint("Invalid handler\n");
3667                 return LB_STATUS_ERROR_INVALID;
3668         }
3669
3670         if (handler->common->request.pinup) {
3671                 ErrPrint("Previous pinup request is not finished\n");
3672                 return LB_STATUS_ERROR_BUSY;
3673         }
3674
3675         if (handler->common->is_pinned_up == flag) {
3676                 DbgPrint("No changes\n");
3677                 return LB_STATUS_ERROR_ALREADY;
3678         }
3679
3680         packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
3681         if (!packet) {
3682                 ErrPrint("Failed to build a param\n");
3683                 return LB_STATUS_ERROR_FAULT;
3684         }
3685
3686         if (!cb) {
3687                 cb = default_pinup_cb;
3688         }
3689
3690         ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
3691         if (ret == (int)LB_STATUS_SUCCESS) {
3692                 handler->cbs.pinup.cb = cb;
3693                 handler->cbs.pinup.data = data;
3694                 handler->common->request.pinup = 1;
3695         }
3696
3697         return ret;
3698 }
3699
3700 EAPI int livebox_is_pinned_up(struct livebox *handler)
3701 {
3702         if (!handler || handler->state != CREATE) {
3703                 ErrPrint("Handler is invalid\n");
3704                 return LB_STATUS_ERROR_INVALID;
3705         }
3706
3707         if (!handler->common || handler->common->state != CREATE) {
3708                 ErrPrint("Handler is invalid\n");
3709                 return LB_STATUS_ERROR_INVALID;
3710         }
3711
3712         if (!handler->common->id) {
3713                 ErrPrint("Invalid handler\n");
3714                 return LB_STATUS_ERROR_INVALID;
3715         }
3716
3717         return handler->common->is_pinned_up;
3718 }
3719
3720 EAPI int livebox_has_pinup(struct livebox *handler)
3721 {
3722         if (!handler || handler->state != CREATE) {
3723                 ErrPrint("Handler is invalid\n");
3724                 return LB_STATUS_ERROR_INVALID;
3725         }
3726
3727         if (!handler->common || handler->common->state != CREATE) {
3728                 ErrPrint("Handler is invalid\n");
3729                 return LB_STATUS_ERROR_INVALID;
3730         }
3731
3732         if (!handler->common->id) {
3733                 ErrPrint("Invalid handler\n");
3734                 return LB_STATUS_ERROR_INVALID;
3735         }
3736
3737         return handler->common->lb.pinup_supported;
3738 }
3739
3740 EAPI int livebox_set_data(struct livebox *handler, void *data)
3741 {
3742         if (!handler) {
3743                 ErrPrint("Handler is NIL\n");
3744                 return LB_STATUS_ERROR_INVALID;
3745         }
3746
3747         if (handler->state != CREATE) {
3748                 ErrPrint("Handler is invalid\n");
3749                 return LB_STATUS_ERROR_INVALID;
3750         }
3751
3752         handler->data = data;
3753         return LB_STATUS_SUCCESS;
3754 }
3755
3756 EAPI void *livebox_get_data(struct livebox *handler)
3757 {
3758         if (!handler) {
3759                 ErrPrint("Handler is NIL\n");
3760                 return NULL;
3761         }
3762
3763         if (handler->state != CREATE) {
3764                 ErrPrint("Handler is invalid\n");
3765                 return NULL;
3766         }
3767
3768         return handler->data;
3769 }
3770
3771 EAPI int livebox_is_exists(const char *pkgname)
3772 {
3773         char *lb;
3774
3775         lb = lb_pkgname(pkgname);
3776         if (lb) {
3777                 free(lb);
3778                 return 1;
3779         }
3780
3781         return 0;
3782 }
3783
3784 EAPI const char *livebox_content(struct livebox *handler)
3785 {
3786         if (!handler || handler->state != CREATE) {
3787                 ErrPrint("Handler is invalid\n");
3788                 return NULL;
3789         }
3790
3791         if (!handler->common || handler->common->state != CREATE) {
3792                 ErrPrint("Invalid handle\n");
3793                 return NULL;
3794         }
3795
3796         return handler->common->content;
3797 }
3798
3799 EAPI const char *livebox_category_title(struct livebox *handler)
3800 {
3801         if (!handler || handler->state != CREATE) {
3802                 ErrPrint("Handler is invalid\n");
3803                 return NULL;
3804         }
3805
3806         if (!handler->common || handler->common->state != CREATE) {
3807                 ErrPrint("Invalid handle\n");
3808                 return NULL;
3809         }
3810
3811         return handler->common->title;
3812 }
3813
3814 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)
3815 {
3816         struct packet *packet;
3817         struct cb_info *cbinfo;
3818         int ret;
3819
3820         if (!handler || handler->state != CREATE) {
3821                 ErrPrint("Handler is invalid\n");
3822                 return LB_STATUS_ERROR_INVALID;
3823         }
3824
3825         if (!handler->common || handler->common->state != CREATE) {
3826                 ErrPrint("Handler is invalid\n");
3827                 return LB_STATUS_ERROR_INVALID;
3828         }
3829
3830         if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
3831                 ErrPrint("Handler is not valid\n");
3832                 return LB_STATUS_ERROR_INVALID;
3833         }
3834
3835         if (!emission) {
3836                 emission = "";
3837         }
3838
3839         if (!source) {
3840                 source = "";
3841         }
3842
3843         packet = packet_create("text_signal", "ssssdddd",
3844                                 handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
3845         if (!packet) {
3846                 ErrPrint("Failed to build a param\n");
3847                 return LB_STATUS_ERROR_FAULT;
3848         }
3849
3850         cbinfo = create_cb_info(cb, data);
3851         if (!cbinfo) {
3852                 packet_destroy(packet);
3853                 return LB_STATUS_ERROR_FAULT;
3854         }
3855
3856         ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
3857         if (ret < 0) {
3858                 destroy_cb_info(cbinfo);
3859         }
3860
3861         return ret;
3862 }
3863
3864 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
3865 {
3866         struct packet *packet;
3867
3868         /*!
3869          * \todo
3870          * Validate the group info using DB
3871          * If the group info is not valid, do not send this request
3872          */
3873
3874         packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
3875         if (!packet) {
3876                 ErrPrint("Failed to create a packet\n");
3877                 return LB_STATUS_ERROR_FAULT;
3878         }
3879
3880         return master_rpc_request_only(NULL, packet);
3881 }
3882
3883 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
3884 {
3885         struct packet *packet;
3886
3887         /*!
3888          * \todo
3889          * Validate the group info using DB
3890          * If the group info is not valid, do not send this request
3891          * AND Check the subscribed or not too
3892          */
3893
3894         packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
3895         if (!packet) {
3896                 ErrPrint("Failed to create a packet\n");
3897                 return LB_STATUS_ERROR_FAULT;
3898         }
3899
3900         return master_rpc_request_only(NULL, packet);
3901 }
3902
3903 EAPI int livebox_refresh(struct livebox *handler, int force)
3904 {
3905         struct packet *packet;
3906
3907         if (!handler || handler->state != CREATE) {
3908                 ErrPrint("Handler is invalid\n");
3909                 return LB_STATUS_ERROR_INVALID;
3910         }
3911
3912         if (!handler->common || handler->common->state != CREATE) {
3913                 ErrPrint("Handler is not valid\n");
3914                 return LB_STATUS_ERROR_INVALID;
3915         }
3916
3917         if (!handler->common->id) {
3918                 ErrPrint("Handler is not valid\n");
3919                 return LB_STATUS_ERROR_INVALID;
3920         }
3921
3922         packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
3923         if (!packet) {
3924                 ErrPrint("Failed to create a packet\n");
3925                 return LB_STATUS_ERROR_FAULT;
3926         }
3927
3928         return master_rpc_request_only(handler, packet);
3929 }
3930
3931 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
3932 {
3933         struct packet *packet;
3934
3935         if (!cluster || !category) {
3936                 ErrPrint("Invalid argument\n");
3937                 return LB_STATUS_ERROR_INVALID;
3938         }
3939
3940         packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
3941         if (!packet) {
3942                 ErrPrint("Failed to create a packet\n");
3943                 return LB_STATUS_ERROR_FAULT;
3944         }
3945
3946         return master_rpc_request_only(NULL, packet);
3947 }
3948
3949 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
3950 {
3951         int old_state;
3952         int ret;
3953
3954         if (!handler || handler->state != CREATE) {
3955                 ErrPrint("Handler is invalid\n");
3956                 return LB_STATUS_ERROR_INVALID;
3957         }
3958
3959         if (!handler->common || handler->common->state != CREATE) {
3960                 ErrPrint("Handler is not valid\n");
3961                 return LB_STATUS_ERROR_INVALID;
3962         }
3963
3964         if (!handler->common->id) {
3965                 ErrPrint("Handler is not valid\n");
3966                 return LB_STATUS_ERROR_INVALID;
3967         }
3968
3969         if (!handler->common->is_user) {
3970                 /* System cluster livebox cannot be changed its visible states */
3971                 if (state == LB_HIDE_WITH_PAUSE) {
3972                         ErrPrint("CA Livebox is not able to change the visibility\n");
3973                         return LB_STATUS_ERROR_PERMISSION;
3974                 }
3975         }
3976
3977         if (handler->visible == state) {
3978                 DbgPrint("%s has no changes\n", handler->common->pkgname);
3979                 return LB_STATUS_ERROR_ALREADY;
3980         }
3981
3982         old_state = handler->visible;
3983         handler->visible = state;
3984
3985         ret = lb_set_visibility(handler, state);
3986         if (ret < 0) {
3987                 handler->visible = old_state;
3988         }
3989
3990         return ret;
3991 }
3992
3993 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
3994 {
3995         if (!handler || handler->state != CREATE) {
3996                 ErrPrint("Handler is invalid\n");
3997                 return LB_VISIBLE_ERROR;
3998         }
3999
4000         if (!handler->common || handler->common->state != CREATE) {
4001                 ErrPrint("Handler is not valid\n");
4002                 return LB_VISIBLE_ERROR;
4003         }
4004
4005         if (!handler->common->id) {
4006                 ErrPrint("Handler is not valid\n");
4007                 return LB_VISIBLE_ERROR;
4008         }
4009
4010         return handler->visible;
4011 }
4012
4013 int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
4014 {
4015         void *pc = NULL;
4016         void *ps = NULL;
4017
4018         if (cluster) {
4019                 pc = strdup(cluster);
4020                 if (!pc) {
4021                         ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
4022                         return LB_STATUS_ERROR_MEMORY;
4023                 }
4024         }
4025
4026         if (category) {
4027                 ps = strdup(category);
4028                 if (!ps) {
4029                         ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
4030                         free(pc);
4031                         return LB_STATUS_ERROR_MEMORY;
4032                 }
4033         }
4034
4035         if (common->cluster) {
4036                 free(common->cluster);
4037         }
4038
4039         if (common->category) {
4040                 free(common->category);
4041         }
4042
4043         common->cluster = pc;
4044         common->category = ps;
4045
4046         return LB_STATUS_SUCCESS;
4047 }
4048
4049 void lb_set_size(struct livebox_common *common, int w, int h)
4050 {
4051         int size_type;
4052
4053         common->lb.width = w;
4054         common->lb.height = h;
4055
4056         size_type = livebox_service_size_type(w, h);
4057         if (size_type != LB_SIZE_TYPE_UNKNOWN) {
4058                 common->lb.mouse_event = livebox_service_mouse_event(common->pkgname, size_type);
4059         }
4060 }
4061
4062 void lb_set_update_mode(struct livebox_common *common, int active_mode)
4063 {
4064         common->is_active_update = active_mode;
4065 }
4066
4067 void lb_set_pdsize(struct livebox_common *common, int w, int h)
4068 {
4069         common->pd.width = w;
4070         common->pd.height = h;
4071 }
4072
4073 void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
4074 {
4075         common->pd.default_width = w;
4076         common->pd.default_height = h;
4077 }
4078
4079 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
4080 {
4081         struct dlist *l;
4082         struct dlist *n;
4083         struct fault_info *info;
4084
4085         s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4086
4087         dlist_foreach_safe(s_info.fault_list, l, n, info) {
4088                 if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
4089                         info->is_deleted = 1;
4090                 }
4091
4092                 if (info->is_deleted) {
4093                         s_info.fault_list = dlist_remove(s_info.fault_list, l);
4094                         free(info);
4095                 }
4096         }
4097
4098         s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4099 }
4100
4101 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
4102 {
4103         struct dlist *l;
4104         struct dlist *n;
4105         struct event_info *info;
4106
4107         if (event == LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
4108                 if (handler->visible != LB_SHOW) {
4109                         DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
4110                         handler->paused_updating++;
4111                         return;
4112                 } else {
4113                         handler->paused_updating = 0;
4114                 }
4115         }
4116
4117         s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4118
4119         dlist_foreach_safe(s_info.event_list, l, n, info) {
4120                 if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
4121                         DbgPrint("Event handler returns EXIT_FAILURE\n");
4122                         info->is_deleted = 1;
4123                 }
4124
4125                 if (info->is_deleted) {
4126                         s_info.event_list = dlist_remove(s_info.event_list, l);
4127                         free(info);
4128                 }
4129         }
4130
4131         s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4132 }
4133
4134 struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
4135 {
4136         struct dlist *l;
4137         struct livebox_common *common;
4138
4139         dlist_foreach(s_info.livebox_common_list, l, common) {
4140                 if (!common->id) {
4141                         continue;
4142                 }
4143
4144                 if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
4145                         return common;
4146                 }
4147         }
4148
4149         return NULL;
4150 }
4151
4152 struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
4153 {
4154         struct dlist *l;
4155         struct livebox_common *common;
4156
4157         dlist_foreach(s_info.livebox_common_list, l, common) {
4158                 if (common->timestamp == timestamp) {
4159                         return common;
4160                 }
4161         }
4162
4163         return NULL;
4164 }
4165
4166 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
4167 {
4168         struct livebox *handler;
4169
4170         handler = calloc(1, sizeof(*handler));
4171         if (!handler) {
4172                 ErrPrint("Failed to create a new livebox\n");
4173                 return NULL;
4174         }
4175
4176         handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
4177         if (!handler->common) {
4178                 ErrPrint("Heap: %s\n", strerror(errno));
4179                 free(handler);
4180                 return NULL;
4181         }
4182
4183         lb_common_ref(handler->common, handler);
4184         lb_set_id(handler->common, id);
4185         handler->common->timestamp = timestamp;
4186         handler->common->state = CREATE;
4187         handler->visible = LB_SHOW;
4188         s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
4189
4190         return lb_ref(handler);
4191 }
4192
4193 int lb_delete_all(void)
4194 {
4195         struct dlist *l;
4196         struct dlist *n;
4197         struct livebox *handler;
4198
4199         dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
4200                 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
4201                 lb_unref(handler, 1);
4202         }
4203
4204         return LB_STATUS_SUCCESS;
4205 }
4206
4207 int lb_set_content(struct livebox_common *common, const char *content)
4208 {
4209         char *pc = NULL;
4210
4211         if (content) {
4212                 pc = strdup(content);
4213                 if (!pc) {
4214                         ErrPrint("heap: %s [%s]\n", strerror(errno), content);
4215                         return LB_STATUS_ERROR_MEMORY;
4216                 }
4217         }
4218
4219         free(common->content);
4220         common->content = pc;
4221         return LB_STATUS_SUCCESS;
4222 }
4223
4224 int lb_set_title(struct livebox_common *common, const char *title)
4225 {
4226         char *pt = NULL;
4227
4228         if (title) {
4229                 pt = strdup(title);
4230                 if (!pt) {
4231                         ErrPrint("heap: %s [%s]\n", strerror(errno), title);
4232                         return LB_STATUS_ERROR_MEMORY;
4233                 }
4234         }
4235
4236         free(common->title);
4237         common->title = pt;
4238         return LB_STATUS_SUCCESS;
4239 }
4240
4241 void lb_set_size_list(struct livebox_common *common, int size_list)
4242 {
4243         common->lb.size_list = size_list;
4244 }
4245
4246 void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
4247 {
4248         char *pa = NULL;
4249
4250         if (!auto_launch || !strlen(auto_launch)) {
4251                 return;
4252         }
4253
4254         pa = strdup(auto_launch);
4255         if (!pa) {
4256                 ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
4257                 return;
4258         }
4259
4260         free(common->lb.auto_launch);
4261         common->lb.auto_launch = pa;
4262 }
4263
4264 void lb_set_priority(struct livebox_common *common, double priority)
4265 {
4266         common->lb.priority = priority;
4267 }
4268
4269 void lb_set_id(struct livebox_common *common, const char *id)
4270 {
4271         char *pi = NULL;
4272
4273         if (id) {
4274                 pi = strdup(id);
4275                 if (!pi) {
4276                         ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
4277                         return;
4278                 }
4279         }
4280
4281         free(common->id);
4282         common->id = pi;
4283 }
4284
4285 void lb_set_filename(struct livebox_common *common, const char *filename)
4286 {
4287         if (common->filename) {
4288                 if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
4289                         if (common->filename[0] && unlink(common->filename) < 0) {
4290                                 ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
4291                         }
4292                 }
4293
4294                 free(common->filename);
4295         }
4296
4297         common->filename = strdup(filename);
4298         if (!common->filename) {
4299                 ErrPrint("Heap: %s\n", strerror(errno));
4300         }
4301 }
4302
4303 void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
4304 {
4305         char *_icon = NULL;
4306         char *_name = NULL;
4307
4308         if (icon && strlen(icon)) {
4309                 _icon = strdup(icon);
4310                 if (!_icon) {
4311                         ErrPrint("Heap: %s\n", strerror(errno));
4312                 }
4313         }
4314
4315         if (name && strlen(name)) {
4316                 _name = strdup(name);
4317                 if (!_name) {
4318                         ErrPrint("Heap: %s\n", strerror(errno));
4319                 }
4320         }
4321
4322         free(common->alt.icon);
4323         common->alt.icon = _icon;
4324
4325         free(common->alt.name);
4326         common->alt.name = _name;
4327 }
4328
4329 int lb_set_lb_fb(struct livebox_common *common, const char *filename)
4330 {
4331         struct fb_info *fb;
4332
4333         if (!common) {
4334                 return LB_STATUS_ERROR_INVALID;
4335         }
4336
4337         fb = common->lb.fb;
4338         if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
4339                 return LB_STATUS_SUCCESS;
4340         }
4341
4342         common->lb.fb = NULL;
4343
4344         if (!filename || filename[0] == '\0') {
4345                 if (fb) {
4346                         fb_destroy(fb);
4347                 }
4348                 return LB_STATUS_SUCCESS;
4349         }
4350
4351         common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
4352         if (!common->lb.fb) {
4353                 ErrPrint("Faield to create a FB\n");
4354                 if (fb) {
4355                         fb_destroy(fb);
4356                 }
4357                 return LB_STATUS_ERROR_FAULT;
4358         }
4359
4360         if (fb) {
4361                 fb_destroy(fb);
4362         }
4363
4364         return LB_STATUS_SUCCESS;
4365 }
4366
4367 int lb_set_pd_fb(struct livebox_common *common, const char *filename)
4368 {
4369         struct fb_info *fb;
4370
4371         if (!common || common->state != CREATE) {
4372                 return LB_STATUS_ERROR_INVALID;
4373         }
4374
4375         fb = common->pd.fb;
4376         if (fb && !strcmp(fb_id(fb), filename)) {
4377                 /* BUFFER is not changed, just update the content */
4378                 return LB_STATUS_ERROR_EXIST;
4379         }
4380         common->pd.fb = NULL;
4381
4382         if (!filename || filename[0] == '\0') {
4383                 if (fb) {
4384                         fb_destroy(fb);
4385                 }
4386                 return LB_STATUS_SUCCESS;
4387         }
4388
4389         common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
4390         if (!common->pd.fb) {
4391                 ErrPrint("Failed to create a FB\n");
4392                 if (fb) {
4393                         fb_destroy(fb);
4394                 }
4395                 return LB_STATUS_ERROR_FAULT;
4396         }
4397
4398         if (fb) {
4399                 fb_destroy(fb);
4400         }
4401         return LB_STATUS_SUCCESS;
4402 }
4403
4404 struct fb_info *lb_get_lb_fb(struct livebox_common *common)
4405 {
4406         return common->lb.fb;
4407 }
4408
4409 struct fb_info *lb_get_pd_fb(struct livebox_common *common)
4410 {
4411         return common->pd.fb;
4412 }
4413
4414 void lb_set_user(struct livebox_common *common, int user)
4415 {
4416         common->is_user = user;
4417 }
4418
4419 void lb_set_pinup(struct livebox_common *common, int pinup_supported)
4420 {
4421         common->lb.pinup_supported = pinup_supported;
4422 }
4423
4424 void lb_set_text_lb(struct livebox_common *common)
4425 {
4426         common->lb.type = _LB_TYPE_TEXT;
4427 }
4428
4429 void lb_set_text_pd(struct livebox_common *common)
4430 {
4431         common->pd.type = _PD_TYPE_TEXT;
4432 }
4433
4434 int lb_text_lb(struct livebox_common *common)
4435 {
4436         return common->lb.type == _LB_TYPE_TEXT;
4437 }
4438
4439 int lb_text_pd(struct livebox_common *common)
4440 {
4441         return common->pd.type == _PD_TYPE_TEXT;
4442 }
4443
4444 void lb_set_period(struct livebox_common *common, double period)
4445 {
4446         common->lb.period = period;
4447 }
4448
4449 struct livebox *lb_ref(struct livebox *handler)
4450 {
4451         if (!handler) {
4452                 return NULL;
4453         }
4454
4455         handler->refcnt++;
4456         return handler;
4457 }
4458
4459 struct livebox *lb_unref(struct livebox *handler, int destroy_common)
4460 {
4461         if (!handler) {
4462                 return NULL;
4463         }
4464
4465         handler->refcnt--;
4466         if (handler->refcnt > 0) {
4467                 return handler;
4468         }
4469
4470         if (handler->cbs.created.cb) {
4471                 handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
4472                 handler->cbs.created.cb = NULL;
4473                 handler->cbs.created.data = NULL;
4474         }
4475
4476         if (handler->cbs.deleted.cb) {
4477                 handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
4478                 handler->cbs.deleted.cb = NULL;
4479                 handler->cbs.deleted.data = NULL;
4480         }
4481
4482         if (handler->cbs.pinup.cb) {
4483                 handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
4484                 handler->cbs.pinup.cb = NULL;
4485                 handler->cbs.pinup.data = NULL;
4486         }
4487
4488         if (handler->cbs.group_changed.cb) {
4489                 handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
4490                 handler->cbs.group_changed.cb = NULL;
4491                 handler->cbs.group_changed.data = NULL;
4492         }
4493
4494         if (handler->cbs.period_changed.cb) {
4495                 handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
4496                 handler->cbs.period_changed.cb = NULL;
4497                 handler->cbs.period_changed.data = NULL;
4498         }
4499
4500         if (handler->cbs.size_changed.cb) {
4501                 handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
4502                 handler->cbs.size_changed.cb = NULL;
4503                 handler->cbs.size_changed.data = NULL;
4504         }
4505
4506         if (handler->cbs.pd_created.cb) {
4507                 handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
4508                 handler->cbs.pd_created.cb = NULL;
4509                 handler->cbs.pd_created.data = NULL;
4510         }
4511
4512         if (handler->cbs.pd_destroyed.cb) {
4513                 handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
4514                 handler->cbs.pd_destroyed.cb = NULL;
4515                 handler->cbs.pd_destroyed.data = NULL;
4516         }
4517
4518         if (handler->cbs.update_mode.cb) {
4519                 handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
4520                 handler->cbs.update_mode.cb = NULL;
4521                 handler->cbs.update_mode.data = NULL;
4522         }
4523
4524         if (handler->cbs.access_event.cb) {
4525                 handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
4526                 handler->cbs.access_event.cb = NULL;
4527                 handler->cbs.access_event.data = NULL;
4528         }
4529
4530         if (handler->cbs.key_event.cb) {
4531                 handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
4532                 handler->cbs.key_event.cb = NULL;
4533                 handler->cbs.key_event.data = NULL;
4534         }
4535
4536         dlist_remove_data(s_info.livebox_list, handler);
4537
4538         handler->state = DESTROYED;
4539         if (lb_common_unref(handler->common, handler) == 0) {
4540                 if (destroy_common) {
4541                         /*!
4542                          * \note
4543                          * Lock file should be deleted after all callbacks are processed.
4544                          */
4545                         lb_destroy_lock_file(handler->common, 0);
4546                         lb_destroy_common_handle(handler->common);
4547                 }
4548         }
4549         free(handler);
4550         DbgPrint("Handler is released\n");
4551         return NULL;
4552 }
4553
4554 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
4555 {
4556         struct packet *packet;
4557         struct cb_info *cbinfo;
4558         int ret;
4559
4560         if (handler->common->request.deleted) {
4561                 ErrPrint("Already in-progress\n");
4562                 if (cb) {
4563                         cb(handler, LB_STATUS_SUCCESS, data);
4564                 }
4565                 return LB_STATUS_ERROR_BUSY;
4566         }
4567
4568         if (!cb) {
4569                 cb = default_delete_cb;
4570         }
4571
4572         packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp);
4573         if (!packet) {
4574                 ErrPrint("Failed to build a param\n");
4575                 if (cb) {
4576                         cb(handler, LB_STATUS_ERROR_FAULT, data);
4577                 }
4578
4579                 return LB_STATUS_ERROR_FAULT;
4580         }
4581
4582         cbinfo = create_cb_info(cb, data);
4583         if (!cbinfo) {
4584                 packet_destroy(packet);
4585                 ErrPrint("Failed to create cbinfo\n");
4586                 if (cb) {
4587                         cb(handler, LB_STATUS_ERROR_FAULT, data);
4588                 }
4589
4590                 return LB_STATUS_ERROR_FAULT;
4591         }
4592
4593         ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
4594         if (ret < 0) {
4595                 /*!
4596                  * Packet is destroyed by master_rpc_async_request.
4597                  */
4598                 destroy_cb_info(cbinfo);
4599
4600                 if (cb) {
4601                         cb(handler, LB_STATUS_ERROR_FAULT, data);
4602                 }
4603         } else {
4604                 handler->common->request.deleted = 1;
4605         }
4606
4607         return ret;
4608 }
4609
4610 EAPI int livebox_client_paused(void)
4611 {
4612         struct packet *packet;
4613
4614         packet = packet_create_noack("client_paused", "d", util_timestamp());
4615         if (!packet) {
4616                 ErrPrint("Failed to create a pause packet\n");
4617                 return LB_STATUS_ERROR_FAULT;
4618         }
4619
4620         return master_rpc_request_only(NULL, packet);
4621 }
4622
4623 EAPI int livebox_client_resumed(void)
4624 {
4625         struct packet *packet;
4626
4627         packet = packet_create_noack("client_resumed", "d", util_timestamp());
4628         if (!packet) {
4629                 ErrPrint("Failed to create a resume packet\n");
4630                 return LB_STATUS_ERROR_FAULT;
4631         }
4632
4633         return master_rpc_request_only(NULL, packet);
4634 }
4635
4636 EAPI int livebox_sync_lb_fb(struct livebox *handler)
4637 {
4638         if (!handler || handler->state != CREATE) {
4639                 ErrPrint("Invalid handle\n");
4640                 return LB_STATUS_ERROR_INVALID;
4641         }
4642
4643         if (!handler->common || handler->common->state != CREATE) {
4644                 ErrPrint("Invalid handle\n");
4645                 return LB_STATUS_ERROR_INVALID;
4646         }
4647
4648         if (!handler->common->id) {
4649                 return LB_STATUS_ERROR_INVALID;
4650         }
4651
4652         return lb_sync_lb_fb(handler->common);
4653 }
4654
4655 int lb_sync_lb_fb(struct livebox_common *common)
4656 {
4657         int ret;
4658
4659         if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
4660                 (void)do_fb_lock(common->lb.lock_fd);
4661                 ret = fb_sync(lb_get_lb_fb(common));
4662                 (void)do_fb_unlock(common->lb.lock_fd);
4663         } else {
4664                 ret = fb_sync(lb_get_lb_fb(common));
4665         }
4666
4667         return ret;
4668 }
4669
4670 int lb_sync_pd_fb(struct livebox_common *common)
4671 {
4672         int ret;
4673
4674         if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
4675                 (void)do_fb_lock(common->pd.lock_fd);
4676                 ret = fb_sync(lb_get_pd_fb(common));
4677                 (void)do_fb_unlock(common->pd.lock_fd);
4678         } else {
4679                 ret = fb_sync(lb_get_pd_fb(common));
4680         }
4681
4682         return ret;
4683 }
4684
4685 EAPI int livebox_sync_pd_fb(struct livebox *handler)
4686 {
4687         if (!handler || handler->state != CREATE) {
4688                 ErrPrint("Invalid handle\n");
4689                 return LB_STATUS_ERROR_INVALID;
4690         }
4691
4692         if (!handler->common || handler->common->state != CREATE) {
4693                 ErrPrint("Invalid handle\n");
4694                 return LB_STATUS_ERROR_INVALID;
4695         }
4696
4697         if (!handler->common->id) {
4698                 ErrPrint("Invalid handle\n");
4699                 return LB_STATUS_ERROR_INVALID;
4700         }
4701
4702         return lb_sync_pd_fb(handler->common);
4703 }
4704
4705 EAPI const char *livebox_alt_icon(struct livebox *handler)
4706 {
4707         if (!handler || handler->state != CREATE) {
4708                 ErrPrint("Handler is not valid[%p]\n", handler);
4709                 return NULL;
4710         }
4711
4712         if (!handler->common || handler->common->state != CREATE) {
4713                 ErrPrint("Handler is not valid\n");
4714                 return NULL;
4715         }
4716
4717         return handler->common->alt.icon;
4718 }
4719
4720 EAPI const char *livebox_alt_name(struct livebox *handler)
4721 {
4722         if (!handler || handler->state != CREATE) {
4723                 ErrPrint("Handler is not valid[%p]\n", handler);
4724                 return NULL;
4725         }
4726
4727         if (!handler->common || handler->common->state != CREATE) {
4728                 ErrPrint("Handler is not valid\n");
4729                 return NULL;
4730         }
4731
4732         return handler->common->alt.name;
4733 }
4734
4735 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
4736 {
4737         int ret = LB_STATUS_SUCCESS;
4738         int fd;
4739
4740         if (!handler || handler->state != CREATE) {
4741                 ErrPrint("Handler is not valid[%p]\n", handler);
4742                 return LB_STATUS_ERROR_INVALID;
4743         }
4744
4745         if (!handler->common || handler->common->state != CREATE) {
4746                 ErrPrint("Handler is not valid\n");
4747                 return LB_STATUS_ERROR_INVALID;
4748         }
4749
4750         if (!handler->common->id) {
4751                 ErrPrint("Handler is not valid[%p]\n", handler);
4752                 return LB_STATUS_ERROR_INVALID;
4753         }
4754
4755         if (is_pd) {
4756                 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4757                         DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4758                         return LB_STATUS_ERROR_INVALID;
4759                 }
4760
4761                 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4762                         return LB_STATUS_SUCCESS;
4763                 }
4764
4765                 fd = handler->common->pd.lock_fd;
4766         } else {
4767                 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4768                         DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4769                         return LB_STATUS_ERROR_INVALID;
4770                 }
4771
4772                 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4773                         return LB_STATUS_SUCCESS;
4774                 }
4775
4776                 fd = handler->common->lb.lock_fd;
4777         }
4778
4779         ret = do_fb_lock(fd);
4780
4781         return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4782 }
4783
4784 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
4785 {
4786         int ret = LB_STATUS_SUCCESS;
4787         int fd;
4788
4789         if (!handler || handler->state != CREATE) {
4790                 ErrPrint("Invalid handle\n");
4791                 return LB_STATUS_ERROR_INVALID;
4792         }
4793
4794         if (!handler->common || handler->common->state != CREATE) {
4795                 ErrPrint("Invalid handle\n");
4796                 return LB_STATUS_ERROR_INVALID;
4797         }
4798
4799         if (!handler->common->id) {
4800                 ErrPrint("Handler is not valid[%p]\n", handler);
4801                 return LB_STATUS_ERROR_INVALID;
4802         }
4803
4804         if (is_pd) {
4805                 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4806                         DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4807                         return LB_STATUS_ERROR_INVALID;
4808                 }
4809
4810                 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4811                         return LB_STATUS_SUCCESS;
4812                 }
4813
4814                 fd = handler->common->pd.lock_fd;
4815         } else {
4816                 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4817                         DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4818                         return LB_STATUS_ERROR_INVALID;
4819                 }
4820
4821                 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4822                         return LB_STATUS_SUCCESS;
4823                 }
4824
4825                 fd = handler->common->lb.lock_fd;
4826         }
4827
4828         ret = do_fb_unlock(fd);
4829
4830         return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4831 }
4832
4833 EAPI int livebox_set_option(enum livebox_option_type option, int state)
4834 {
4835         int ret = LB_STATUS_SUCCESS;
4836
4837         switch (option) {
4838         case LB_OPTION_MANUAL_SYNC:
4839                 conf_set_manual_sync(state);
4840                 break;
4841         case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4842                 conf_set_frame_drop_for_resizing(state);
4843                 break;
4844         case LB_OPTION_SHARED_CONTENT:
4845                 conf_set_shared_content(state);
4846                 break;
4847         default:
4848                 ret = LB_STATUS_ERROR_INVALID;
4849                 break;
4850         }
4851
4852         return ret;
4853 }
4854
4855 EAPI int livebox_option(enum livebox_option_type option)
4856 {
4857         int ret;
4858
4859         switch (option) {
4860         case LB_OPTION_MANUAL_SYNC:
4861                 ret = conf_manual_sync();
4862                 break;
4863         case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4864                 ret = conf_frame_drop_for_resizing();
4865                 break;
4866         case LB_OPTION_SHARED_CONTENT:
4867                 ret = conf_shared_content();
4868                 break;
4869         default:
4870                 ret = LB_STATUS_ERROR_INVALID;
4871                 break;
4872         }
4873
4874         return ret;
4875 }
4876
4877 EAPI int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data)
4878 {
4879         s_info.launch.handler = launch_handler;
4880         s_info.launch.data = data;
4881
4882         return LB_STATUS_SUCCESS;
4883 }
4884
4885 /* End of a file */