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