2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
25 #include <sys/types.h>
31 #include <com-core_packet.h>
33 #include <livebox-service.h>
34 #include <livebox-errno.h>
39 #include "livebox_internal.h"
42 #include "master_rpc.h"
46 #define EAPI __attribute__((visibility("default")))
53 INFO_STATE_CALLBACK_IN_IDLE = 0x00,
54 INFO_STATE_CALLBACK_IN_PROCESSING = 0x01,
58 struct dlist *livebox_list;
59 struct dlist *livebox_common_list;
61 struct dlist *event_list;
62 struct dlist *fault_list;
65 int prevent_overwrite;
66 enum event_state event_state;
67 enum event_state fault_state;
69 struct dlist *job_list;
75 .prevent_overwrite = 0,
76 .event_state = INFO_STATE_CALLBACK_IN_IDLE,
77 .fault_state = INFO_STATE_CALLBACK_IN_IDLE,
89 int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data);
95 int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data);
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);
102 static inline void default_create_cb(struct livebox *handler, int ret, void *data)
104 DbgPrint("Default created event handler: %d\n", ret);
107 static inline void default_delete_cb(struct livebox *handler, int ret, void *data)
109 DbgPrint("Default deleted event handler: %d\n", ret);
112 static inline void default_pinup_cb(struct livebox *handler, int ret, void *data)
114 DbgPrint("Default pinup event handler: %d\n", ret);
117 static inline void default_group_changed_cb(struct livebox *handler, int ret, void *data)
119 DbgPrint("Default group changed event handler: %d\n", ret);
122 static inline void default_period_changed_cb(struct livebox *handler, int ret, void *data)
124 DbgPrint("Default period changed event handler: %d\n", ret);
127 static inline void default_pd_created_cb(struct livebox *handler, int ret, void *data)
129 DbgPrint("Default PD created event handler: %d\n", ret);
132 static inline void default_pd_destroyed_cb(struct livebox *handler, int ret, void *data)
134 DbgPrint("Default PD destroyed event handler: %d\n", ret);
137 static inline void default_lb_size_changed_cb(struct livebox *handler, int ret, void *data)
139 DbgPrint("Default LB size changed event handler: %d\n", ret);
142 static inline void default_update_mode_cb(struct livebox *handler, int ret, void *data)
144 DbgPrint("Default update mode set event handler: %d\n", ret);
147 static inline void default_access_event_cb(struct livebox *handler, int ret, void *data)
149 DbgPrint("Default access event handler: %d\n", ret);
152 static inline void default_key_event_cb(struct livebox *handler, int ret, void *data)
154 DbgPrint("Default key event handler: %d\n", ret);
157 static inline __attribute__((always_inline)) struct cb_info *create_cb_info(ret_cb_t cb, void *data)
159 struct cb_info *info;
161 info = malloc(sizeof(*info));
163 ErrPrint("Heap: %s\n", strerror(errno));
172 static inline void destroy_cb_info(struct cb_info *info)
177 static int do_fb_lock(int fd)
182 flock.l_type = F_RDLCK;
183 flock.l_whence = SEEK_SET;
186 flock.l_pid = getpid();
189 ret = fcntl(fd, F_SETLKW, &flock);
192 ErrPrint("fcntl: %s\n", strerror(errno));
194 } while (ret == EINTR);
199 static int do_fb_unlock(int fd)
204 flock.l_type = F_UNLCK;
205 flock.l_whence = SEEK_SET;
208 flock.l_pid = getpid();
211 ret = fcntl(fd, F_SETLKW, &flock);
214 ErrPrint("fcntl: %s\n", strerror(errno));
216 } while (ret == EINTR);
221 int lb_destroy_lock_file(struct livebox_common *common, int is_pd)
224 if (!common->pd.lock) {
225 return LB_STATUS_ERROR_INVALID;
228 if (close(common->pd.lock_fd) < 0) {
229 ErrPrint("close: %s\n", strerror(errno));
231 common->pd.lock_fd = -1;
233 if (unlink(common->pd.lock) < 0) {
234 ErrPrint("unlink: %s\n", strerror(errno));
237 free(common->pd.lock);
238 common->pd.lock = NULL;
240 if (!common->lb.lock) {
241 return LB_STATUS_ERROR_INVALID;
244 if (close(common->lb.lock_fd) < 0) {
245 ErrPrint("close: %s\n", strerror(errno));
247 common->lb.lock_fd = -1;
249 if (unlink(common->lb.lock) < 0) {
250 ErrPrint("unlink: %s\n", strerror(errno));
253 free(common->lb.lock);
254 common->lb.lock = NULL;
257 return LB_STATUS_SUCCESS;
260 int lb_create_lock_file(struct livebox_common *common, int is_pd)
265 len = strlen(common->id);
266 file = malloc(len + 20);
268 ErrPrint("Heap: %s\n", strerror(errno));
269 return LB_STATUS_ERROR_MEMORY;
272 snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(common->id), is_pd ? "pd" : "lb");
275 common->pd.lock_fd = open(file, O_RDONLY);
276 if (common->pd.lock_fd < 0) {
277 ErrPrint("open: %s\n", strerror(errno));
279 return LB_STATUS_ERROR_IO;
282 common->pd.lock = file;
284 common->lb.lock_fd = open(file, O_RDONLY);
285 if (common->lb.lock_fd < 0) {
286 ErrPrint("open: %s\n", strerror(errno));
288 return LB_STATUS_ERROR_IO;
291 common->lb.lock = file;
294 return LB_STATUS_SUCCESS;
297 static void update_mode_cb(struct livebox *handler, const struct packet *result, void *data)
302 ret = LB_STATUS_ERROR_FAULT;
304 } else if (packet_get(result, "i", &ret) != 1) {
305 ErrPrint("Invalid argument\n");
306 ret = LB_STATUS_ERROR_INVALID;
311 ErrPrint("Resize request is failed: %d\n", ret);
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;
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);
329 static void resize_cb(struct livebox *handler, const struct packet *result, void *data)
334 ret = LB_STATUS_ERROR_FAULT;
336 } else if (packet_get(result, "i", &ret) != 1) {
337 ErrPrint("Invalid argument\n");
338 ret = LB_STATUS_ERROR_INVALID;
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.
348 * So the user can only get the resized value(result) from the first update event
349 * after this request.
352 ErrPrint("Resize request is failed: %d\n", ret);
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;
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);
370 static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data)
374 struct cb_info *info = data;
379 destroy_cb_info(info);
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;
389 cb(handler, ret, cbdata);
394 static void set_group_ret_cb(struct livebox *handler, const struct packet *result, void *data)
399 ret = LB_STATUS_ERROR_FAULT;
401 } else if (packet_get(result, "i", &ret) != 1) {
402 ErrPrint("Invalid argument\n");
403 ret = LB_STATUS_ERROR_INVALID;
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;
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);
425 static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data)
430 ret = LB_STATUS_ERROR_FAULT;
432 } else if (packet_get(result, "i", &ret) != 1) {
433 ErrPrint("Invalid argument\n");
434 ret = LB_STATUS_ERROR_INVALID;
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;
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);
456 static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data)
458 struct cb_info *info = data;
465 destroy_cb_info(info);
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;
476 handler->cbs.deleted.cb = cb;
477 handler->cbs.deleted.data = cbdata;
479 cb(handler, ret, cbdata);
484 * Do not call the deleted callback from here.
485 * master will send the "deleted" event.
486 * Then invoke this callback.
488 * if (handler->cbs.deleted.cb)
489 * handler->cbs.deleted.cb(handler, ret, handler->cbs.deleted.data);
493 static void new_ret_cb(struct livebox *handler, const struct packet *result, void *data)
496 struct cb_info *info = data;
502 destroy_cb_info(info);
505 ret = LB_STATUS_ERROR_FAULT;
506 } else if (packet_get(result, "i", &ret) != 1) {
507 ret = LB_STATUS_ERROR_INVALID;
511 handler->cbs.created.cb = cb;
512 handler->cbs.created.data = cbdata;
516 * Don't go anymore ;)
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.
526 cb(handler, ret, cbdata);
529 lb_unref(handler, 1);
532 static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data)
537 ret = LB_STATUS_ERROR_FAULT;
539 } else if (packet_get(result, "i", &ret) != 1) {
540 ret = LB_STATUS_ERROR_INVALID;
545 ErrPrint("Failed to create a PD[%d]\n", ret);
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;
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);
563 static void activated_cb(struct livebox *handler, const struct packet *result, void *data)
566 struct cb_info *info = data;
569 const char *pkgname = "";
573 destroy_cb_info(info);
576 ret = LB_STATUS_ERROR_FAULT;
577 } else if (packet_get(result, "is", &ret, &pkgname) != 2) {
578 ret = LB_STATUS_ERROR_INVALID;
582 cb(handler, ret, cbdata);
586 static void pd_destroy_cb(struct livebox *handler, const struct packet *result, void *data)
591 struct cb_info *info = data;
595 destroy_cb_info(info);
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;
605 if (ret == LB_STATUS_SUCCESS) {
606 handler->cbs.pd_destroyed.cb = cb;
607 handler->cbs.pd_destroyed.data = cbdata;
609 handler->common->is_pd_created = 0;
610 handler->common->request.pd_destroyed = 0;
613 cb(handler, ret, cbdata);
618 static void delete_cluster_cb(struct livebox *handler, const struct packet *result, void *data)
620 struct cb_info *info = data;
627 destroy_cb_info(info);
630 ret = LB_STATUS_ERROR_FAULT;
631 } else if (packet_get(result, "i", &ret) != 1) {
632 ret = LB_STATUS_ERROR_INVALID;
636 cb(handler, ret, cbdata);
640 static void delete_category_cb(struct livebox *handler, const struct packet *result, void *data)
642 struct cb_info *info = data;
649 destroy_cb_info(info);
652 ret = LB_STATUS_ERROR_FAULT;
653 } else if (packet_get(result, "i", &ret) != 1) {
654 ret = LB_STATUS_ERROR_INVALID;
658 cb(handler, ret, cbdata);
662 static int lb_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
664 struct packet *packet;
665 struct cb_info *cbinfo;
669 id = fb_id(handler->common->lb.fb);
670 if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
671 return LB_STATUS_ERROR_INVALID;
674 packet = packet_create("lb_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
676 ErrPrint("Failed to build a param\n");
677 return LB_STATUS_ERROR_FAULT;
680 cbinfo = create_cb_info(cb, data);
682 packet_destroy(packet);
683 return LB_STATUS_ERROR_FAULT;
686 ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo);
688 destroy_cb_info(cbinfo);
694 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
697 int ret = LB_STATUS_ERROR_INVALID;
700 struct cb_info *info = data;
704 destroy_cb_info(info);
707 pixmap = 0; /* PIXMAP 0 means error */
708 } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
712 if (ret == LB_STATUS_ERROR_BUSY) {
713 ret = lb_acquire_lb_pixmap(handler, cb, cbdata);
714 DbgPrint("Busy, Try again: %d\n", ret);
716 } else if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
718 cb(handler, pixmap, cbdata);
721 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
722 lb_unref(handler, 1);
725 cb(handler, pixmap, cbdata);
730 static int lb_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
732 struct packet *packet;
733 struct cb_info *cbinfo;
737 id = fb_id(handler->common->pd.fb);
738 if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
739 return LB_STATUS_ERROR_INVALID;
742 packet = packet_create("pd_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
744 ErrPrint("Failed to build a param\n");
745 return LB_STATUS_ERROR_FAULT;
748 cbinfo = create_cb_info(cb, data);
750 packet_destroy(packet);
751 return LB_STATUS_ERROR_FAULT;
754 ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo);
758 * Packet will be destroyed by master_rpc_async_request
760 destroy_cb_info(cbinfo);
766 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
772 struct cb_info *info = data;
776 destroy_cb_info(info);
779 pixmap = 0; /* PIXMAP 0 means error */
780 ret = LB_STATUS_ERROR_FAULT;
781 } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
783 ret = LB_STATUS_ERROR_INVALID;
786 if (ret == LB_STATUS_ERROR_BUSY) {
787 ret = lb_acquire_pd_pixmap(handler, cb, cbdata);
788 DbgPrint("Busy, Try again: %d\n", ret);
790 } else if (ret == LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
792 cb(handler, pixmap, cbdata);
794 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
795 lb_unref(handler, 1);
798 DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap);
799 cb(handler, pixmap, cbdata);
804 static void pinup_done_cb(struct livebox *handler, const struct packet *result, void *data)
809 ret = LB_STATUS_ERROR_FAULT;
811 } else if (packet_get(result, "i", &ret) != 1) {
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;
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);
833 static void key_ret_cb(struct livebox *handler, const struct packet *result, void *data)
838 ret = LB_STATUS_ERROR_FAULT;
842 if (packet_get(result, "i", &ret) != 1) {
843 ret = LB_STATUS_ERROR_INVALID;
847 if (ret != LB_STATUS_SUCCESS) {
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;
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);
864 static void access_ret_cb(struct livebox *handler, const struct packet *result, void *data)
869 ret = LB_STATUS_ERROR_FAULT;
873 if (packet_get(result, "i", &ret) != 1) {
874 ret = LB_STATUS_ERROR_INVALID;
878 if (ret != LB_STATUS_SUCCESS) {
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;
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);
896 static int send_access_event(struct livebox *handler, const char *event, int x, int y)
898 struct packet *packet;
901 timestamp = util_timestamp();
903 packet = packet_create(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
905 ErrPrint("Failed to build packet\n");
906 return LB_STATUS_ERROR_FAULT;
909 return master_rpc_async_request(handler, packet, 0, access_ret_cb, NULL);
912 static int send_key_event(struct livebox *handler, const char *event, unsigned int keycode)
914 struct packet *packet;
917 timestamp = util_timestamp();
918 packet = packet_create(event, "ssdi", handler->common->pkgname, handler->common->id, timestamp, keycode);
920 ErrPrint("Failed to build packet\n");
921 return LB_STATUS_ERROR_FAULT;
924 return master_rpc_async_request(handler, packet, 0, key_ret_cb, NULL);
927 static int send_mouse_event(struct livebox *handler, const char *event, int x, int y)
929 struct packet *packet;
932 timestamp = util_timestamp();
933 packet = packet_create_noack(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
935 ErrPrint("Failed to build param\n");
936 return LB_STATUS_ERROR_FAULT;
939 return master_rpc_request_only(handler, packet);
942 static void initialize_livebox(void *disp, int use_thread)
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");
952 livebox_service_init();
955 client_init(use_thread);
960 EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread)
962 if (s_info.init_count > 0) {
964 return LB_STATUS_SUCCESS;
969 * Some application doesn't want to use the environment value.
970 * So set them using arguments.
972 s_info.prevent_overwrite = prevent_overwrite;
973 conf_set_event_filter(event_filter);
975 initialize_livebox(disp, use_thread);
976 return LB_STATUS_SUCCESS;
979 EAPI int livebox_init(void *disp)
983 if (s_info.init_count > 0) {
985 return LB_STATUS_SUCCESS;
988 env = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE");
989 if (env && !strcasecmp(env, "true")) {
990 s_info.prevent_overwrite = 1;
993 env = getenv("PROVIDER_EVENT_FILTER");
996 if (sscanf(env, "%lf", &event_filter) == 1) {
997 conf_set_event_filter(event_filter);
1001 initialize_livebox(disp, 0);
1002 return LB_STATUS_SUCCESS;
1005 EAPI int livebox_fini(void)
1007 if (s_info.init_count <= 0) {
1008 ErrPrint("Doesn't initialized\n");
1009 return LB_STATUS_ERROR_INVALID;
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;
1020 livebox_service_fini();
1021 return LB_STATUS_SUCCESS;
1024 static inline char *lb_pkgname(const char *pkgname)
1028 lb = livebox_service_pkgname(pkgname);
1030 if (util_validate_livebox_package(pkgname) == 0) {
1031 return strdup(pkgname);
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)
1041 struct livebox_common *common;
1043 if (!conf_shared_content()) {
1045 * Shared content option is turnned off.
1050 dlist_foreach(s_info.livebox_common_list, l, common) {
1051 if (common->state != CREATE) {
1055 if (strcmp(common->pkgname, pkgname)) {
1059 if (strcmp(common->cluster, cluster)) {
1060 DbgPrint("Cluster mismatched\n");
1064 if (strcmp(common->category, category)) {
1065 DbgPrint("Category mismatched\n");
1069 if (common->content && content) {
1070 if (strcmp(common->content, content)) {
1071 DbgPrint("%s Content ([%s] <> [%s])\n", common->pkgname, common->content, content);
1080 * We assumes "" (ZERO length string) to NULL
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);
1090 if (common->request.size_changed) {
1091 DbgPrint("Changing size\n");
1094 * Do not re-use resizing instance.
1095 * We will not use predicted size.
1100 if (common->request.created) {
1101 DbgPrint("Creating now but re-use it (%s)\n", common->pkgname);
1104 if (common->lb.width != w || common->lb.height != h) {
1105 DbgPrint("Size mismatched\n");
1109 DbgPrint("common handle is found: %p\n", common);
1117 * Just wrapping the livebox_add_with_size function.
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)
1121 return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data);
1124 static gboolean job_execute_cb(void *data)
1126 struct job_item *item;
1129 l = dlist_nth(s_info.job_list, 0);
1131 s_info.job_timer = 0;
1135 item = dlist_data(l);
1136 s_info.job_list = dlist_remove(s_info.job_list, l);
1139 item->cb(item->handle, item->ret, item->data);
1140 lb_unref(item->handle, 1);
1147 static int job_add(struct livebox *handle, ret_cb_t job_cb, int ret, void *data)
1149 struct job_item *item;
1152 ErrPrint("Invalid argument\n");
1153 return LB_STATUS_ERROR_INVALID;
1156 item = malloc(sizeof(*item));
1158 ErrPrint("Heap: %s\n", strerror(errno));
1159 return LB_STATUS_ERROR_MEMORY;
1162 item->handle = lb_ref(handle);
1167 s_info.job_list = dlist_append(s_info.job_list, item);
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");
1176 return LB_STATUS_SUCCESS;
1179 static int create_real_instance(struct livebox *handler, ret_cb_t cb, void *data)
1181 struct cb_info *cbinfo;
1182 struct packet *packet;
1183 struct livebox_common *common;
1186 common = handler->common;
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);
1193 ErrPrint("Failed to create a new packet\n");
1194 return LB_STATUS_ERROR_FAULT;
1197 cbinfo = create_cb_info(cb, data);
1199 ErrPrint("Failed to create a cbinfo\n");
1200 packet_destroy(packet);
1201 return LB_STATUS_ERROR_MEMORY;
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.
1209 ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo);
1211 ErrPrint("Failed to send a new packet\n");
1212 destroy_cb_info(cbinfo);
1213 return LB_STATUS_ERROR_FAULT;
1215 handler->common->request.created = 1;
1216 return LB_STATUS_SUCCESS;
1219 static void create_cb(struct livebox *handle, int ret, void *data)
1221 struct cb_info *cbinfo = data;
1224 cbinfo->cb(handle, ret, cbinfo->data);
1227 destroy_cb_info(cbinfo);
1231 * Forcely generate "updated" event
1233 lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
1236 static int create_fake_instance(struct livebox *handler, ret_cb_t cb, void *data)
1238 struct cb_info *cbinfo;
1240 cbinfo = create_cb_info(cb, data);
1242 ErrPrint("Failed to create a cbinfo\n");
1243 return LB_STATUS_ERROR_MEMORY;
1246 if (job_add(handler, create_cb, LB_STATUS_SUCCESS, cbinfo) != LB_STATUS_SUCCESS) {
1247 destroy_cb_info(cbinfo);
1250 return LB_STATUS_SUCCESS;
1253 struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category)
1255 struct livebox_common *common;
1257 common = calloc(1, sizeof(*common));
1259 ErrPrint("Heap: %s\n", strerror(errno));
1263 common->pkgname = strdup(pkgname);
1264 if (!common->pkgname) {
1269 common->cluster = strdup(cluster);
1270 if (!common->cluster) {
1271 ErrPrint("Error: %s\n", strerror(errno));
1272 free(common->pkgname);
1277 common->category = strdup(category);
1278 if (!common->category) {
1279 ErrPrint("Error: %s\n", strerror(errno));
1280 free(common->cluster);
1281 free(common->pkgname);
1286 /* Data provider will set this */
1287 common->lb.type = _LB_TYPE_FILE;
1288 common->pd.type = _PD_TYPE_SCRIPT;
1290 /* Used for handling the mouse event on a box */
1291 common->lb.mouse_event = livebox_service_mouse_event(common->pkgname);
1293 /* Cluster infomration is not determined yet */
1294 common->nr_of_sizes = 0x01;
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;
1304 common->state = CREATE;
1305 common->visible = LB_SHOW;
1307 s_info.livebox_common_list = dlist_append(s_info.livebox_common_list, common);
1311 int lb_destroy_common_handle(struct livebox_common *common)
1313 dlist_remove_data(s_info.livebox_common_list, common);
1315 common->state = DESTROYED;
1316 free(common->cluster);
1317 free(common->category);
1319 free(common->pkgname);
1320 free(common->filename);
1321 free(common->lb.auto_launch);
1322 free(common->alt.icon);
1323 free(common->alt.name);
1325 if (common->lb.fb) {
1326 fb_destroy(common->lb.fb);
1327 common->lb.fb = NULL;
1330 if (common->pd.fb) {
1331 fb_destroy(common->pd.fb);
1332 common->pd.fb = NULL;
1338 int lb_common_ref(struct livebox_common *common, struct livebox *handle)
1340 common->livebox_list = dlist_append(common->livebox_list, handle);
1343 return common->refcnt;
1346 int lb_common_unref(struct livebox_common *common, struct livebox *handle)
1349 dlist_remove_data(common->livebox_list, handle);
1350 refcnt = --common->refcnt;
1355 static void refresh_for_paused_updating_cb(struct livebox *handle, int ret, void *data)
1357 if (handle->paused_updating == 0) {
1358 DbgPrint("Paused updates are cleared\n");
1362 DbgPrint("Pending updates are found\n");
1363 lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
1366 static int lb_set_visibility(struct livebox *handler, enum livebox_visible_state state)
1368 struct packet *packet;
1369 int need_to_add_job = 0;
1372 if (handler->common->visible != LB_SHOW && state == LB_SHOW) {
1373 need_to_add_job = !!handler->paused_updating;
1374 } else if (handler->common->visible == LB_SHOW && state != LB_SHOW) {
1376 struct livebox *item;
1378 dlist_foreach(handler->common->livebox_list, l, item) {
1379 if (item->visible == LB_SHOW) {
1380 DbgPrint("%s visibility is not changed\n", handler->common->pkgname);
1381 return LB_STATUS_SUCCESS;
1384 } else if (handler->common->visible == LB_SHOW && state == LB_SHOW && handler->paused_updating) {
1385 if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1386 ErrPrint("Unable to add a new job for refreshing box\n");
1389 return LB_STATUS_SUCCESS;
1393 * No need to send this to the master
1395 return LB_STATUS_SUCCESS;
1398 packet = packet_create_noack("change,visibility", "ssi", handler->common->pkgname, handler->common->id, (int)state);
1400 ErrPrint("Failed to create a packet\n");
1401 return LB_STATUS_ERROR_FAULT;
1404 ret = master_rpc_request_only(handler, packet);
1405 if (ret == LB_STATUS_SUCCESS) {
1406 DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state);
1407 handler->common->visible = state;
1409 if (need_to_add_job) {
1410 if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1411 ErrPrint("Unable to add a new job for refreshing box\n");
1419 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)
1422 struct livebox *handler;
1426 if (!pkgname || !cluster || !category) {
1427 ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
1428 pkgname, cluster, category);
1432 lbid = lb_pkgname(pkgname);
1434 ErrPrint("Invalid package: %s\n", pkgname);
1438 if (livebox_service_is_enabled(lbid) == 0) {
1439 DbgPrint("Livebox [%s](%s) is disabled package\n", lbid, pkgname);
1444 if (type != LB_SIZE_TYPE_UNKNOWN) {
1445 (void)livebox_service_get_size(type, &w, &h);
1448 handler = calloc(1, sizeof(*handler));
1450 ErrPrint("Error: %s\n", strerror(errno));
1456 cb = default_create_cb;
1459 handler->common = find_sharable_common_handle(lbid, content, w, h, cluster, category);
1460 if (!handler->common) {
1461 handler->common = lb_create_common_handle(handler, lbid, cluster, category);
1463 if (!handler->common) {
1464 ErrPrint("Failed to find common handle\n");
1469 if (!content || !strlen(content)) {
1473 * I know the content should not be modified. use it temporarly without "const"
1475 pc = livebox_service_content(handler->common->pkgname);
1476 lb_set_content(handler->common, pc);
1479 lb_set_content(handler->common, content);
1482 lb_set_period(handler->common, period);
1483 lb_set_size(handler->common, w, h);
1484 lb_common_ref(handler->common, handler);
1486 if (create_real_instance(handler, cb, data) < 0) {
1487 if (lb_common_unref(handler->common, handler) == 0) {
1491 lb_destroy_common_handle(handler->common);
1492 handler->common = NULL;
1500 lb_common_ref(handler->common, handler);
1502 if (handler->common->request.created) {
1504 * If a box is in creating, wait its result too
1506 handler->cbs.created.cb = cb;
1507 handler->cbs.created.data = data;
1510 * or fire the fake created_event
1512 if (create_fake_instance(handler, cb, data) < 0) {
1513 if (lb_common_unref(handler->common, handler) == 0) {
1517 lb_destroy_common_handle(handler->common);
1525 handler->visible = LB_SHOW;
1526 handler->state = CREATE;
1527 handler = lb_ref(handler);
1529 if (handler->common->visible != LB_SHOW) {
1530 lb_set_visibility(handler, LB_SHOW);
1536 EAPI double livebox_period(struct livebox *handler)
1538 if (!handler || handler->state != CREATE) {
1539 ErrPrint("Handler is not valid\n");
1543 if (!handler->common || handler->common->state != CREATE) {
1544 ErrPrint("Invalid handle\n");
1548 if (!handler->common->id) {
1549 ErrPrint("Hnalder is not valid\n");
1553 return handler->common->lb.period;
1556 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
1558 struct packet *packet;
1561 if (!handler || handler->state != CREATE) {
1562 ErrPrint("Handler is not valid\n");
1563 return LB_STATUS_ERROR_INVALID;
1566 if (!handler->common || handler->common->state != CREATE) {
1567 ErrPrint("Invalid handle\n");
1568 return LB_STATUS_ERROR_INVALID;
1571 if (!handler->common->id) {
1572 ErrPrint("Handler is not valid\n");
1573 return LB_STATUS_ERROR_INVALID;
1576 if (handler->common->request.period_changed) {
1577 ErrPrint("Previous request for changing period is not finished\n");
1578 return LB_STATUS_ERROR_BUSY;
1581 if (!handler->common->is_user) {
1582 ErrPrint("CA Livebox is not able to change the period\n");
1583 return LB_STATUS_ERROR_PERMISSION;
1586 if (handler->common->lb.period == period) {
1587 DbgPrint("No changes\n");
1588 return LB_STATUS_ERROR_ALREADY;
1591 packet = packet_create("set_period", "ssd", handler->common->pkgname, handler->common->id, period);
1593 ErrPrint("Failed to build a packet %s\n", handler->common->pkgname);
1594 return LB_STATUS_ERROR_FAULT;
1598 cb = default_period_changed_cb;
1601 ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
1602 if (ret == LB_STATUS_SUCCESS) {
1603 handler->cbs.period_changed.cb = cb;
1604 handler->cbs.period_changed.data = data;
1605 handler->common->request.period_changed = 1;
1611 static void lb_update_visibility(struct livebox_common *old_common)
1614 struct livebox *item;
1617 dlist_foreach(old_common->livebox_list, l, item) {
1618 if (item->visible == LB_SHOW) {
1626 l = dlist_nth(old_common->livebox_list, 0);
1627 item = dlist_data(l);
1630 lb_set_visibility(item, LB_HIDE_WITH_PAUSE);
1632 ErrPrint("Unable to get the valid handle from common handler\n");
1635 lb_set_visibility(item, LB_SHOW);
1641 * The second parameter should be the "return value",
1642 * But in this case, we will use it for "type of deleting instance".
1644 static void job_del_cb(struct livebox *handle, int type, void *data)
1646 struct cb_info *cbinfo = data;
1649 if (handle->visible == LB_SHOW) {
1650 lb_update_visibility(handle->common);
1654 data = cbinfo->data;
1655 destroy_cb_info(cbinfo);
1657 if (handle->common->state != CREATE) {
1658 DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt);
1660 cb(handle, LB_STATUS_SUCCESS, data);
1666 if (handle->common->refcnt == 1) {
1667 handle->common->delete_type = type;
1668 handle->common->state = DELETE;
1670 if (!handle->common->id) {
1673 * The id is not determined yet.
1674 * It means a user didn't receive created event yet.
1675 * Then just stop to delete procedure from here.
1676 * Because the "created" event handle will release this.
1677 * By the way, if the user adds any callback for getting return status of this,
1681 cb(handle, LB_STATUS_SUCCESS, data);
1685 DbgPrint("Send delete request\n");
1686 lb_send_delete(handle, type, cb, data);
1689 cb(handle, LB_STATUS_SUCCESS, data);
1692 DbgPrint("Before unref: %d\n", handle->common->refcnt);
1693 lb_unref(handle, 1);
1697 EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data)
1699 struct cb_info *cbinfo;
1702 ErrPrint("Handler is NIL\n");
1703 return LB_STATUS_ERROR_INVALID;
1706 if (handler->state != CREATE) {
1707 ErrPrint("Handler is already deleted\n");
1708 return LB_STATUS_ERROR_INVALID;
1711 handler->state = DELETE;
1713 cbinfo = create_cb_info(cb, data);
1715 ErrPrint("Failed to create a cbinfo\n");
1716 return LB_STATUS_ERROR_MEMORY;
1719 if (job_add(handler, job_del_cb, type, cbinfo) != LB_STATUS_SUCCESS) {
1720 ErrPrint("Failed to add a new job\n");
1721 destroy_cb_info(cbinfo);
1722 return LB_STATUS_ERROR_FAULT;
1725 return LB_STATUS_SUCCESS;
1728 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
1730 return livebox_del_NEW(handler, LB_DELETE_PERMANENTLY, cb, data);
1733 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
1735 struct fault_info *info;
1738 return LB_STATUS_ERROR_INVALID;
1741 info = malloc(sizeof(*info));
1743 ErrPrint("Heap: %s\n", strerror(errno));
1744 return LB_STATUS_ERROR_MEMORY;
1748 info->user_data = data;
1749 info->is_deleted = 0;
1751 s_info.fault_list = dlist_append(s_info.fault_list, info);
1752 return LB_STATUS_SUCCESS;
1755 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
1757 struct fault_info *info;
1760 dlist_foreach(s_info.fault_list, l, info) {
1761 if (info->handler == cb) {
1764 data = info->user_data;
1766 if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1767 info->is_deleted = 1;
1769 s_info.fault_list = dlist_remove(s_info.fault_list, l);
1780 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
1782 struct event_info *info;
1785 ErrPrint("Invalid argument cb is nil\n");
1786 return LB_STATUS_ERROR_INVALID;
1789 info = malloc(sizeof(*info));
1791 ErrPrint("Heap: %s\n", strerror(errno));
1792 return LB_STATUS_ERROR_MEMORY;
1796 info->user_data = data;
1797 info->is_deleted = 0;
1799 s_info.event_list = dlist_append(s_info.event_list, info);
1800 return LB_STATUS_SUCCESS;
1803 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
1805 struct event_info *info;
1808 dlist_foreach(s_info.event_list, l, info) {
1809 if (info->handler == cb) {
1812 data = info->user_data;
1814 if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1815 info->is_deleted = 1;
1817 s_info.event_list = dlist_remove(s_info.event_list, l);
1828 EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data)
1830 struct packet *packet;
1833 if (!handler || handler->state != CREATE) {
1834 ErrPrint("Handler is Invalid\n");
1835 return LB_STATUS_ERROR_INVALID;
1838 if (!handler->common || handler->common->state != CREATE) {
1839 ErrPrint("Handler is Invalid\n");
1840 return LB_STATUS_ERROR_INVALID;
1843 if (!handler->common->id) {
1844 ErrPrint("Handler is Invalid\n");
1845 return LB_STATUS_ERROR_INVALID;
1848 if (handler->common->request.update_mode) {
1849 ErrPrint("Previous update_mode cb is not finished yet\n");
1850 return LB_STATUS_ERROR_BUSY;
1853 if (handler->common->is_active_update == active_update) {
1854 return LB_STATUS_ERROR_ALREADY;
1857 if (!handler->common->is_user) {
1858 return LB_STATUS_ERROR_PERMISSION;
1861 packet = packet_create("update_mode", "ssi", handler->common->pkgname, handler->common->id, active_update);
1863 return LB_STATUS_ERROR_FAULT;
1867 cb = default_update_mode_cb;
1870 ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL);
1871 if (ret == LB_STATUS_SUCCESS) {
1872 handler->cbs.update_mode.cb = cb;
1873 handler->cbs.update_mode.data = data;
1874 handler->common->request.update_mode = 1;
1880 EAPI int livebox_is_active_update(struct livebox *handler)
1882 if (!handler || handler->state != CREATE) {
1883 ErrPrint("Handler is Invalid\n");
1884 return LB_STATUS_ERROR_INVALID;
1887 if (!handler->common || handler->common->state != CREATE) {
1888 ErrPrint("Handler is Invalid\n");
1889 return LB_STATUS_ERROR_INVALID;
1892 if (!handler->common->id) {
1893 return LB_STATUS_ERROR_INVALID;
1896 return handler->common->is_active_update;
1899 static void resize_job_cb(struct livebox *handler, int ret, void *data)
1901 struct cb_info *info = data;
1904 info->cb(handler, ret, info->data);
1911 * Forcely update the box
1913 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
1916 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
1918 struct livebox_common *common;
1925 * If this handle is host instance or link instance,
1926 * Create a new instance or find another linkable instance.
1929 if (!handler || handler->state != CREATE) {
1930 ErrPrint("Handler is not valid\n");
1931 return LB_STATUS_ERROR_INVALID;
1934 if (!handler->common || handler->common->state != CREATE) {
1935 ErrPrint("Invalid handle\n");
1936 return LB_STATUS_ERROR_INVALID;
1939 if (!handler->common->id) {
1940 ErrPrint("Handler is not valid\n");
1941 return LB_STATUS_ERROR_INVALID;
1946 * resize operation should be separated by each handler.
1947 * If a handler is resizing, the other handler can request resize too.
1948 * So we should not use the common->request.size_changed flag.
1950 if (handler->cbs.size_changed.cb) {
1951 ErrPrint("Previous resize request is not finished yet\n");
1952 return LB_STATUS_ERROR_BUSY;
1955 if (livebox_service_get_size(type, &w, &h) != 0) {
1956 ErrPrint("Invalid size type\n");
1957 return LB_STATUS_ERROR_INVALID;
1960 if (handler->common->lb.width == w && handler->common->lb.height == h) {
1961 DbgPrint("No changes\n");
1962 return LB_STATUS_ERROR_ALREADY;
1965 if (!handler->common->is_user) {
1966 ErrPrint("CA Livebox is not able to be resized\n");
1967 return LB_STATUS_ERROR_PERMISSION;
1970 if (handler->common->refcnt <= 1) {
1971 struct packet *packet;
1973 /* Only 1 instance */
1974 packet = packet_create("resize", "ssii", handler->common->pkgname, handler->common->id, w, h);
1976 ErrPrint("Failed to build param\n");
1977 return LB_STATUS_ERROR_FAULT;
1981 cb = default_lb_size_changed_cb;
1984 ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
1985 if (ret == LB_STATUS_SUCCESS) {
1986 handler->cbs.size_changed.cb = cb;
1987 handler->cbs.size_changed.data = data;
1988 handler->common->request.size_changed = 1;
1991 common = find_sharable_common_handle(handler->common->pkgname, handler->common->content, w, h, handler->common->cluster, handler->common->category);
1993 struct livebox_common *old_common;
1996 * If the common handler is in resizing,
1997 * if user tries to resize a hander, then simply create new one even if the requested size is same with this.
1999 if (handler->common->request.size_changed) {
2004 old_common = handler->common;
2006 common = lb_create_common_handle(handler, old_common->pkgname, old_common->cluster, old_common->category);
2008 ErrPrint("Failed to create common handle\n");
2009 return LB_STATUS_ERROR_FAULT;
2012 lb_set_size(common, w, h);
2013 lb_set_content(common, old_common->content);
2014 lb_set_period(common, old_common->lb.period);
2018 * Disconnecting from old one.
2020 if (lb_common_unref(old_common, handler) == 0) {
2025 ErrPrint("Common has no associated handler\n");
2028 lb_common_ref(common, handler);
2031 * Connect to a new one
2033 handler->common = common;
2037 * Need to care, if it fails to create a common handle,
2038 * the resize operation will be failed.
2039 * in that case, we should reuse the old common handle
2041 ret = create_real_instance(handler, cb, data);
2043 lb_common_unref(common, handler);
2044 lb_destroy_common_handle(common);
2046 lb_common_ref(old_common, handler);
2047 handler->common = old_common;
2050 * In this case, we should update visibility of old_common's liveboxes
2052 if (handler->visible == LB_SHOW) {
2053 lb_update_visibility(old_common);
2057 struct cb_info *cbinfo;
2059 cbinfo = create_cb_info(cb, data);
2061 ErrPrint("Failed to create a cbinfo\n");
2062 ret = LB_STATUS_ERROR_MEMORY;
2064 ret = job_add(handler, resize_job_cb, LB_STATUS_SUCCESS, cbinfo);
2065 if (ret == LB_STATUS_SUCCESS) {
2066 struct livebox_common *old_common;
2068 old_common = handler->common;
2070 if (lb_common_unref(handler->common, handler) == 0) {
2071 ErrPrint("Old common has no associated handler\n");
2074 lb_common_ref(common, handler);
2075 handler->common = common;
2077 if (handler->visible == LB_SHOW) {
2078 lb_update_visibility(old_common); /* To update visibility: Show --> Paused */
2079 lb_update_visibility(common); /* To update visibility: Paused --> Show */
2082 destroy_cb_info(cbinfo);
2091 EAPI int livebox_click(struct livebox *handler, double x, double y)
2093 struct packet *packet;
2097 if (!handler || handler->state != CREATE) {
2098 ErrPrint("Handler is invalid\n");
2099 return LB_STATUS_ERROR_INVALID;
2102 if (!handler->common || handler->common->state != CREATE) {
2103 ErrPrint("Handler is invalid\n");
2104 return LB_STATUS_ERROR_INVALID;
2107 if (!handler->common->id) {
2108 ErrPrint("Handler is not valid\n");
2109 return LB_STATUS_ERROR_INVALID;
2112 if (handler->common->lb.auto_launch) {
2116 DbgPrint("AUTO_LAUNCH [%s]\n", handler->common->lb.auto_launch);
2118 ret = service_create(&service);
2119 if (ret == SERVICE_ERROR_NONE) {
2120 service_set_package(service, handler->common->lb.auto_launch);
2121 service_send_launch_request(service, NULL, NULL);
2122 service_destroy(service);
2124 ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
2127 ret = aul_launch_app(handler->common->lb.auto_launch, NULL);
2129 ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
2133 timestamp = util_timestamp();
2134 DbgPrint("CLICKED: %lf\n", timestamp);
2136 packet = packet_create_noack("clicked", "sssddd", handler->common->pkgname, handler->common->id, "clicked", timestamp, x, y);
2138 ErrPrint("Failed to build param\n");
2139 return LB_STATUS_ERROR_FAULT;
2142 ret = master_rpc_request_only(handler, packet);
2144 if (!handler->common->lb.mouse_event && (handler->common->lb.type == _LB_TYPE_BUFFER || handler->common->lb.type == _LB_TYPE_SCRIPT)) {
2145 int ret; /* Shadow variable */
2146 ret = send_mouse_event(handler, "lb_mouse_down", x * handler->common->lb.width, y * handler->common->lb.height);
2148 ErrPrint("Failed to send Down: %d\n", ret);
2151 ret = send_mouse_event(handler, "lb_mouse_move", x * handler->common->lb.width, y * handler->common->lb.height);
2153 ErrPrint("Failed to send Move: %d\n", ret);
2156 ret = send_mouse_event(handler, "lb_mouse_up", x * handler->common->lb.width, y * handler->common->lb.height);
2158 ErrPrint("Failed to send Up: %d\n", ret);
2165 EAPI int livebox_has_pd(struct livebox *handler)
2167 if (!handler || handler->state != CREATE) {
2168 ErrPrint("Handler is invalid\n");
2169 return LB_STATUS_ERROR_INVALID;
2172 if (!handler->common || handler->common->state != CREATE) {
2173 ErrPrint("Handler is invalid\n");
2174 return LB_STATUS_ERROR_INVALID;
2177 if (!handler->common->id) {
2178 ErrPrint("Handler is not valid\n");
2179 return LB_STATUS_ERROR_INVALID;
2182 return !!handler->common->pd.fb;
2185 EAPI int livebox_pd_is_created(struct livebox *handler)
2187 if (!handler || handler->state != CREATE) {
2188 ErrPrint("Handler is invalid\n");
2189 return LB_STATUS_ERROR_INVALID;
2192 if (!handler->common || handler->common->state != CREATE) {
2193 ErrPrint("Handler is invalid\n");
2194 return LB_STATUS_ERROR_INVALID;
2197 if (!handler->common->pd.fb || !handler->common->id) {
2198 ErrPrint("Handler is not valid\n");
2199 return LB_STATUS_ERROR_INVALID;
2202 return handler->common->is_pd_created;
2205 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
2207 return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
2210 static void turn_off_pd_destroyed_flag_cb(struct livebox *handler, int ret, void *data)
2212 if (handler->common->request.pd_destroyed) {
2216 DbgPrint("pd_destroyed request is canceled\n");
2217 handler->common->request.pd_destroyed = 0;
2218 cb = handler->cbs.pd_destroyed.cb;
2219 data = handler->cbs.pd_destroyed.data;
2220 handler->cbs.pd_destroyed.cb = NULL;
2221 handler->cbs.pd_destroyed.data = NULL;
2224 cb(handler, ret, data);
2229 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
2231 struct packet *packet;
2234 if (!handler || handler->state != CREATE) {
2235 ErrPrint("Handler is invalid\n");
2236 return LB_STATUS_ERROR_INVALID;
2239 if (!handler->common || handler->common->state != CREATE) {
2240 ErrPrint("Handler is invalid\n");
2241 return LB_STATUS_ERROR_INVALID;
2244 if (!handler->common->pd.fb || !handler->common->id) {
2245 ErrPrint("Handler is not valid\n");
2246 return LB_STATUS_ERROR_INVALID;
2251 * Only one handler can have a PD
2253 if (handler->common->is_pd_created) {
2254 DbgPrint("PD is already created\n");
2255 return LB_STATUS_SUCCESS;
2258 if (handler->common->request.pd_created) {
2259 ErrPrint("Previous request is not completed yet\n");
2260 return LB_STATUS_ERROR_BUSY;
2265 * Turn off the pd_destroyed request flag
2267 if (handler->common->request.pd_destroyed) {
2268 if (job_add(handler, turn_off_pd_destroyed_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2269 ErrPrint("Failed to add pd_destroyed job\n");
2273 packet = packet_create("create_pd", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2275 ErrPrint("Failed to build param\n");
2276 return LB_STATUS_ERROR_FAULT;
2280 cb = default_pd_created_cb;
2283 DbgPrint("PERF_DBOX\n");
2284 ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
2285 if (ret == LB_STATUS_SUCCESS) {
2286 handler->cbs.pd_created.cb = cb;
2287 handler->cbs.pd_created.data = data;
2288 handler->common->request.pd_created = 1;
2294 EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
2296 struct packet *packet;
2298 if (!handler || handler->state != CREATE) {
2299 ErrPrint("Handler is invalid\n");
2300 return LB_STATUS_ERROR_INVALID;
2303 if (!handler->common || handler->common->state != CREATE) {
2304 ErrPrint("Handler is invalid\n");
2305 return LB_STATUS_ERROR_INVALID;
2308 if (!handler->common->pd.fb || !handler->common->id) {
2309 ErrPrint("Handler is not valid\n");
2310 return LB_STATUS_ERROR_INVALID;
2313 if (!handler->common->is_pd_created) {
2314 ErrPrint("PD is not created\n");
2315 return LB_STATUS_ERROR_INVALID;
2318 packet = packet_create_noack("pd_move", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2320 ErrPrint("Failed to build param\n");
2321 return LB_STATUS_ERROR_FAULT;
2324 return master_rpc_request_only(handler, packet);
2327 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
2329 struct packet *packet;
2330 struct cb_info *cbinfo;
2334 return LB_STATUS_ERROR_INVALID;
2337 packet = packet_create("activate_package", "s", pkgname);
2339 ErrPrint("Failed to build a param\n");
2340 return LB_STATUS_ERROR_FAULT;
2343 cbinfo = create_cb_info(cb, data);
2345 ErrPrint("Unable to create cbinfo\n");
2346 packet_destroy(packet);
2347 return LB_STATUS_ERROR_FAULT;
2350 ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo);
2352 destroy_cb_info(cbinfo);
2358 static void turn_off_pd_created_flag_cb(struct livebox *handler, int ret, void *data)
2360 if (handler->common->request.pd_created) {
2364 DbgPrint("pd_created request is canceled\n");
2365 handler->common->request.pd_created = 0;
2366 cb = handler->cbs.pd_created.cb;
2367 data = handler->cbs.pd_created.data;
2368 handler->cbs.pd_created.cb = NULL;
2369 handler->cbs.pd_created.data = NULL;
2372 cb(handler, ret, data);
2377 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
2379 struct packet *packet;
2380 struct cb_info *cbinfo;
2383 if (!handler || handler->state != CREATE) {
2384 ErrPrint("Handler is invalid\n");
2385 return LB_STATUS_ERROR_INVALID;
2388 if (!handler->common || handler->common->state != CREATE) {
2389 ErrPrint("Handler is invalid\n");
2390 return LB_STATUS_ERROR_INVALID;
2393 if (!handler->common->pd.fb || !handler->common->id) {
2394 ErrPrint("Handler is not valid\n");
2395 return LB_STATUS_ERROR_INVALID;
2400 * Replace the callback check code.
2401 * Use the flag instead of callback.
2402 * the flag should be in the ADT "common"
2404 if (!handler->common->is_pd_created && !handler->common->request.pd_created) {
2405 ErrPrint("PD is not created\n");
2406 return LB_STATUS_ERROR_INVALID;
2409 if (handler->common->request.pd_destroyed) {
2410 ErrPrint("PD destroy request is already sent\n");
2411 return LB_STATUS_ERROR_ALREADY;
2416 * Disable the pd_created request flag
2418 if (handler->common->request.pd_created) {
2419 if (job_add(handler, turn_off_pd_created_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2420 ErrPrint("Failed to add a new job\n");
2424 DbgPrint("[%s]\n", handler->common->pkgname);
2426 packet = packet_create("destroy_pd", "ss", handler->common->pkgname, handler->common->id);
2428 ErrPrint("Failed to build a param\n");
2429 return LB_STATUS_ERROR_FAULT;
2433 cb = default_pd_destroyed_cb;
2436 cbinfo = create_cb_info(cb, data);
2438 packet_destroy(packet);
2439 return LB_STATUS_ERROR_FAULT;
2442 ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo);
2444 destroy_cb_info(cbinfo);
2446 handler->common->request.pd_destroyed = 1;
2452 EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data)
2456 char cmd[32] = { '\0', };
2460 if (!handler || handler->state != CREATE) {
2461 ErrPrint("Handler is invalid\n");
2462 return LB_STATUS_ERROR_INVALID;
2465 if (!handler->common || handler->common->state != CREATE) {
2466 ErrPrint("Handler is invalid\n");
2467 return LB_STATUS_ERROR_INVALID;
2470 if (!handler->common->id) {
2471 ErrPrint("Handler is not valid\n");
2472 return LB_STATUS_ERROR_INVALID;
2475 if (handler->common->request.access_event) {
2476 ErrPrint("Previous access event is not yet done\n");
2477 return LB_STATUS_ERROR_BUSY;
2480 if (type & ACCESS_EVENT_PD_MASK) {
2481 if (!handler->common->is_pd_created) {
2482 ErrPrint("PD is not created\n");
2483 return LB_STATUS_ERROR_INVALID;
2487 w = handler->common->pd.width;
2488 h = handler->common->pd.height;
2489 } else if (type & ACCESS_EVENT_LB_MASK) {
2492 w = handler->common->lb.width;
2493 h = handler->common->lb.height;
2495 ErrPrint("Invalid event type\n");
2496 return LB_STATUS_ERROR_INVALID;
2499 switch (type & ~ACCESS_EVENT_PD_MASK) {
2500 case ACCESS_EVENT_HIGHLIGHT:
2501 strcpy(ptr, "_access_hl");
2503 case ACCESS_EVENT_HIGHLIGHT_NEXT:
2504 strcpy(ptr, "_access_hl_next");
2506 case ACCESS_EVENT_HIGHLIGHT_PREV:
2507 strcpy(ptr, "_access_hl_prev");
2509 case ACCESS_EVENT_ACTIVATE:
2510 strcpy(ptr, "_access_activate");
2512 case ACCESS_EVENT_ACTION_DOWN:
2513 strcpy(ptr, "_access_action_down");
2515 case ACCESS_EVENT_ACTION_UP:
2516 strcpy(ptr, "_access_action_up");
2518 case ACCESS_EVENT_UNHIGHLIGHT:
2519 strcpy(ptr, "_access_unhighlight");
2521 case ACCESS_EVENT_SCROLL_DOWN:
2522 strcpy(ptr, "_access_scroll_down");
2524 case ACCESS_EVENT_SCROLL_MOVE:
2525 strcpy(ptr, "_access_scroll_move");
2527 case ACCESS_EVENT_SCROLL_UP:
2528 strcpy(ptr, "_access_scroll_up");
2531 return LB_STATUS_ERROR_INVALID;
2535 cb = default_access_event_cb;
2538 ret = send_access_event(handler, cmd, x * w, y * h);
2539 if (ret == LB_STATUS_SUCCESS) {
2540 handler->cbs.access_event.cb = cb;
2541 handler->cbs.access_event.data = data;
2542 handler->common->request.access_event = 1;
2548 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
2550 return livebox_mouse_event(handler, type, x, y);
2553 EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y)
2557 char cmd[32] = { '\0', };
2560 if (!handler || handler->state != CREATE) {
2561 ErrPrint("Handler is invalid\n");
2562 return LB_STATUS_ERROR_INVALID;
2565 if (!handler->common || handler->common->state != CREATE) {
2566 ErrPrint("Handler is invalid\n");
2567 return LB_STATUS_ERROR_INVALID;
2570 if (!handler->common->id) {
2571 ErrPrint("Handler is not valid\n");
2572 return LB_STATUS_ERROR_INVALID;
2575 if (!(type & CONTENT_EVENT_MOUSE_MASK)) {
2576 ErrPrint("Invalid content event is used\n");
2577 return LB_STATUS_ERROR_INVALID;
2580 if (type & CONTENT_EVENT_PD_MASK) {
2583 if (!handler->common->is_pd_created) {
2584 ErrPrint("PD is not created\n");
2585 return LB_STATUS_ERROR_INVALID;
2588 if (!handler->common->pd.fb) {
2589 ErrPrint("Handler is not valid\n");
2590 return LB_STATUS_ERROR_INVALID;
2593 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2594 if (fabs(x - handler->common->pd.x) < conf_event_filter() && fabs(y - handler->common->pd.y) < conf_event_filter()) {
2595 return LB_STATUS_ERROR_BUSY;
2597 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2602 w = handler->common->pd.width;
2603 h = handler->common->pd.height;
2604 handler->common->pd.x = x;
2605 handler->common->pd.y = y;
2609 } else if (type & CONTENT_EVENT_LB_MASK) {
2612 if (!handler->common->lb.mouse_event) {
2613 return LB_STATUS_ERROR_INVALID;
2616 if (!handler->common->lb.fb) {
2617 ErrPrint("Handler is not valid\n");
2618 return LB_STATUS_ERROR_INVALID;
2621 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2622 if (fabs(x - handler->common->lb.x) < conf_event_filter() && fabs(y - handler->common->lb.y) < conf_event_filter()) {
2623 return LB_STATUS_ERROR_BUSY;
2625 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2630 w = handler->common->lb.width;
2631 h = handler->common->lb.height;
2632 handler->common->lb.x = x;
2633 handler->common->lb.y = y;
2638 ErrPrint("Invalid event type\n");
2639 return LB_STATUS_ERROR_INVALID;
2643 * Must be short than 29 bytes.
2645 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2646 case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
2647 strcpy(ptr, "_mouse_enter");
2649 case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
2650 strcpy(ptr, "_mouse_leave");
2652 case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
2653 strcpy(ptr, "_mouse_up");
2655 case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
2656 strcpy(ptr, "_mouse_down");
2658 case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
2659 strcpy(ptr, "_mouse_move");
2661 case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
2662 strcpy(ptr, "_mouse_set");
2664 case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
2665 strcpy(ptr, "_mouse_unset");
2668 ErrPrint("Invalid event type\n");
2669 return LB_STATUS_ERROR_INVALID;
2672 return send_mouse_event(handler, cmd, x * w, y * h);
2675 EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data)
2677 char cmd[32] = { '\0', };
2681 if (!handler || handler->state != CREATE) {
2682 ErrPrint("Handler is invalid\n");
2683 return LB_STATUS_ERROR_INVALID;
2686 if (!handler->common || handler->common->state != CREATE) {
2687 ErrPrint("Handler is invalid\n");
2688 return LB_STATUS_ERROR_INVALID;
2691 if (!handler->common->id) {
2692 ErrPrint("Handler is not valid\n");
2693 return LB_STATUS_ERROR_INVALID;
2696 if (!(type & CONTENT_EVENT_KEY_MASK)) {
2697 ErrPrint("Invalid key event is used\n");
2698 return LB_STATUS_ERROR_INVALID;
2701 if (handler->common->request.key_event) {
2702 ErrPrint("Previous key event is not completed yet\n");
2703 return LB_STATUS_ERROR_BUSY;
2706 if (type & CONTENT_EVENT_PD_MASK) {
2707 if (!handler->common->is_pd_created) {
2708 ErrPrint("PD is not created\n");
2709 return LB_STATUS_ERROR_INVALID;
2712 if (!handler->common->pd.fb) {
2713 ErrPrint("Handler is not valid\n");
2714 return LB_STATUS_ERROR_INVALID;
2717 if (type & CONTENT_EVENT_KEY_DOWN) {
2720 * filtering the reproduced events if it is too fast
2722 } else if (type & CONTENT_EVENT_KEY_SET) {
2725 * What can I do for this case?
2731 } else if (type & CONTENT_EVENT_LB_MASK) {
2732 if (!handler->common->lb.mouse_event) {
2733 return LB_STATUS_ERROR_INVALID;
2736 if (!handler->common->lb.fb) {
2737 ErrPrint("Handler is not valid\n");
2738 return LB_STATUS_ERROR_INVALID;
2741 if (type & CONTENT_EVENT_KEY_DOWN) {
2744 * filtering the reproduced events if it is too fast
2746 } else if (type & CONTENT_EVENT_KEY_SET) {
2748 * What can I do for this case?
2755 ErrPrint("Invalid event type\n");
2756 return LB_STATUS_ERROR_INVALID;
2760 * Must be short than 29 bytes.
2762 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2763 case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK:
2764 strcpy(ptr, "_key_focus_in");
2766 case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK:
2767 strcpy(ptr, "_key_focus_out");
2769 case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
2770 strcpy(ptr, "_key_up");
2772 case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
2773 strcpy(ptr, "_key_down");
2775 case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK:
2776 strcpy(ptr, "_key_set");
2778 case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK:
2779 strcpy(ptr, "_key_unset");
2782 ErrPrint("Invalid event type\n");
2783 return LB_STATUS_ERROR_INVALID;
2787 cb = default_key_event_cb;
2790 ret = send_key_event(handler, cmd, keycode);
2791 if (ret == LB_STATUS_SUCCESS) {
2792 handler->cbs.key_event.cb = cb;
2793 handler->cbs.key_event.data = data;
2794 handler->common->request.key_event = 1;
2800 EAPI const char *livebox_filename(struct livebox *handler)
2802 if (!handler || handler->state != CREATE) {
2803 ErrPrint("Handler is invalid\n");
2807 if (!handler->common || handler->common->state != CREATE) {
2808 ErrPrint("Handler is invalid\n");
2812 if (!handler->common->id) {
2813 ErrPrint("Handler is not valid\n");
2817 if (handler->common->filename) {
2818 return handler->common->filename;
2822 return util_uri_to_path(handler->common->id);
2825 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
2830 if (!handler || handler->state != CREATE) {
2831 ErrPrint("Handler is invalid\n");
2832 return LB_STATUS_ERROR_INVALID;
2835 if (!handler->common || handler->common->state != CREATE) {
2836 ErrPrint("Handler is invalid\n");
2837 return LB_STATUS_ERROR_INVALID;
2840 if (!handler->common->id) {
2841 ErrPrint("Handler is not valid\n");
2842 return LB_STATUS_ERROR_INVALID;
2852 if (!handler->common->is_pd_created) {
2853 *w = handler->common->pd.default_width;
2854 *h = handler->common->pd.default_height;
2856 *w = handler->common->pd.width;
2857 *h = handler->common->pd.height;
2860 return LB_STATUS_SUCCESS;
2863 EAPI int livebox_size(struct livebox *handler)
2868 if (!handler || handler->state != CREATE) {
2869 ErrPrint("Handler is invalid\n");
2870 return LB_STATUS_ERROR_INVALID;
2873 if (!handler->common || handler->common->state != CREATE) {
2874 ErrPrint("Handler is invalid\n");
2875 return LB_STATUS_ERROR_INVALID;
2878 if (!handler->common->id) {
2879 ErrPrint("Handler is not valid\n");
2880 return LB_STATUS_ERROR_INVALID;
2883 w = handler->common->lb.width;
2884 h = handler->common->lb.height;
2886 switch (handler->common->lb.type) {
2887 case _LB_TYPE_BUFFER:
2888 case _LB_TYPE_SCRIPT:
2889 if (!fb_is_created(handler->common->lb.fb)) {
2898 return livebox_service_size_type(w, h);
2901 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
2903 struct packet *packet;
2907 ErrPrint("Handler is NIL\n");
2908 return LB_STATUS_ERROR_INVALID;
2911 if (!cluster || !category || handler->state != CREATE) {
2912 ErrPrint("Invalid argument\n");
2913 return LB_STATUS_ERROR_INVALID;
2916 if (!handler->common || handler->common->state != CREATE) {
2917 ErrPrint("Invalid argument\n");
2918 return LB_STATUS_ERROR_INVALID;
2921 if (!handler->common->id) {
2922 ErrPrint("Invalid argument\n");
2923 return LB_STATUS_ERROR_INVALID;
2926 if (handler->common->request.group_changed) {
2927 ErrPrint("Previous group changing request is not finished yet\n");
2928 return LB_STATUS_ERROR_BUSY;
2931 if (!handler->common->is_user) {
2932 ErrPrint("CA Livebox is not able to change the group\n");
2933 return LB_STATUS_ERROR_PERMISSION;
2936 if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) {
2937 DbgPrint("No changes\n");
2938 return LB_STATUS_ERROR_ALREADY;
2941 packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category);
2943 ErrPrint("Failed to build a param\n");
2944 return LB_STATUS_ERROR_FAULT;
2948 cb = default_group_changed_cb;
2951 ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
2952 if (ret == LB_STATUS_SUCCESS) {
2953 handler->cbs.group_changed.cb = cb;
2954 handler->cbs.group_changed.data = data;
2955 handler->common->request.group_changed = 1;
2961 EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category)
2964 ErrPrint("Handler is NIL\n");
2965 return LB_STATUS_ERROR_INVALID;
2968 if (!cluster || !category || handler->state != CREATE) {
2969 ErrPrint("Invalid argument\n");
2970 return LB_STATUS_ERROR_INVALID;
2973 if (!handler->common || handler->common->state != CREATE) {
2974 ErrPrint("Invalid argument\n");
2975 return LB_STATUS_ERROR_INVALID;
2978 if (!handler->common->id) {
2979 ErrPrint("Invalid argument\n");
2980 return LB_STATUS_ERROR_INVALID;
2983 *cluster = handler->common->cluster;
2984 *category = handler->common->category;
2985 return LB_STATUS_SUCCESS;
2988 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
2993 if (!handler || !size_list) {
2994 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
2995 return LB_STATUS_ERROR_INVALID;
2998 if (!cnt || handler->state != CREATE) {
2999 ErrPrint("Handler is not valid\n");
3000 return LB_STATUS_ERROR_INVALID;
3003 if (!handler->common || handler->common->state != CREATE) {
3004 ErrPrint("Handler is not valid\n");
3005 return LB_STATUS_ERROR_INVALID;
3008 if (!handler->common->id) {
3009 ErrPrint("Handler is not valid\n");
3010 return LB_STATUS_ERROR_INVALID;
3013 for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
3014 if (handler->common->lb.size_list & (0x01 << i)) {
3019 size_list[j++] = (0x01 << i);
3024 return LB_STATUS_SUCCESS;
3027 EAPI const char *livebox_pkgname(struct livebox *handler)
3030 ErrPrint("Handler is NIL\n");
3034 if (handler->state != CREATE) {
3035 ErrPrint("Handler is not valid\n");
3039 if (!handler->common || handler->common->state != CREATE) {
3040 ErrPrint("Handler is not valid\n");
3044 return handler->common->pkgname;
3047 EAPI double livebox_priority(struct livebox *handler)
3049 if (!handler || handler->state != CREATE) {
3050 ErrPrint("Handler is invalid\n");
3054 if (!handler->common || handler->common->state != CREATE) {
3055 ErrPrint("Handler is invalid\n");
3059 if (!handler->common->id) {
3060 ErrPrint("Handler is not valid (%p)\n", handler);
3064 return handler->common->lb.priority;
3067 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
3069 struct packet *packet;
3070 struct cb_info *cbinfo;
3073 packet = packet_create("delete_cluster", "s", cluster);
3075 ErrPrint("Failed to build a param\n");
3076 return LB_STATUS_ERROR_FAULT;
3079 cbinfo = create_cb_info(cb, data);
3081 packet_destroy(packet);
3082 return LB_STATUS_ERROR_FAULT;
3085 ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
3087 destroy_cb_info(cbinfo);
3093 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
3095 struct packet *packet;
3096 struct cb_info *cbinfo;
3099 packet = packet_create("delete_category", "ss", cluster, category);
3101 ErrPrint("Failed to build a param\n");
3102 return LB_STATUS_ERROR_FAULT;
3105 cbinfo = create_cb_info(cb, data);
3107 packet_destroy(packet);
3108 return LB_STATUS_ERROR_FAULT;
3111 ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
3113 destroy_cb_info(cbinfo);
3119 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
3121 if (!handler || handler->state != CREATE) {
3122 ErrPrint("Handler is invalid\n");
3123 return LB_TYPE_INVALID;
3126 if (!handler->common || handler->common->state != CREATE) {
3127 ErrPrint("Handler is invalid\n");
3128 return LB_TYPE_INVALID;
3131 if (!handler->common->id) {
3132 ErrPrint("Handler is not valid\n");
3133 return LB_TYPE_INVALID;
3136 switch (handler->common->lb.type) {
3138 return LB_TYPE_IMAGE;
3139 case _LB_TYPE_BUFFER:
3140 case _LB_TYPE_SCRIPT:
3143 id = fb_id(handler->common->lb.fb);
3144 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3145 return LB_TYPE_PIXMAP;
3148 return LB_TYPE_BUFFER;
3150 return LB_TYPE_TEXT;
3155 return LB_TYPE_INVALID;
3158 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
3160 if (!handler || handler->state != CREATE) {
3161 ErrPrint("Handler is invalid\n");
3162 return PD_TYPE_INVALID;
3165 if (!handler->common || handler->common->state != CREATE) {
3166 ErrPrint("Handler is invalid\n");
3167 return PD_TYPE_INVALID;
3170 if (!handler->common->id) {
3171 ErrPrint("Handler is not valid\n");
3172 return PD_TYPE_INVALID;
3175 switch (handler->common->pd.type) {
3177 return PD_TYPE_TEXT;
3178 case _PD_TYPE_BUFFER:
3179 case _PD_TYPE_SCRIPT:
3182 id = fb_id(handler->common->pd.fb);
3183 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3184 return PD_TYPE_PIXMAP;
3187 return PD_TYPE_BUFFER;
3192 return PD_TYPE_INVALID;
3195 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3198 ErrPrint("Handler is NIL\n");
3199 return LB_STATUS_ERROR_INVALID;
3202 if (handler->state != CREATE) {
3203 ErrPrint("Handler is not valid\n");
3204 return LB_STATUS_ERROR_INVALID;
3207 memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops));
3208 return LB_STATUS_SUCCESS;
3211 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3214 ErrPrint("Handler is NIL\n");
3215 return LB_STATUS_ERROR_INVALID;
3218 if (handler->state != CREATE) {
3219 ErrPrint("Handler is not valid\n");
3220 return LB_STATUS_ERROR_INVALID;
3223 memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops));
3224 return LB_STATUS_SUCCESS;
3227 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3229 if (!handler || handler->state != CREATE) {
3230 ErrPrint("Handler is invalid\n");
3231 return LB_STATUS_ERROR_INVALID;
3234 if (!handler->common || handler->common->state != CREATE) {
3235 ErrPrint("Handler is invalid\n");
3236 return LB_STATUS_ERROR_INVALID;
3239 if (!handler->common->id) {
3240 ErrPrint("Invalid handle\n");
3241 return LB_STATUS_ERROR_INVALID;
3244 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3245 ErrPrint("Handler is not valid type\n");
3246 return LB_STATUS_ERROR_INVALID;
3249 return lb_acquire_lb_pixmap(handler, cb, data);
3252 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
3254 struct packet *packet;
3256 if (!handler || pixmap == 0 || handler->state != CREATE) {
3257 ErrPrint("Handler is invalid [%d]\n", pixmap);
3258 return LB_STATUS_ERROR_INVALID;
3261 if (!handler->common || handler->common->state != CREATE) {
3262 ErrPrint("Handler is invalid\n");
3263 return LB_STATUS_ERROR_INVALID;
3266 if (!handler->common->id) {
3267 ErrPrint("Invalid handle\n");
3268 return LB_STATUS_ERROR_INVALID;
3271 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3272 ErrPrint("Handler is not valid type\n");
3273 return LB_STATUS_ERROR_INVALID;
3276 packet = packet_create_noack("lb_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
3278 ErrPrint("Failed to build a param\n");
3279 return LB_STATUS_ERROR_INVALID;
3282 return master_rpc_request_only(handler, packet);
3285 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3287 if (!handler || handler->state != CREATE) {
3288 ErrPrint("Handler is invalid\n");
3289 return LB_STATUS_ERROR_INVALID;
3292 if (!handler->common || handler->common->state != CREATE) {
3293 ErrPrint("Handler is invalid\n");
3294 return LB_STATUS_ERROR_INVALID;
3297 if (!handler->common->id) {
3298 ErrPrint("Invalid handle\n");
3299 return LB_STATUS_ERROR_INVALID;
3302 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3303 ErrPrint("Handler is not valid type\n");
3304 return LB_STATUS_ERROR_INVALID;
3307 return lb_acquire_pd_pixmap(handler, cb, data);
3310 EAPI int livebox_pd_pixmap(const struct livebox *handler)
3315 if (!handler || handler->state != CREATE) {
3316 ErrPrint("Handler is invalid\n");
3320 if (!handler->common || handler->common->state != CREATE) {
3321 ErrPrint("Handler is invalid\n");
3325 if (!handler->common->id) {
3326 ErrPrint("Invalid handler\n");
3330 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3331 ErrPrint("Invalid handler\n");
3335 id = fb_id(handler->common->pd.fb);
3336 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3337 ErrPrint("PIXMAP Id is not valid\n");
3344 EAPI int livebox_lb_pixmap(const struct livebox *handler)
3349 if (!handler || handler->state != CREATE) {
3350 ErrPrint("Handler is invalid\n");
3354 if (!handler->common || handler->common->state != CREATE) {
3355 ErrPrint("Handler is invalid\n");
3359 if (!handler->common->id) {
3360 ErrPrint("Invalid handler\n");
3364 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3365 ErrPrint("Invalid handler\n");
3369 id = fb_id(handler->common->lb.fb);
3370 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3371 ErrPrint("PIXMAP Id is not valid\n");
3378 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
3380 struct packet *packet;
3382 if (!handler || pixmap == 0 || handler->state != CREATE) {
3383 ErrPrint("Handler is invalid [%d]\n", pixmap);
3384 return LB_STATUS_ERROR_INVALID;
3387 if (!handler->common || handler->common->state != CREATE) {
3388 ErrPrint("Handler is invalid\n");
3389 return LB_STATUS_ERROR_INVALID;
3392 if (!handler->common->id) {
3393 ErrPrint("Invalid handle\n");
3394 return LB_STATUS_ERROR_INVALID;
3397 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3398 ErrPrint("Handler is not valid type\n");
3399 return LB_STATUS_ERROR_INVALID;
3402 packet = packet_create_noack("pd_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
3404 ErrPrint("Failed to build a param\n");
3405 return LB_STATUS_ERROR_FAULT;
3408 return master_rpc_request_only(handler, packet);
3411 EAPI void *livebox_acquire_fb(struct livebox *handler)
3413 if (!handler || handler->state != CREATE) {
3414 ErrPrint("Handler is invalid\n");
3418 if (!handler->common || handler->common->state != CREATE) {
3419 ErrPrint("Handler is invalid\n");
3423 if (!handler->common->id) {
3424 ErrPrint("Invalid handle\n");
3428 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3429 ErrPrint("Handler is not valid type\n");
3433 return fb_acquire_buffer(handler->common->lb.fb);
3436 EAPI int livebox_release_fb(void *buffer)
3438 return fb_release_buffer(buffer);
3441 EAPI int livebox_fb_refcnt(void *buffer)
3443 return fb_refcnt(buffer);
3446 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
3448 if (!handler || handler->state != CREATE) {
3449 ErrPrint("Handler is invalid\n");
3453 if (!handler->common || handler->common->state != CREATE) {
3454 ErrPrint("Handler is invalid\n");
3458 if (!handler->common->id) {
3459 ErrPrint("Invalid handler\n");
3463 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3464 ErrPrint("Handler is not valid type\n");
3468 return fb_acquire_buffer(handler->common->pd.fb);
3471 EAPI int livebox_release_pdfb(void *buffer)
3473 return fb_release_buffer(buffer);
3476 EAPI int livebox_pdfb_refcnt(void *buffer)
3478 return fb_refcnt(buffer);
3481 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
3483 if (!handler || handler->state != CREATE) {
3484 ErrPrint("Handler is invalid\n");
3485 return LB_STATUS_ERROR_INVALID;
3488 if (!handler->common || handler->common->state != CREATE) {
3489 ErrPrint("Handler is invalid\n");
3490 return LB_STATUS_ERROR_INVALID;
3493 if (!handler->common->id) {
3494 ErrPrint("Invalid handler\n");
3495 return LB_STATUS_ERROR_INVALID;
3498 return fb_size(handler->common->pd.fb);
3501 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
3503 if (!handler || handler->state != CREATE) {
3504 ErrPrint("Handler is invalid\n");
3505 return LB_STATUS_ERROR_INVALID;
3508 if (!handler->common || handler->common->state != CREATE) {
3509 ErrPrint("Handler is invalid\n");
3510 return LB_STATUS_ERROR_INVALID;
3513 if (!handler->common->id) {
3514 ErrPrint("Invalid handler\n");
3515 return LB_STATUS_ERROR_INVALID;
3518 return fb_size(handler->common->lb.fb);
3521 EAPI int livebox_is_user(struct livebox *handler)
3523 if (!handler || handler->state != CREATE) {
3524 ErrPrint("Handler is invalid\n");
3525 return LB_STATUS_ERROR_INVALID;
3528 if (!handler->common || handler->common->state != CREATE) {
3529 ErrPrint("Handler is invalid\n");
3530 return LB_STATUS_ERROR_INVALID;
3533 if (!handler->common->id) {
3534 ErrPrint("Invalid handler\n");
3535 return LB_STATUS_ERROR_INVALID;
3538 return handler->common->is_user;
3541 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
3543 struct packet *packet;
3546 if (!handler || handler->state != CREATE) {
3547 ErrPrint("Handler is invalid\n");
3548 return LB_STATUS_ERROR_INVALID;
3551 if (!handler->common || handler->common->state != CREATE) {
3552 ErrPrint("Handler is invalid\n");
3553 return LB_STATUS_ERROR_INVALID;
3556 if (!handler->common->id) {
3557 ErrPrint("Invalid handler\n");
3558 return LB_STATUS_ERROR_INVALID;
3561 if (handler->common->request.pinup) {
3562 ErrPrint("Previous pinup request is not finished\n");
3563 return LB_STATUS_ERROR_BUSY;
3566 if (handler->common->is_pinned_up == flag) {
3567 DbgPrint("No changes\n");
3568 return LB_STATUS_ERROR_ALREADY;
3571 packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
3573 ErrPrint("Failed to build a param\n");
3574 return LB_STATUS_ERROR_FAULT;
3578 cb = default_pinup_cb;
3581 ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
3582 if (ret == LB_STATUS_SUCCESS) {
3583 handler->cbs.pinup.cb = cb;
3584 handler->cbs.pinup.data = data;
3585 handler->common->request.pinup = 1;
3591 EAPI int livebox_is_pinned_up(struct livebox *handler)
3593 if (!handler || handler->state != CREATE) {
3594 ErrPrint("Handler is invalid\n");
3595 return LB_STATUS_ERROR_INVALID;
3598 if (!handler->common || handler->common->state != CREATE) {
3599 ErrPrint("Handler is invalid\n");
3600 return LB_STATUS_ERROR_INVALID;
3603 if (!handler->common->id) {
3604 ErrPrint("Invalid handler\n");
3605 return LB_STATUS_ERROR_INVALID;
3608 return handler->common->is_pinned_up;
3611 EAPI int livebox_has_pinup(struct livebox *handler)
3613 if (!handler || handler->state != CREATE) {
3614 ErrPrint("Handler is invalid\n");
3615 return LB_STATUS_ERROR_INVALID;
3618 if (!handler->common || handler->common->state != CREATE) {
3619 ErrPrint("Handler is invalid\n");
3620 return LB_STATUS_ERROR_INVALID;
3623 if (!handler->common->id) {
3624 ErrPrint("Invalid handler\n");
3625 return LB_STATUS_ERROR_INVALID;
3628 return handler->common->lb.pinup_supported;
3631 EAPI int livebox_set_data(struct livebox *handler, void *data)
3634 ErrPrint("Handler is NIL\n");
3635 return LB_STATUS_ERROR_INVALID;
3638 if (handler->state != CREATE) {
3639 ErrPrint("Handler is invalid\n");
3640 return LB_STATUS_ERROR_INVALID;
3643 handler->data = data;
3644 return LB_STATUS_SUCCESS;
3647 EAPI void *livebox_get_data(struct livebox *handler)
3650 ErrPrint("Handler is NIL\n");
3654 if (handler->state != CREATE) {
3655 ErrPrint("Handler is invalid\n");
3659 return handler->data;
3662 EAPI int livebox_is_exists(const char *pkgname)
3666 lb = lb_pkgname(pkgname);
3675 EAPI const char *livebox_content(struct livebox *handler)
3677 if (!handler || handler->state != CREATE) {
3678 ErrPrint("Handler is invalid\n");
3682 if (!handler->common || handler->common->state != CREATE) {
3683 ErrPrint("Invalid handle\n");
3687 return handler->common->content;
3690 EAPI const char *livebox_category_title(struct livebox *handler)
3692 if (!handler || handler->state != CREATE) {
3693 ErrPrint("Handler is invalid\n");
3697 if (!handler->common || handler->common->state != CREATE) {
3698 ErrPrint("Invalid handle\n");
3702 return handler->common->title;
3705 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)
3707 struct packet *packet;
3708 struct cb_info *cbinfo;
3711 if (!handler || handler->state != CREATE) {
3712 ErrPrint("Handler is invalid\n");
3713 return LB_STATUS_ERROR_INVALID;
3716 if (!handler->common || handler->common->state != CREATE) {
3717 ErrPrint("Handler is invalid\n");
3718 return LB_STATUS_ERROR_INVALID;
3721 if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
3722 ErrPrint("Handler is not valid\n");
3723 return LB_STATUS_ERROR_INVALID;
3734 packet = packet_create("text_signal", "ssssdddd",
3735 handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
3737 ErrPrint("Failed to build a param\n");
3738 return LB_STATUS_ERROR_FAULT;
3741 cbinfo = create_cb_info(cb, data);
3743 packet_destroy(packet);
3744 return LB_STATUS_ERROR_FAULT;
3747 ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
3749 destroy_cb_info(cbinfo);
3755 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
3757 struct packet *packet;
3761 * Validate the group info using DB
3762 * If the group info is not valid, do not send this request
3765 packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
3767 ErrPrint("Failed to create a packet\n");
3768 return LB_STATUS_ERROR_FAULT;
3771 return master_rpc_request_only(NULL, packet);
3774 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
3776 struct packet *packet;
3780 * Validate the group info using DB
3781 * If the group info is not valid, do not send this request
3782 * AND Check the subscribed or not too
3785 packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
3787 ErrPrint("Failed to create a packet\n");
3788 return LB_STATUS_ERROR_FAULT;
3791 return master_rpc_request_only(NULL, packet);
3794 EAPI int livebox_refresh(struct livebox *handler, int force)
3796 struct packet *packet;
3798 if (!handler || handler->state != CREATE) {
3799 ErrPrint("Handler is invalid\n");
3800 return LB_STATUS_ERROR_INVALID;
3803 if (!handler->common || handler->common->state != CREATE) {
3804 ErrPrint("Handler is not valid\n");
3805 return LB_STATUS_ERROR_INVALID;
3808 if (!handler->common->id) {
3809 ErrPrint("Handler is not valid\n");
3810 return LB_STATUS_ERROR_INVALID;
3813 packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
3815 ErrPrint("Failed to create a packet\n");
3816 return LB_STATUS_ERROR_FAULT;
3819 return master_rpc_request_only(handler, packet);
3822 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
3824 struct packet *packet;
3826 if (!cluster || !category) {
3827 ErrPrint("Invalid argument\n");
3828 return LB_STATUS_ERROR_INVALID;
3831 packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
3833 ErrPrint("Failed to create a packet\n");
3834 return LB_STATUS_ERROR_FAULT;
3837 return master_rpc_request_only(NULL, packet);
3840 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
3845 if (!handler || handler->state != CREATE) {
3846 ErrPrint("Handler is invalid\n");
3847 return LB_STATUS_ERROR_INVALID;
3850 if (!handler->common || handler->common->state != CREATE) {
3851 ErrPrint("Handler is not valid\n");
3852 return LB_STATUS_ERROR_INVALID;
3855 if (!handler->common->id) {
3856 ErrPrint("Handler is not valid\n");
3857 return LB_STATUS_ERROR_INVALID;
3860 if (!handler->common->is_user) {
3861 /* System cluster livebox cannot be changed its visible states */
3862 if (state == LB_HIDE_WITH_PAUSE) {
3863 ErrPrint("CA Livebox is not able to change the visibility\n");
3864 return LB_STATUS_ERROR_PERMISSION;
3868 DbgPrint("[%s] Change visiblity to 0x%x\n", handler->common->pkgname, state);
3870 if (handler->visible == state) {
3871 DbgPrint("%s has no changes\n", handler->common->pkgname);
3872 return LB_STATUS_ERROR_ALREADY;
3875 old_state = handler->visible;
3876 handler->visible = state;
3878 ret = lb_set_visibility(handler, state);
3880 handler->visible = old_state;
3886 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
3888 if (!handler || handler->state != CREATE) {
3889 ErrPrint("Handler is invalid\n");
3890 return LB_VISIBLE_ERROR;
3893 if (!handler->common || handler->common->state != CREATE) {
3894 ErrPrint("Handler is not valid\n");
3895 return LB_VISIBLE_ERROR;
3898 if (!handler->common->id) {
3899 ErrPrint("Handler is not valid\n");
3900 return LB_VISIBLE_ERROR;
3903 return handler->visible;
3906 int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
3912 pc = strdup(cluster);
3914 ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
3915 return LB_STATUS_ERROR_MEMORY;
3920 ps = strdup(category);
3922 ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
3924 return LB_STATUS_ERROR_MEMORY;
3928 if (common->cluster) {
3929 free(common->cluster);
3932 if (common->category) {
3933 free(common->category);
3936 common->cluster = pc;
3937 common->category = ps;
3939 return LB_STATUS_SUCCESS;
3942 void lb_set_size(struct livebox_common *common, int w, int h)
3944 common->lb.width = w;
3945 common->lb.height = h;
3948 void lb_set_update_mode(struct livebox_common *common, int active_mode)
3950 common->is_active_update = active_mode;
3953 void lb_set_pdsize(struct livebox_common *common, int w, int h)
3955 common->pd.width = w;
3956 common->pd.height = h;
3959 void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
3961 common->pd.default_width = w;
3962 common->pd.default_height = h;
3965 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
3969 struct fault_info *info;
3971 s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
3973 dlist_foreach_safe(s_info.fault_list, l, n, info) {
3974 if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
3975 info->is_deleted = 1;
3978 if (info->is_deleted) {
3979 s_info.fault_list = dlist_remove(s_info.fault_list, l);
3984 s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
3987 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
3991 struct event_info *info;
3993 if (event == LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
3994 if (handler->visible != LB_SHOW) {
3995 DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
3996 handler->paused_updating++;
3999 handler->paused_updating = 0;
4003 s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4005 dlist_foreach_safe(s_info.event_list, l, n, info) {
4006 if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
4007 DbgPrint("Event handler returns EXIT_FAILURE\n");
4008 info->is_deleted = 1;
4011 if (info->is_deleted) {
4012 s_info.event_list = dlist_remove(s_info.event_list, l);
4017 s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4020 struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
4023 struct livebox_common *common;
4025 dlist_foreach(s_info.livebox_common_list, l, common) {
4030 if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
4038 struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
4041 struct livebox_common *common;
4043 dlist_foreach(s_info.livebox_common_list, l, common) {
4044 if (common->timestamp == timestamp) {
4052 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
4054 struct livebox *handler;
4056 handler = calloc(1, sizeof(*handler));
4058 ErrPrint("Failed to create a new livebox\n");
4062 handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
4063 if (!handler->common) {
4064 ErrPrint("Heap: %s\n", strerror(errno));
4069 lb_common_ref(handler->common, handler);
4070 lb_set_id(handler->common, id);
4071 handler->common->timestamp = timestamp;
4072 handler->common->state = CREATE;
4073 handler->visible = LB_SHOW;
4074 s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
4076 return lb_ref(handler);
4079 int lb_delete_all(void)
4083 struct livebox *handler;
4085 dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
4086 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
4087 lb_unref(handler, 1);
4090 return LB_STATUS_SUCCESS;
4093 int lb_set_content(struct livebox_common *common, const char *content)
4098 pc = strdup(content);
4100 ErrPrint("heap: %s [%s]\n", strerror(errno), content);
4101 return LB_STATUS_ERROR_MEMORY;
4105 free(common->content);
4106 common->content = pc;
4107 return LB_STATUS_SUCCESS;
4110 int lb_set_title(struct livebox_common *common, const char *title)
4117 ErrPrint("heap: %s [%s]\n", strerror(errno), title);
4118 return LB_STATUS_ERROR_MEMORY;
4122 free(common->title);
4124 return LB_STATUS_SUCCESS;
4127 void lb_set_size_list(struct livebox_common *common, int size_list)
4129 common->lb.size_list = size_list;
4132 void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
4136 if (!auto_launch || !strlen(auto_launch)) {
4140 pa = strdup(auto_launch);
4142 ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
4146 free(common->lb.auto_launch);
4147 common->lb.auto_launch = pa;
4150 void lb_set_priority(struct livebox_common *common, double priority)
4152 common->lb.priority = priority;
4155 void lb_set_id(struct livebox_common *common, const char *id)
4162 ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
4171 void lb_set_filename(struct livebox_common *common, const char *filename)
4173 if (common->filename) {
4174 if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
4175 if (common->filename[0] && unlink(common->filename) < 0) {
4176 ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
4180 free(common->filename);
4183 common->filename = strdup(filename);
4184 if (!common->filename) {
4185 ErrPrint("Heap: %s\n", strerror(errno));
4189 void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
4194 if (icon && strlen(icon)) {
4195 _icon = strdup(icon);
4197 ErrPrint("Heap: %s\n", strerror(errno));
4201 if (name && strlen(name)) {
4202 _name = strdup(name);
4204 ErrPrint("Heap: %s\n", strerror(errno));
4208 free(common->alt.icon);
4209 common->alt.icon = _icon;
4211 free(common->alt.name);
4212 common->alt.name = _name;
4215 int lb_set_lb_fb(struct livebox_common *common, const char *filename)
4220 return LB_STATUS_ERROR_INVALID;
4224 if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
4225 return LB_STATUS_SUCCESS;
4228 common->lb.fb = NULL;
4230 if (!filename || filename[0] == '\0') {
4234 return LB_STATUS_SUCCESS;
4237 common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
4238 if (!common->lb.fb) {
4239 ErrPrint("Faield to create a FB\n");
4243 return LB_STATUS_ERROR_FAULT;
4250 return LB_STATUS_SUCCESS;
4253 int lb_set_pd_fb(struct livebox_common *common, const char *filename)
4257 if (!common || common->state != CREATE) {
4258 return LB_STATUS_ERROR_INVALID;
4262 if (fb && !strcmp(fb_id(fb), filename)) {
4263 /* BUFFER is not changed, just update the content */
4264 return LB_STATUS_ERROR_EXIST;
4266 common->pd.fb = NULL;
4268 if (!filename || filename[0] == '\0') {
4272 return LB_STATUS_SUCCESS;
4275 common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
4276 if (!common->pd.fb) {
4277 ErrPrint("Failed to create a FB\n");
4281 return LB_STATUS_ERROR_FAULT;
4287 return LB_STATUS_SUCCESS;
4290 struct fb_info *lb_get_lb_fb(struct livebox_common *common)
4292 return common->lb.fb;
4295 struct fb_info *lb_get_pd_fb(struct livebox_common *common)
4297 return common->pd.fb;
4300 void lb_set_user(struct livebox_common *common, int user)
4302 common->is_user = user;
4305 void lb_set_pinup(struct livebox_common *common, int pinup_supported)
4307 common->lb.pinup_supported = pinup_supported;
4310 void lb_set_text_lb(struct livebox_common *common)
4312 common->lb.type = _LB_TYPE_TEXT;
4315 void lb_set_text_pd(struct livebox_common *common)
4317 common->pd.type = _PD_TYPE_TEXT;
4320 int lb_text_lb(struct livebox_common *common)
4322 return common->lb.type == _LB_TYPE_TEXT;
4325 int lb_text_pd(struct livebox_common *common)
4327 return common->pd.type == _PD_TYPE_TEXT;
4330 void lb_set_period(struct livebox_common *common, double period)
4332 common->lb.period = period;
4335 struct livebox *lb_ref(struct livebox *handler)
4345 struct livebox *lb_unref(struct livebox *handler, int destroy_common)
4352 if (handler->refcnt > 0) {
4356 if (handler->cbs.created.cb) {
4357 handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
4358 handler->cbs.created.cb = NULL;
4359 handler->cbs.created.data = NULL;
4362 if (handler->cbs.deleted.cb) {
4363 handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
4364 handler->cbs.deleted.cb = NULL;
4365 handler->cbs.deleted.data = NULL;
4368 if (handler->cbs.pinup.cb) {
4369 handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
4370 handler->cbs.pinup.cb = NULL;
4371 handler->cbs.pinup.data = NULL;
4374 if (handler->cbs.group_changed.cb) {
4375 handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
4376 handler->cbs.group_changed.cb = NULL;
4377 handler->cbs.group_changed.data = NULL;
4380 if (handler->cbs.period_changed.cb) {
4381 handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
4382 handler->cbs.period_changed.cb = NULL;
4383 handler->cbs.period_changed.data = NULL;
4386 if (handler->cbs.size_changed.cb) {
4387 handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
4388 handler->cbs.size_changed.cb = NULL;
4389 handler->cbs.size_changed.data = NULL;
4392 if (handler->cbs.pd_created.cb) {
4393 handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
4394 handler->cbs.pd_created.cb = NULL;
4395 handler->cbs.pd_created.data = NULL;
4398 if (handler->cbs.pd_destroyed.cb) {
4399 handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
4400 handler->cbs.pd_destroyed.cb = NULL;
4401 handler->cbs.pd_destroyed.data = NULL;
4404 if (handler->cbs.update_mode.cb) {
4405 handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
4406 handler->cbs.update_mode.cb = NULL;
4407 handler->cbs.update_mode.data = NULL;
4410 if (handler->cbs.access_event.cb) {
4411 handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
4412 handler->cbs.access_event.cb = NULL;
4413 handler->cbs.access_event.data = NULL;
4416 if (handler->cbs.key_event.cb) {
4417 handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
4418 handler->cbs.key_event.cb = NULL;
4419 handler->cbs.key_event.data = NULL;
4422 if (handler->common->filename) {
4423 (void)util_unlink(handler->common->filename);
4426 dlist_remove_data(s_info.livebox_list, handler);
4428 handler->state = DESTROYED;
4429 if (lb_common_unref(handler->common, handler) == 0) {
4430 if (destroy_common) {
4433 * Lock file should be deleted after all callbacks are processed.
4435 lb_destroy_lock_file(handler->common, 0);
4436 lb_destroy_common_handle(handler->common);
4440 DbgPrint("Handler is released\n");
4444 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
4446 struct packet *packet;
4447 struct cb_info *cbinfo;
4450 if (handler->common->request.deleted) {
4451 ErrPrint("Already in-progress\n");
4453 cb(handler, LB_STATUS_SUCCESS, data);
4455 return LB_STATUS_ERROR_BUSY;
4459 cb = default_delete_cb;
4462 packet = packet_create("delete", "ssi", handler->common->pkgname, handler->common->id, type);
4464 ErrPrint("Failed to build a param\n");
4466 cb(handler, LB_STATUS_ERROR_FAULT, data);
4469 return LB_STATUS_ERROR_FAULT;
4472 cbinfo = create_cb_info(cb, data);
4474 packet_destroy(packet);
4475 ErrPrint("Failed to create cbinfo\n");
4477 cb(handler, LB_STATUS_ERROR_FAULT, data);
4480 return LB_STATUS_ERROR_FAULT;
4483 ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
4486 * Packet is destroyed by master_rpc_async_request.
4488 destroy_cb_info(cbinfo);
4491 cb(handler, LB_STATUS_ERROR_FAULT, data);
4494 handler->common->request.deleted = 1;
4500 EAPI int livebox_client_paused(void)
4502 struct packet *packet;
4504 packet = packet_create_noack("client_paused", "d", util_timestamp());
4506 ErrPrint("Failed to create a pause packet\n");
4507 return LB_STATUS_ERROR_FAULT;
4510 return master_rpc_request_only(NULL, packet);
4513 EAPI int livebox_client_resumed(void)
4515 struct packet *packet;
4517 packet = packet_create_noack("client_resumed", "d", util_timestamp());
4519 ErrPrint("Failed to create a resume packet\n");
4520 return LB_STATUS_ERROR_FAULT;
4523 return master_rpc_request_only(NULL, packet);
4526 EAPI int livebox_sync_lb_fb(struct livebox *handler)
4528 if (!handler || handler->state != CREATE) {
4529 ErrPrint("Invalid handle\n");
4530 return LB_STATUS_ERROR_INVALID;
4533 if (!handler->common || handler->common->state != CREATE) {
4534 ErrPrint("Invalid handle\n");
4535 return LB_STATUS_ERROR_INVALID;
4538 if (!handler->common->id) {
4539 return LB_STATUS_ERROR_INVALID;
4542 return lb_sync_lb_fb(handler->common);
4545 int lb_sync_lb_fb(struct livebox_common *common)
4549 if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
4550 (void)do_fb_lock(common->lb.lock_fd);
4551 ret = fb_sync(lb_get_lb_fb(common));
4552 (void)do_fb_unlock(common->lb.lock_fd);
4554 ret = fb_sync(lb_get_lb_fb(common));
4560 int lb_sync_pd_fb(struct livebox_common *common)
4564 if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
4565 (void)do_fb_lock(common->pd.lock_fd);
4566 ret = fb_sync(lb_get_pd_fb(common));
4567 (void)do_fb_unlock(common->pd.lock_fd);
4569 ret = fb_sync(lb_get_pd_fb(common));
4575 EAPI int livebox_sync_pd_fb(struct livebox *handler)
4577 if (!handler || handler->state != CREATE) {
4578 ErrPrint("Invalid handle\n");
4579 return LB_STATUS_ERROR_INVALID;
4582 if (!handler->common || handler->common->state != CREATE) {
4583 ErrPrint("Invalid handle\n");
4584 return LB_STATUS_ERROR_INVALID;
4587 if (!handler->common->id) {
4588 ErrPrint("Invalid handle\n");
4589 return LB_STATUS_ERROR_INVALID;
4592 return lb_sync_pd_fb(handler->common);
4595 EAPI const char *livebox_alt_icon(struct livebox *handler)
4597 if (!handler || handler->state != CREATE) {
4598 ErrPrint("Handler is not valid[%p]\n", handler);
4602 if (!handler->common || handler->common->state != CREATE) {
4603 ErrPrint("Handler is not valid\n");
4607 return handler->common->alt.icon;
4610 EAPI const char *livebox_alt_name(struct livebox *handler)
4612 if (!handler || handler->state != CREATE) {
4613 ErrPrint("Handler is not valid[%p]\n", handler);
4617 if (!handler->common || handler->common->state != CREATE) {
4618 ErrPrint("Handler is not valid\n");
4622 return handler->common->alt.name;
4625 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
4627 int ret = LB_STATUS_SUCCESS;
4630 if (!handler || handler->state != CREATE) {
4631 ErrPrint("Handler is not valid[%p]\n", handler);
4632 return LB_STATUS_ERROR_INVALID;
4635 if (!handler->common || handler->common->state != CREATE) {
4636 ErrPrint("Handler is not valid\n");
4637 return LB_STATUS_ERROR_INVALID;
4640 if (!handler->common->id) {
4641 ErrPrint("Handler is not valid[%p]\n", handler);
4642 return LB_STATUS_ERROR_INVALID;
4646 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4647 DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4648 return LB_STATUS_ERROR_INVALID;
4651 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4652 return LB_STATUS_SUCCESS;
4655 fd = handler->common->pd.lock_fd;
4657 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4658 DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4659 return LB_STATUS_ERROR_INVALID;
4662 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4663 return LB_STATUS_SUCCESS;
4666 fd = handler->common->lb.lock_fd;
4669 ret = do_fb_lock(fd);
4671 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4674 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
4676 int ret = LB_STATUS_SUCCESS;
4679 if (!handler || handler->state != CREATE) {
4680 ErrPrint("Invalid handle\n");
4681 return LB_STATUS_ERROR_INVALID;
4684 if (!handler->common || handler->common->state != CREATE) {
4685 ErrPrint("Invalid handle\n");
4686 return LB_STATUS_ERROR_INVALID;
4689 if (!handler->common->id) {
4690 ErrPrint("Handler is not valid[%p]\n", handler);
4691 return LB_STATUS_ERROR_INVALID;
4695 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4696 DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4697 return LB_STATUS_ERROR_INVALID;
4700 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4701 return LB_STATUS_SUCCESS;
4704 fd = handler->common->pd.lock_fd;
4706 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4707 DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4708 return LB_STATUS_ERROR_INVALID;
4711 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4712 return LB_STATUS_SUCCESS;
4715 fd = handler->common->lb.lock_fd;
4718 ret = do_fb_unlock(fd);
4720 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4723 EAPI int livebox_set_option(enum livebox_option_type option, int state)
4725 int ret = LB_STATUS_SUCCESS;
4728 case LB_OPTION_MANUAL_SYNC:
4729 conf_set_manual_sync(state);
4731 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4732 conf_set_frame_drop_for_resizing(state);
4734 case LB_OPTION_SHARED_CONTENT:
4735 conf_set_shared_content(state);
4738 ret = LB_STATUS_ERROR_INVALID;
4745 EAPI int livebox_option(enum livebox_option_type option)
4750 case LB_OPTION_MANUAL_SYNC:
4751 ret = conf_manual_sync();
4753 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4754 ret = conf_frame_drop_for_resizing();
4756 case LB_OPTION_SHARED_CONTENT:
4757 ret = conf_shared_content();
4760 ret = LB_STATUS_ERROR_INVALID;