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;
1317 if (common->filename) {
1318 (void)util_unlink(common->filename);
1321 free(common->cluster);
1322 free(common->category);
1324 free(common->pkgname);
1325 free(common->filename);
1326 free(common->lb.auto_launch);
1327 free(common->alt.icon);
1328 free(common->alt.name);
1330 if (common->lb.fb) {
1331 fb_destroy(common->lb.fb);
1332 common->lb.fb = NULL;
1335 if (common->pd.fb) {
1336 fb_destroy(common->pd.fb);
1337 common->pd.fb = NULL;
1343 int lb_common_ref(struct livebox_common *common, struct livebox *handle)
1345 common->livebox_list = dlist_append(common->livebox_list, handle);
1348 return common->refcnt;
1351 int lb_common_unref(struct livebox_common *common, struct livebox *handle)
1354 dlist_remove_data(common->livebox_list, handle);
1355 refcnt = --common->refcnt;
1360 static void refresh_for_paused_updating_cb(struct livebox *handle, int ret, void *data)
1362 if (handle->paused_updating == 0) {
1363 DbgPrint("Paused updates are cleared\n");
1367 DbgPrint("Pending updates are found\n");
1368 lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
1371 static int lb_set_visibility(struct livebox *handler, enum livebox_visible_state state)
1373 struct packet *packet;
1374 int need_to_add_job = 0;
1377 if (handler->common->visible != LB_SHOW && state == LB_SHOW) {
1378 need_to_add_job = !!handler->paused_updating;
1379 } else if (handler->common->visible == LB_SHOW && state != LB_SHOW) {
1381 struct livebox *item;
1383 dlist_foreach(handler->common->livebox_list, l, item) {
1384 if (item->visible == LB_SHOW) {
1385 DbgPrint("%s visibility is not changed\n", handler->common->pkgname);
1386 return LB_STATUS_SUCCESS;
1389 } else if (handler->common->visible == LB_SHOW && state == LB_SHOW && handler->paused_updating) {
1390 if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1391 ErrPrint("Unable to add a new job for refreshing box\n");
1394 return LB_STATUS_SUCCESS;
1398 * No need to send this to the master
1400 return LB_STATUS_SUCCESS;
1403 packet = packet_create_noack("change,visibility", "ssi", handler->common->pkgname, handler->common->id, (int)state);
1405 ErrPrint("Failed to create a packet\n");
1406 return LB_STATUS_ERROR_FAULT;
1409 ret = master_rpc_request_only(handler, packet);
1410 if (ret == LB_STATUS_SUCCESS) {
1411 DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state);
1412 handler->common->visible = state;
1414 if (need_to_add_job) {
1415 if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1416 ErrPrint("Unable to add a new job for refreshing box\n");
1424 EAPI struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data)
1427 struct livebox *handler;
1431 if (!pkgname || !cluster || !category) {
1432 ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
1433 pkgname, cluster, category);
1437 lbid = lb_pkgname(pkgname);
1439 ErrPrint("Invalid package: %s\n", pkgname);
1443 if (livebox_service_is_enabled(lbid) == 0) {
1444 DbgPrint("Livebox [%s](%s) is disabled package\n", lbid, pkgname);
1449 if (type != LB_SIZE_TYPE_UNKNOWN) {
1450 (void)livebox_service_get_size(type, &w, &h);
1453 handler = calloc(1, sizeof(*handler));
1455 ErrPrint("Error: %s\n", strerror(errno));
1461 cb = default_create_cb;
1464 handler->common = find_sharable_common_handle(lbid, content, w, h, cluster, category);
1465 if (!handler->common) {
1466 handler->common = lb_create_common_handle(handler, lbid, cluster, category);
1468 if (!handler->common) {
1469 ErrPrint("Failed to find common handle\n");
1474 if (!content || !strlen(content)) {
1478 * I know the content should not be modified. use it temporarly without "const"
1480 pc = livebox_service_content(handler->common->pkgname);
1481 lb_set_content(handler->common, pc);
1484 lb_set_content(handler->common, content);
1487 lb_set_period(handler->common, period);
1488 lb_set_size(handler->common, w, h);
1489 lb_common_ref(handler->common, handler);
1491 if (create_real_instance(handler, cb, data) < 0) {
1492 if (lb_common_unref(handler->common, handler) == 0) {
1496 lb_destroy_common_handle(handler->common);
1497 handler->common = NULL;
1505 lb_common_ref(handler->common, handler);
1507 if (handler->common->request.created) {
1509 * If a box is in creating, wait its result too
1511 handler->cbs.created.cb = cb;
1512 handler->cbs.created.data = data;
1515 * or fire the fake created_event
1517 if (create_fake_instance(handler, cb, data) < 0) {
1518 if (lb_common_unref(handler->common, handler) == 0) {
1522 lb_destroy_common_handle(handler->common);
1530 handler->visible = LB_SHOW;
1531 handler->state = CREATE;
1532 handler = lb_ref(handler);
1534 if (handler->common->visible != LB_SHOW) {
1535 lb_set_visibility(handler, LB_SHOW);
1541 EAPI double livebox_period(struct livebox *handler)
1543 if (!handler || handler->state != CREATE) {
1544 ErrPrint("Handler is not valid\n");
1548 if (!handler->common || handler->common->state != CREATE) {
1549 ErrPrint("Invalid handle\n");
1553 if (!handler->common->id) {
1554 ErrPrint("Hnalder is not valid\n");
1558 return handler->common->lb.period;
1561 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
1563 struct packet *packet;
1566 if (!handler || handler->state != CREATE) {
1567 ErrPrint("Handler is not valid\n");
1568 return LB_STATUS_ERROR_INVALID;
1571 if (!handler->common || handler->common->state != CREATE) {
1572 ErrPrint("Invalid handle\n");
1573 return LB_STATUS_ERROR_INVALID;
1576 if (!handler->common->id) {
1577 ErrPrint("Handler is not valid\n");
1578 return LB_STATUS_ERROR_INVALID;
1581 if (handler->common->request.period_changed) {
1582 ErrPrint("Previous request for changing period is not finished\n");
1583 return LB_STATUS_ERROR_BUSY;
1586 if (!handler->common->is_user) {
1587 ErrPrint("CA Livebox is not able to change the period\n");
1588 return LB_STATUS_ERROR_PERMISSION;
1591 if (handler->common->lb.period == period) {
1592 DbgPrint("No changes\n");
1593 return LB_STATUS_ERROR_ALREADY;
1596 packet = packet_create("set_period", "ssd", handler->common->pkgname, handler->common->id, period);
1598 ErrPrint("Failed to build a packet %s\n", handler->common->pkgname);
1599 return LB_STATUS_ERROR_FAULT;
1603 cb = default_period_changed_cb;
1606 ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
1607 if (ret == LB_STATUS_SUCCESS) {
1608 handler->cbs.period_changed.cb = cb;
1609 handler->cbs.period_changed.data = data;
1610 handler->common->request.period_changed = 1;
1616 static void lb_update_visibility(struct livebox_common *old_common)
1619 struct livebox *item;
1622 dlist_foreach(old_common->livebox_list, l, item) {
1623 if (item->visible == LB_SHOW) {
1631 l = dlist_nth(old_common->livebox_list, 0);
1632 item = dlist_data(l);
1635 lb_set_visibility(item, LB_HIDE_WITH_PAUSE);
1637 ErrPrint("Unable to get the valid handle from common handler\n");
1640 lb_set_visibility(item, LB_SHOW);
1646 * The second parameter should be the "return value",
1647 * But in this case, we will use it for "type of deleting instance".
1649 static void job_del_cb(struct livebox *handle, int type, void *data)
1651 struct cb_info *cbinfo = data;
1654 if (handle->visible == LB_SHOW) {
1655 lb_update_visibility(handle->common);
1659 data = cbinfo->data;
1660 destroy_cb_info(cbinfo);
1662 if (handle->common->state != CREATE) {
1663 DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt);
1665 cb(handle, LB_STATUS_SUCCESS, data);
1671 if (handle->common->refcnt == 1) {
1672 handle->common->delete_type = type;
1673 handle->common->state = DELETE;
1675 if (!handle->common->id) {
1678 * The id is not determined yet.
1679 * It means a user didn't receive created event yet.
1680 * Then just stop to delete procedure from here.
1681 * Because the "created" event handle will release this.
1682 * By the way, if the user adds any callback for getting return status of this,
1686 cb(handle, LB_STATUS_SUCCESS, data);
1690 DbgPrint("Send delete request\n");
1691 lb_send_delete(handle, type, cb, data);
1694 cb(handle, LB_STATUS_SUCCESS, data);
1697 DbgPrint("Before unref: %d\n", handle->common->refcnt);
1698 lb_unref(handle, 1);
1702 EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data)
1704 struct cb_info *cbinfo;
1707 ErrPrint("Handler is NIL\n");
1708 return LB_STATUS_ERROR_INVALID;
1711 if (handler->state != CREATE) {
1712 ErrPrint("Handler is already deleted\n");
1713 return LB_STATUS_ERROR_INVALID;
1716 handler->state = DELETE;
1718 cbinfo = create_cb_info(cb, data);
1720 ErrPrint("Failed to create a cbinfo\n");
1721 return LB_STATUS_ERROR_MEMORY;
1724 if (job_add(handler, job_del_cb, type, cbinfo) != LB_STATUS_SUCCESS) {
1725 ErrPrint("Failed to add a new job\n");
1726 destroy_cb_info(cbinfo);
1727 return LB_STATUS_ERROR_FAULT;
1730 return LB_STATUS_SUCCESS;
1733 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
1735 return livebox_del_NEW(handler, LB_DELETE_PERMANENTLY, cb, data);
1738 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
1740 struct fault_info *info;
1743 return LB_STATUS_ERROR_INVALID;
1746 info = malloc(sizeof(*info));
1748 ErrPrint("Heap: %s\n", strerror(errno));
1749 return LB_STATUS_ERROR_MEMORY;
1753 info->user_data = data;
1754 info->is_deleted = 0;
1756 s_info.fault_list = dlist_append(s_info.fault_list, info);
1757 return LB_STATUS_SUCCESS;
1760 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
1762 struct fault_info *info;
1765 dlist_foreach(s_info.fault_list, l, info) {
1766 if (info->handler == cb) {
1769 data = info->user_data;
1771 if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1772 info->is_deleted = 1;
1774 s_info.fault_list = dlist_remove(s_info.fault_list, l);
1785 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
1787 struct event_info *info;
1790 ErrPrint("Invalid argument cb is nil\n");
1791 return LB_STATUS_ERROR_INVALID;
1794 info = malloc(sizeof(*info));
1796 ErrPrint("Heap: %s\n", strerror(errno));
1797 return LB_STATUS_ERROR_MEMORY;
1801 info->user_data = data;
1802 info->is_deleted = 0;
1804 s_info.event_list = dlist_append(s_info.event_list, info);
1805 return LB_STATUS_SUCCESS;
1808 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
1810 struct event_info *info;
1813 dlist_foreach(s_info.event_list, l, info) {
1814 if (info->handler == cb) {
1817 data = info->user_data;
1819 if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1820 info->is_deleted = 1;
1822 s_info.event_list = dlist_remove(s_info.event_list, l);
1833 EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data)
1835 struct packet *packet;
1838 if (!handler || handler->state != CREATE) {
1839 ErrPrint("Handler is Invalid\n");
1840 return LB_STATUS_ERROR_INVALID;
1843 if (!handler->common || handler->common->state != CREATE) {
1844 ErrPrint("Handler is Invalid\n");
1845 return LB_STATUS_ERROR_INVALID;
1848 if (!handler->common->id) {
1849 ErrPrint("Handler is Invalid\n");
1850 return LB_STATUS_ERROR_INVALID;
1853 if (handler->common->request.update_mode) {
1854 ErrPrint("Previous update_mode cb is not finished yet\n");
1855 return LB_STATUS_ERROR_BUSY;
1858 if (handler->common->is_active_update == active_update) {
1859 return LB_STATUS_ERROR_ALREADY;
1862 if (!handler->common->is_user) {
1863 return LB_STATUS_ERROR_PERMISSION;
1866 packet = packet_create("update_mode", "ssi", handler->common->pkgname, handler->common->id, active_update);
1868 return LB_STATUS_ERROR_FAULT;
1872 cb = default_update_mode_cb;
1875 ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL);
1876 if (ret == LB_STATUS_SUCCESS) {
1877 handler->cbs.update_mode.cb = cb;
1878 handler->cbs.update_mode.data = data;
1879 handler->common->request.update_mode = 1;
1885 EAPI int livebox_is_active_update(struct livebox *handler)
1887 if (!handler || handler->state != CREATE) {
1888 ErrPrint("Handler is Invalid\n");
1889 return LB_STATUS_ERROR_INVALID;
1892 if (!handler->common || handler->common->state != CREATE) {
1893 ErrPrint("Handler is Invalid\n");
1894 return LB_STATUS_ERROR_INVALID;
1897 if (!handler->common->id) {
1898 return LB_STATUS_ERROR_INVALID;
1901 return handler->common->is_active_update;
1904 static void resize_job_cb(struct livebox *handler, int ret, void *data)
1906 struct cb_info *info = data;
1909 info->cb(handler, ret, info->data);
1916 * Forcely update the box
1918 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
1921 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
1923 struct livebox_common *common;
1930 * If this handle is host instance or link instance,
1931 * Create a new instance or find another linkable instance.
1934 if (!handler || handler->state != CREATE) {
1935 ErrPrint("Handler is not valid\n");
1936 return LB_STATUS_ERROR_INVALID;
1939 if (!handler->common || handler->common->state != CREATE) {
1940 ErrPrint("Invalid handle\n");
1941 return LB_STATUS_ERROR_INVALID;
1944 if (!handler->common->id) {
1945 ErrPrint("Handler is not valid\n");
1946 return LB_STATUS_ERROR_INVALID;
1951 * resize operation should be separated by each handler.
1952 * If a handler is resizing, the other handler can request resize too.
1953 * So we should not use the common->request.size_changed flag.
1955 if (handler->cbs.size_changed.cb) {
1956 ErrPrint("Previous resize request is not finished yet\n");
1957 return LB_STATUS_ERROR_BUSY;
1960 if (livebox_service_get_size(type, &w, &h) != 0) {
1961 ErrPrint("Invalid size type\n");
1962 return LB_STATUS_ERROR_INVALID;
1965 if (handler->common->lb.width == w && handler->common->lb.height == h) {
1966 DbgPrint("No changes\n");
1967 return LB_STATUS_ERROR_ALREADY;
1970 if (!handler->common->is_user) {
1971 ErrPrint("CA Livebox is not able to be resized\n");
1972 return LB_STATUS_ERROR_PERMISSION;
1975 if (handler->common->refcnt <= 1) {
1976 struct packet *packet;
1978 /* Only 1 instance */
1979 packet = packet_create("resize", "ssii", handler->common->pkgname, handler->common->id, w, h);
1981 ErrPrint("Failed to build param\n");
1982 return LB_STATUS_ERROR_FAULT;
1986 cb = default_lb_size_changed_cb;
1989 ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
1990 if (ret == LB_STATUS_SUCCESS) {
1991 handler->cbs.size_changed.cb = cb;
1992 handler->cbs.size_changed.data = data;
1993 handler->common->request.size_changed = 1;
1996 common = find_sharable_common_handle(handler->common->pkgname, handler->common->content, w, h, handler->common->cluster, handler->common->category);
1998 struct livebox_common *old_common;
2001 * If the common handler is in resizing,
2002 * if user tries to resize a hander, then simply create new one even if the requested size is same with this.
2004 if (handler->common->request.size_changed) {
2009 old_common = handler->common;
2011 common = lb_create_common_handle(handler, old_common->pkgname, old_common->cluster, old_common->category);
2013 ErrPrint("Failed to create common handle\n");
2014 return LB_STATUS_ERROR_FAULT;
2017 lb_set_size(common, w, h);
2018 lb_set_content(common, old_common->content);
2019 lb_set_period(common, old_common->lb.period);
2023 * Disconnecting from old one.
2025 if (lb_common_unref(old_common, handler) == 0) {
2030 ErrPrint("Common has no associated handler\n");
2033 lb_common_ref(common, handler);
2036 * Connect to a new one
2038 handler->common = common;
2042 * Need to care, if it fails to create a common handle,
2043 * the resize operation will be failed.
2044 * in that case, we should reuse the old common handle
2046 ret = create_real_instance(handler, cb, data);
2048 lb_common_unref(common, handler);
2049 lb_destroy_common_handle(common);
2051 lb_common_ref(old_common, handler);
2052 handler->common = old_common;
2055 * In this case, we should update visibility of old_common's liveboxes
2057 if (handler->visible == LB_SHOW) {
2058 lb_update_visibility(old_common);
2062 struct cb_info *cbinfo;
2064 cbinfo = create_cb_info(cb, data);
2066 ErrPrint("Failed to create a cbinfo\n");
2067 ret = LB_STATUS_ERROR_MEMORY;
2069 ret = job_add(handler, resize_job_cb, LB_STATUS_SUCCESS, cbinfo);
2070 if (ret == LB_STATUS_SUCCESS) {
2071 struct livebox_common *old_common;
2073 old_common = handler->common;
2075 if (lb_common_unref(handler->common, handler) == 0) {
2076 ErrPrint("Old common has no associated handler\n");
2079 lb_common_ref(common, handler);
2080 handler->common = common;
2082 if (handler->visible == LB_SHOW) {
2083 lb_update_visibility(old_common); /* To update visibility: Show --> Paused */
2084 lb_update_visibility(common); /* To update visibility: Paused --> Show */
2087 destroy_cb_info(cbinfo);
2096 EAPI int livebox_click(struct livebox *handler, double x, double y)
2098 struct packet *packet;
2102 if (!handler || handler->state != CREATE) {
2103 ErrPrint("Handler is invalid\n");
2104 return LB_STATUS_ERROR_INVALID;
2107 if (!handler->common || handler->common->state != CREATE) {
2108 ErrPrint("Handler is invalid\n");
2109 return LB_STATUS_ERROR_INVALID;
2112 if (!handler->common->id) {
2113 ErrPrint("Handler is not valid\n");
2114 return LB_STATUS_ERROR_INVALID;
2117 if (handler->common->lb.auto_launch) {
2121 DbgPrint("AUTO_LAUNCH [%s]\n", handler->common->lb.auto_launch);
2123 ret = service_create(&service);
2124 if (ret == SERVICE_ERROR_NONE) {
2125 service_set_package(service, handler->common->lb.auto_launch);
2126 service_send_launch_request(service, NULL, NULL);
2127 service_destroy(service);
2129 ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
2132 ret = aul_launch_app(handler->common->lb.auto_launch, NULL);
2134 ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
2138 timestamp = util_timestamp();
2139 DbgPrint("CLICKED: %lf\n", timestamp);
2141 packet = packet_create_noack("clicked", "sssddd", handler->common->pkgname, handler->common->id, "clicked", timestamp, x, y);
2143 ErrPrint("Failed to build param\n");
2144 return LB_STATUS_ERROR_FAULT;
2147 ret = master_rpc_request_only(handler, packet);
2149 if (!handler->common->lb.mouse_event && (handler->common->lb.type == _LB_TYPE_BUFFER || handler->common->lb.type == _LB_TYPE_SCRIPT)) {
2150 int ret; /* Shadow variable */
2151 ret = send_mouse_event(handler, "lb_mouse_down", x * handler->common->lb.width, y * handler->common->lb.height);
2153 ErrPrint("Failed to send Down: %d\n", ret);
2156 ret = send_mouse_event(handler, "lb_mouse_move", x * handler->common->lb.width, y * handler->common->lb.height);
2158 ErrPrint("Failed to send Move: %d\n", ret);
2161 ret = send_mouse_event(handler, "lb_mouse_up", x * handler->common->lb.width, y * handler->common->lb.height);
2163 ErrPrint("Failed to send Up: %d\n", ret);
2170 EAPI int livebox_has_pd(struct livebox *handler)
2172 if (!handler || handler->state != CREATE) {
2173 ErrPrint("Handler is invalid\n");
2174 return LB_STATUS_ERROR_INVALID;
2177 if (!handler->common || handler->common->state != CREATE) {
2178 ErrPrint("Handler is invalid\n");
2179 return LB_STATUS_ERROR_INVALID;
2182 if (!handler->common->id) {
2183 ErrPrint("Handler is not valid\n");
2184 return LB_STATUS_ERROR_INVALID;
2187 return !!handler->common->pd.fb;
2190 EAPI int livebox_pd_is_created(struct livebox *handler)
2192 if (!handler || handler->state != CREATE) {
2193 ErrPrint("Handler is invalid\n");
2194 return LB_STATUS_ERROR_INVALID;
2197 if (!handler->common || handler->common->state != CREATE) {
2198 ErrPrint("Handler is invalid\n");
2199 return LB_STATUS_ERROR_INVALID;
2202 if (!handler->common->pd.fb || !handler->common->id) {
2203 ErrPrint("Handler is not valid\n");
2204 return LB_STATUS_ERROR_INVALID;
2207 return handler->common->is_pd_created;
2210 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
2212 return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
2215 static void turn_off_pd_destroyed_flag_cb(struct livebox *handler, int ret, void *data)
2217 if (handler->common->request.pd_destroyed) {
2221 DbgPrint("pd_destroyed request is canceled\n");
2222 handler->common->request.pd_destroyed = 0;
2223 cb = handler->cbs.pd_destroyed.cb;
2224 data = handler->cbs.pd_destroyed.data;
2225 handler->cbs.pd_destroyed.cb = NULL;
2226 handler->cbs.pd_destroyed.data = NULL;
2229 cb(handler, ret, data);
2234 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
2236 struct packet *packet;
2239 if (!handler || handler->state != CREATE) {
2240 ErrPrint("Handler is invalid\n");
2241 return LB_STATUS_ERROR_INVALID;
2244 if (!handler->common || handler->common->state != CREATE) {
2245 ErrPrint("Handler is invalid\n");
2246 return LB_STATUS_ERROR_INVALID;
2249 if (!handler->common->pd.fb || !handler->common->id) {
2250 ErrPrint("Handler is not valid\n");
2251 return LB_STATUS_ERROR_INVALID;
2256 * Only one handler can have a PD
2258 if (handler->common->is_pd_created) {
2259 DbgPrint("PD is already created\n");
2260 return LB_STATUS_SUCCESS;
2263 if (handler->common->request.pd_created) {
2264 ErrPrint("Previous request is not completed yet\n");
2265 return LB_STATUS_ERROR_BUSY;
2270 * Turn off the pd_destroyed request flag
2272 if (handler->common->request.pd_destroyed) {
2273 if (job_add(handler, turn_off_pd_destroyed_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2274 ErrPrint("Failed to add pd_destroyed job\n");
2278 packet = packet_create("create_pd", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2280 ErrPrint("Failed to build param\n");
2281 return LB_STATUS_ERROR_FAULT;
2285 cb = default_pd_created_cb;
2288 DbgPrint("PERF_DBOX\n");
2289 ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
2290 if (ret == LB_STATUS_SUCCESS) {
2291 handler->cbs.pd_created.cb = cb;
2292 handler->cbs.pd_created.data = data;
2293 handler->common->request.pd_created = 1;
2299 EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
2301 struct packet *packet;
2303 if (!handler || handler->state != CREATE) {
2304 ErrPrint("Handler is invalid\n");
2305 return LB_STATUS_ERROR_INVALID;
2308 if (!handler->common || handler->common->state != CREATE) {
2309 ErrPrint("Handler is invalid\n");
2310 return LB_STATUS_ERROR_INVALID;
2313 if (!handler->common->pd.fb || !handler->common->id) {
2314 ErrPrint("Handler is not valid\n");
2315 return LB_STATUS_ERROR_INVALID;
2318 if (!handler->common->is_pd_created) {
2319 ErrPrint("PD is not created\n");
2320 return LB_STATUS_ERROR_INVALID;
2323 packet = packet_create_noack("pd_move", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2325 ErrPrint("Failed to build param\n");
2326 return LB_STATUS_ERROR_FAULT;
2329 return master_rpc_request_only(handler, packet);
2332 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
2334 struct packet *packet;
2335 struct cb_info *cbinfo;
2339 return LB_STATUS_ERROR_INVALID;
2342 packet = packet_create("activate_package", "s", pkgname);
2344 ErrPrint("Failed to build a param\n");
2345 return LB_STATUS_ERROR_FAULT;
2348 cbinfo = create_cb_info(cb, data);
2350 ErrPrint("Unable to create cbinfo\n");
2351 packet_destroy(packet);
2352 return LB_STATUS_ERROR_FAULT;
2355 ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo);
2357 destroy_cb_info(cbinfo);
2363 static void turn_off_pd_created_flag_cb(struct livebox *handler, int ret, void *data)
2365 if (handler->common->request.pd_created) {
2369 DbgPrint("pd_created request is canceled\n");
2370 handler->common->request.pd_created = 0;
2371 cb = handler->cbs.pd_created.cb;
2372 data = handler->cbs.pd_created.data;
2373 handler->cbs.pd_created.cb = NULL;
2374 handler->cbs.pd_created.data = NULL;
2377 cb(handler, ret, data);
2382 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
2384 struct packet *packet;
2385 struct cb_info *cbinfo;
2388 if (!handler || handler->state != CREATE) {
2389 ErrPrint("Handler is invalid\n");
2390 return LB_STATUS_ERROR_INVALID;
2393 if (!handler->common || handler->common->state != CREATE) {
2394 ErrPrint("Handler is invalid\n");
2395 return LB_STATUS_ERROR_INVALID;
2398 if (!handler->common->pd.fb || !handler->common->id) {
2399 ErrPrint("Handler is not valid\n");
2400 return LB_STATUS_ERROR_INVALID;
2405 * Replace the callback check code.
2406 * Use the flag instead of callback.
2407 * the flag should be in the ADT "common"
2409 if (!handler->common->is_pd_created && !handler->common->request.pd_created) {
2410 ErrPrint("PD is not created\n");
2411 return LB_STATUS_ERROR_INVALID;
2414 if (handler->common->request.pd_destroyed) {
2415 ErrPrint("PD destroy request is already sent\n");
2416 return LB_STATUS_ERROR_ALREADY;
2421 * Disable the pd_created request flag
2423 if (handler->common->request.pd_created) {
2424 if (job_add(handler, turn_off_pd_created_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2425 ErrPrint("Failed to add a new job\n");
2429 DbgPrint("[%s]\n", handler->common->pkgname);
2431 packet = packet_create("destroy_pd", "ss", handler->common->pkgname, handler->common->id);
2433 ErrPrint("Failed to build a param\n");
2434 return LB_STATUS_ERROR_FAULT;
2438 cb = default_pd_destroyed_cb;
2441 cbinfo = create_cb_info(cb, data);
2443 packet_destroy(packet);
2444 return LB_STATUS_ERROR_FAULT;
2447 ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo);
2449 destroy_cb_info(cbinfo);
2451 handler->common->request.pd_destroyed = 1;
2457 EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data)
2461 char cmd[32] = { '\0', };
2465 if (!handler || handler->state != CREATE) {
2466 ErrPrint("Handler is invalid\n");
2467 return LB_STATUS_ERROR_INVALID;
2470 if (!handler->common || handler->common->state != CREATE) {
2471 ErrPrint("Handler is invalid\n");
2472 return LB_STATUS_ERROR_INVALID;
2475 if (!handler->common->id) {
2476 ErrPrint("Handler is not valid\n");
2477 return LB_STATUS_ERROR_INVALID;
2480 if (handler->common->request.access_event) {
2481 ErrPrint("Previous access event is not yet done\n");
2482 return LB_STATUS_ERROR_BUSY;
2485 if (type & ACCESS_EVENT_PD_MASK) {
2486 if (!handler->common->is_pd_created) {
2487 ErrPrint("PD is not created\n");
2488 return LB_STATUS_ERROR_INVALID;
2492 w = handler->common->pd.width;
2493 h = handler->common->pd.height;
2494 } else if (type & ACCESS_EVENT_LB_MASK) {
2497 w = handler->common->lb.width;
2498 h = handler->common->lb.height;
2500 ErrPrint("Invalid event type\n");
2501 return LB_STATUS_ERROR_INVALID;
2504 switch (type & ~ACCESS_EVENT_PD_MASK) {
2505 case ACCESS_EVENT_HIGHLIGHT:
2506 strcpy(ptr, "_access_hl");
2508 case ACCESS_EVENT_HIGHLIGHT_NEXT:
2509 strcpy(ptr, "_access_hl_next");
2511 case ACCESS_EVENT_HIGHLIGHT_PREV:
2512 strcpy(ptr, "_access_hl_prev");
2514 case ACCESS_EVENT_ACTIVATE:
2515 strcpy(ptr, "_access_activate");
2517 case ACCESS_EVENT_ACTION_DOWN:
2518 strcpy(ptr, "_access_action_down");
2520 case ACCESS_EVENT_ACTION_UP:
2521 strcpy(ptr, "_access_action_up");
2523 case ACCESS_EVENT_UNHIGHLIGHT:
2524 strcpy(ptr, "_access_unhighlight");
2526 case ACCESS_EVENT_SCROLL_DOWN:
2527 strcpy(ptr, "_access_scroll_down");
2529 case ACCESS_EVENT_SCROLL_MOVE:
2530 strcpy(ptr, "_access_scroll_move");
2532 case ACCESS_EVENT_SCROLL_UP:
2533 strcpy(ptr, "_access_scroll_up");
2536 return LB_STATUS_ERROR_INVALID;
2540 cb = default_access_event_cb;
2543 ret = send_access_event(handler, cmd, x * w, y * h);
2544 if (ret == LB_STATUS_SUCCESS) {
2545 handler->cbs.access_event.cb = cb;
2546 handler->cbs.access_event.data = data;
2547 handler->common->request.access_event = 1;
2553 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
2555 return livebox_mouse_event(handler, type, x, y);
2558 EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y)
2562 char cmd[32] = { '\0', };
2565 if (!handler || handler->state != CREATE) {
2566 ErrPrint("Handler is invalid\n");
2567 return LB_STATUS_ERROR_INVALID;
2570 if (!handler->common || handler->common->state != CREATE) {
2571 ErrPrint("Handler is invalid\n");
2572 return LB_STATUS_ERROR_INVALID;
2575 if (!handler->common->id) {
2576 ErrPrint("Handler is not valid\n");
2577 return LB_STATUS_ERROR_INVALID;
2580 if (!(type & CONTENT_EVENT_MOUSE_MASK)) {
2581 ErrPrint("Invalid content event is used\n");
2582 return LB_STATUS_ERROR_INVALID;
2585 if (type & CONTENT_EVENT_PD_MASK) {
2588 if (!handler->common->is_pd_created) {
2589 ErrPrint("PD is not created\n");
2590 return LB_STATUS_ERROR_INVALID;
2593 if (!handler->common->pd.fb) {
2594 ErrPrint("Handler is not valid\n");
2595 return LB_STATUS_ERROR_INVALID;
2598 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2599 if (fabs(x - handler->common->pd.x) < conf_event_filter() && fabs(y - handler->common->pd.y) < conf_event_filter()) {
2600 return LB_STATUS_ERROR_BUSY;
2602 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2607 w = handler->common->pd.width;
2608 h = handler->common->pd.height;
2609 handler->common->pd.x = x;
2610 handler->common->pd.y = y;
2614 } else if (type & CONTENT_EVENT_LB_MASK) {
2617 if (!handler->common->lb.mouse_event) {
2618 return LB_STATUS_ERROR_INVALID;
2621 if (!handler->common->lb.fb) {
2622 ErrPrint("Handler is not valid\n");
2623 return LB_STATUS_ERROR_INVALID;
2626 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2627 if (fabs(x - handler->common->lb.x) < conf_event_filter() && fabs(y - handler->common->lb.y) < conf_event_filter()) {
2628 return LB_STATUS_ERROR_BUSY;
2630 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2635 w = handler->common->lb.width;
2636 h = handler->common->lb.height;
2637 handler->common->lb.x = x;
2638 handler->common->lb.y = y;
2643 ErrPrint("Invalid event type\n");
2644 return LB_STATUS_ERROR_INVALID;
2648 * Must be short than 29 bytes.
2650 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2651 case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
2652 strcpy(ptr, "_mouse_enter");
2654 case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
2655 strcpy(ptr, "_mouse_leave");
2657 case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
2658 strcpy(ptr, "_mouse_up");
2660 case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
2661 strcpy(ptr, "_mouse_down");
2663 case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
2664 strcpy(ptr, "_mouse_move");
2666 case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
2667 strcpy(ptr, "_mouse_set");
2669 case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
2670 strcpy(ptr, "_mouse_unset");
2673 ErrPrint("Invalid event type\n");
2674 return LB_STATUS_ERROR_INVALID;
2677 return send_mouse_event(handler, cmd, x * w, y * h);
2680 EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data)
2682 char cmd[32] = { '\0', };
2686 if (!handler || handler->state != CREATE) {
2687 ErrPrint("Handler is invalid\n");
2688 return LB_STATUS_ERROR_INVALID;
2691 if (!handler->common || handler->common->state != CREATE) {
2692 ErrPrint("Handler is invalid\n");
2693 return LB_STATUS_ERROR_INVALID;
2696 if (!handler->common->id) {
2697 ErrPrint("Handler is not valid\n");
2698 return LB_STATUS_ERROR_INVALID;
2701 if (!(type & CONTENT_EVENT_KEY_MASK)) {
2702 ErrPrint("Invalid key event is used\n");
2703 return LB_STATUS_ERROR_INVALID;
2706 if (handler->common->request.key_event) {
2707 ErrPrint("Previous key event is not completed yet\n");
2708 return LB_STATUS_ERROR_BUSY;
2711 if (type & CONTENT_EVENT_PD_MASK) {
2712 if (!handler->common->is_pd_created) {
2713 ErrPrint("PD is not created\n");
2714 return LB_STATUS_ERROR_INVALID;
2717 if (!handler->common->pd.fb) {
2718 ErrPrint("Handler is not valid\n");
2719 return LB_STATUS_ERROR_INVALID;
2722 if (type & CONTENT_EVENT_KEY_DOWN) {
2725 * filtering the reproduced events if it is too fast
2727 } else if (type & CONTENT_EVENT_KEY_SET) {
2730 * What can I do for this case?
2736 } else if (type & CONTENT_EVENT_LB_MASK) {
2737 if (!handler->common->lb.mouse_event) {
2738 return LB_STATUS_ERROR_INVALID;
2741 if (!handler->common->lb.fb) {
2742 ErrPrint("Handler is not valid\n");
2743 return LB_STATUS_ERROR_INVALID;
2746 if (type & CONTENT_EVENT_KEY_DOWN) {
2749 * filtering the reproduced events if it is too fast
2751 } else if (type & CONTENT_EVENT_KEY_SET) {
2753 * What can I do for this case?
2760 ErrPrint("Invalid event type\n");
2761 return LB_STATUS_ERROR_INVALID;
2765 * Must be short than 29 bytes.
2767 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2768 case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK:
2769 strcpy(ptr, "_key_focus_in");
2771 case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK:
2772 strcpy(ptr, "_key_focus_out");
2774 case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
2775 strcpy(ptr, "_key_up");
2777 case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
2778 strcpy(ptr, "_key_down");
2780 case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK:
2781 strcpy(ptr, "_key_set");
2783 case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK:
2784 strcpy(ptr, "_key_unset");
2787 ErrPrint("Invalid event type\n");
2788 return LB_STATUS_ERROR_INVALID;
2792 cb = default_key_event_cb;
2795 ret = send_key_event(handler, cmd, keycode);
2796 if (ret == LB_STATUS_SUCCESS) {
2797 handler->cbs.key_event.cb = cb;
2798 handler->cbs.key_event.data = data;
2799 handler->common->request.key_event = 1;
2805 EAPI const char *livebox_filename(struct livebox *handler)
2807 if (!handler || handler->state != CREATE) {
2808 ErrPrint("Handler is invalid\n");
2812 if (!handler->common || handler->common->state != CREATE) {
2813 ErrPrint("Handler is invalid\n");
2817 if (!handler->common->id) {
2818 ErrPrint("Handler is not valid\n");
2822 if (handler->common->filename) {
2823 return handler->common->filename;
2827 return util_uri_to_path(handler->common->id);
2830 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
2835 if (!handler || handler->state != CREATE) {
2836 ErrPrint("Handler is invalid\n");
2837 return LB_STATUS_ERROR_INVALID;
2840 if (!handler->common || handler->common->state != CREATE) {
2841 ErrPrint("Handler is invalid\n");
2842 return LB_STATUS_ERROR_INVALID;
2845 if (!handler->common->id) {
2846 ErrPrint("Handler is not valid\n");
2847 return LB_STATUS_ERROR_INVALID;
2857 if (!handler->common->is_pd_created) {
2858 *w = handler->common->pd.default_width;
2859 *h = handler->common->pd.default_height;
2861 *w = handler->common->pd.width;
2862 *h = handler->common->pd.height;
2865 return LB_STATUS_SUCCESS;
2868 EAPI int livebox_size(struct livebox *handler)
2873 if (!handler || handler->state != CREATE) {
2874 ErrPrint("Handler is invalid\n");
2875 return LB_STATUS_ERROR_INVALID;
2878 if (!handler->common || handler->common->state != CREATE) {
2879 ErrPrint("Handler is invalid\n");
2880 return LB_STATUS_ERROR_INVALID;
2883 if (!handler->common->id) {
2884 ErrPrint("Handler is not valid\n");
2885 return LB_STATUS_ERROR_INVALID;
2888 w = handler->common->lb.width;
2889 h = handler->common->lb.height;
2891 switch (handler->common->lb.type) {
2892 case _LB_TYPE_BUFFER:
2893 case _LB_TYPE_SCRIPT:
2894 if (!fb_is_created(handler->common->lb.fb)) {
2903 return livebox_service_size_type(w, h);
2906 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
2908 struct packet *packet;
2912 ErrPrint("Handler is NIL\n");
2913 return LB_STATUS_ERROR_INVALID;
2916 if (!cluster || !category || handler->state != CREATE) {
2917 ErrPrint("Invalid argument\n");
2918 return LB_STATUS_ERROR_INVALID;
2921 if (!handler->common || handler->common->state != CREATE) {
2922 ErrPrint("Invalid argument\n");
2923 return LB_STATUS_ERROR_INVALID;
2926 if (!handler->common->id) {
2927 ErrPrint("Invalid argument\n");
2928 return LB_STATUS_ERROR_INVALID;
2931 if (handler->common->request.group_changed) {
2932 ErrPrint("Previous group changing request is not finished yet\n");
2933 return LB_STATUS_ERROR_BUSY;
2936 if (!handler->common->is_user) {
2937 ErrPrint("CA Livebox is not able to change the group\n");
2938 return LB_STATUS_ERROR_PERMISSION;
2941 if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) {
2942 DbgPrint("No changes\n");
2943 return LB_STATUS_ERROR_ALREADY;
2946 packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category);
2948 ErrPrint("Failed to build a param\n");
2949 return LB_STATUS_ERROR_FAULT;
2953 cb = default_group_changed_cb;
2956 ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
2957 if (ret == LB_STATUS_SUCCESS) {
2958 handler->cbs.group_changed.cb = cb;
2959 handler->cbs.group_changed.data = data;
2960 handler->common->request.group_changed = 1;
2966 EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category)
2969 ErrPrint("Handler is NIL\n");
2970 return LB_STATUS_ERROR_INVALID;
2973 if (!cluster || !category || handler->state != CREATE) {
2974 ErrPrint("Invalid argument\n");
2975 return LB_STATUS_ERROR_INVALID;
2978 if (!handler->common || handler->common->state != CREATE) {
2979 ErrPrint("Invalid argument\n");
2980 return LB_STATUS_ERROR_INVALID;
2983 if (!handler->common->id) {
2984 ErrPrint("Invalid argument\n");
2985 return LB_STATUS_ERROR_INVALID;
2988 *cluster = handler->common->cluster;
2989 *category = handler->common->category;
2990 return LB_STATUS_SUCCESS;
2993 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
2998 if (!handler || !size_list) {
2999 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
3000 return LB_STATUS_ERROR_INVALID;
3003 if (!cnt || handler->state != CREATE) {
3004 ErrPrint("Handler is not valid\n");
3005 return LB_STATUS_ERROR_INVALID;
3008 if (!handler->common || handler->common->state != CREATE) {
3009 ErrPrint("Handler is not valid\n");
3010 return LB_STATUS_ERROR_INVALID;
3013 if (!handler->common->id) {
3014 ErrPrint("Handler is not valid\n");
3015 return LB_STATUS_ERROR_INVALID;
3018 for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
3019 if (handler->common->lb.size_list & (0x01 << i)) {
3024 size_list[j++] = (0x01 << i);
3029 return LB_STATUS_SUCCESS;
3032 EAPI const char *livebox_pkgname(struct livebox *handler)
3035 ErrPrint("Handler is NIL\n");
3039 if (handler->state != CREATE) {
3040 ErrPrint("Handler is not valid\n");
3044 if (!handler->common || handler->common->state != CREATE) {
3045 ErrPrint("Handler is not valid\n");
3049 return handler->common->pkgname;
3052 EAPI double livebox_priority(struct livebox *handler)
3054 if (!handler || handler->state != CREATE) {
3055 ErrPrint("Handler is invalid\n");
3059 if (!handler->common || handler->common->state != CREATE) {
3060 ErrPrint("Handler is invalid\n");
3064 if (!handler->common->id) {
3065 ErrPrint("Handler is not valid (%p)\n", handler);
3069 return handler->common->lb.priority;
3072 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
3074 struct packet *packet;
3075 struct cb_info *cbinfo;
3078 packet = packet_create("delete_cluster", "s", cluster);
3080 ErrPrint("Failed to build a param\n");
3081 return LB_STATUS_ERROR_FAULT;
3084 cbinfo = create_cb_info(cb, data);
3086 packet_destroy(packet);
3087 return LB_STATUS_ERROR_FAULT;
3090 ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
3092 destroy_cb_info(cbinfo);
3098 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
3100 struct packet *packet;
3101 struct cb_info *cbinfo;
3104 packet = packet_create("delete_category", "ss", cluster, category);
3106 ErrPrint("Failed to build a param\n");
3107 return LB_STATUS_ERROR_FAULT;
3110 cbinfo = create_cb_info(cb, data);
3112 packet_destroy(packet);
3113 return LB_STATUS_ERROR_FAULT;
3116 ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
3118 destroy_cb_info(cbinfo);
3124 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
3126 if (!handler || handler->state != CREATE) {
3127 ErrPrint("Handler is invalid\n");
3128 return LB_TYPE_INVALID;
3131 if (!handler->common || handler->common->state != CREATE) {
3132 ErrPrint("Handler is invalid\n");
3133 return LB_TYPE_INVALID;
3136 if (!handler->common->id) {
3137 ErrPrint("Handler is not valid\n");
3138 return LB_TYPE_INVALID;
3141 switch (handler->common->lb.type) {
3143 return LB_TYPE_IMAGE;
3144 case _LB_TYPE_BUFFER:
3145 case _LB_TYPE_SCRIPT:
3148 id = fb_id(handler->common->lb.fb);
3149 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3150 return LB_TYPE_PIXMAP;
3153 return LB_TYPE_BUFFER;
3155 return LB_TYPE_TEXT;
3160 return LB_TYPE_INVALID;
3163 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
3165 if (!handler || handler->state != CREATE) {
3166 ErrPrint("Handler is invalid\n");
3167 return PD_TYPE_INVALID;
3170 if (!handler->common || handler->common->state != CREATE) {
3171 ErrPrint("Handler is invalid\n");
3172 return PD_TYPE_INVALID;
3175 if (!handler->common->id) {
3176 ErrPrint("Handler is not valid\n");
3177 return PD_TYPE_INVALID;
3180 switch (handler->common->pd.type) {
3182 return PD_TYPE_TEXT;
3183 case _PD_TYPE_BUFFER:
3184 case _PD_TYPE_SCRIPT:
3187 id = fb_id(handler->common->pd.fb);
3188 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3189 return PD_TYPE_PIXMAP;
3192 return PD_TYPE_BUFFER;
3197 return PD_TYPE_INVALID;
3200 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3203 ErrPrint("Handler is NIL\n");
3204 return LB_STATUS_ERROR_INVALID;
3207 if (handler->state != CREATE) {
3208 ErrPrint("Handler is not valid\n");
3209 return LB_STATUS_ERROR_INVALID;
3212 memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops));
3213 return LB_STATUS_SUCCESS;
3216 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3219 ErrPrint("Handler is NIL\n");
3220 return LB_STATUS_ERROR_INVALID;
3223 if (handler->state != CREATE) {
3224 ErrPrint("Handler is not valid\n");
3225 return LB_STATUS_ERROR_INVALID;
3228 memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops));
3229 return LB_STATUS_SUCCESS;
3232 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3234 if (!handler || handler->state != CREATE) {
3235 ErrPrint("Handler is invalid\n");
3236 return LB_STATUS_ERROR_INVALID;
3239 if (!handler->common || handler->common->state != CREATE) {
3240 ErrPrint("Handler is invalid\n");
3241 return LB_STATUS_ERROR_INVALID;
3244 if (!handler->common->id) {
3245 ErrPrint("Invalid handle\n");
3246 return LB_STATUS_ERROR_INVALID;
3249 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3250 ErrPrint("Handler is not valid type\n");
3251 return LB_STATUS_ERROR_INVALID;
3254 return lb_acquire_lb_pixmap(handler, cb, data);
3257 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
3259 struct packet *packet;
3261 if (!handler || pixmap == 0 || handler->state != CREATE) {
3262 ErrPrint("Handler is invalid [%d]\n", pixmap);
3263 return LB_STATUS_ERROR_INVALID;
3266 if (!handler->common || handler->common->state != CREATE) {
3267 ErrPrint("Handler is invalid\n");
3268 return LB_STATUS_ERROR_INVALID;
3271 if (!handler->common->id) {
3272 ErrPrint("Invalid handle\n");
3273 return LB_STATUS_ERROR_INVALID;
3276 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3277 ErrPrint("Handler is not valid type\n");
3278 return LB_STATUS_ERROR_INVALID;
3281 packet = packet_create_noack("lb_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
3283 ErrPrint("Failed to build a param\n");
3284 return LB_STATUS_ERROR_INVALID;
3287 return master_rpc_request_only(handler, packet);
3290 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3292 if (!handler || handler->state != CREATE) {
3293 ErrPrint("Handler is invalid\n");
3294 return LB_STATUS_ERROR_INVALID;
3297 if (!handler->common || handler->common->state != CREATE) {
3298 ErrPrint("Handler is invalid\n");
3299 return LB_STATUS_ERROR_INVALID;
3302 if (!handler->common->id) {
3303 ErrPrint("Invalid handle\n");
3304 return LB_STATUS_ERROR_INVALID;
3307 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3308 ErrPrint("Handler is not valid type\n");
3309 return LB_STATUS_ERROR_INVALID;
3312 return lb_acquire_pd_pixmap(handler, cb, data);
3315 EAPI int livebox_pd_pixmap(const struct livebox *handler)
3320 if (!handler || handler->state != CREATE) {
3321 ErrPrint("Handler is invalid\n");
3325 if (!handler->common || handler->common->state != CREATE) {
3326 ErrPrint("Handler is invalid\n");
3330 if (!handler->common->id) {
3331 ErrPrint("Invalid handler\n");
3335 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3336 ErrPrint("Invalid handler\n");
3340 id = fb_id(handler->common->pd.fb);
3341 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3342 ErrPrint("PIXMAP Id is not valid\n");
3349 EAPI int livebox_lb_pixmap(const struct livebox *handler)
3354 if (!handler || handler->state != CREATE) {
3355 ErrPrint("Handler is invalid\n");
3359 if (!handler->common || handler->common->state != CREATE) {
3360 ErrPrint("Handler is invalid\n");
3364 if (!handler->common->id) {
3365 ErrPrint("Invalid handler\n");
3369 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3370 ErrPrint("Invalid handler\n");
3374 id = fb_id(handler->common->lb.fb);
3375 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3376 ErrPrint("PIXMAP Id is not valid\n");
3383 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
3385 struct packet *packet;
3387 if (!handler || pixmap == 0 || handler->state != CREATE) {
3388 ErrPrint("Handler is invalid [%d]\n", pixmap);
3389 return LB_STATUS_ERROR_INVALID;
3392 if (!handler->common || handler->common->state != CREATE) {
3393 ErrPrint("Handler is invalid\n");
3394 return LB_STATUS_ERROR_INVALID;
3397 if (!handler->common->id) {
3398 ErrPrint("Invalid handle\n");
3399 return LB_STATUS_ERROR_INVALID;
3402 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3403 ErrPrint("Handler is not valid type\n");
3404 return LB_STATUS_ERROR_INVALID;
3407 packet = packet_create_noack("pd_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
3409 ErrPrint("Failed to build a param\n");
3410 return LB_STATUS_ERROR_FAULT;
3413 return master_rpc_request_only(handler, packet);
3416 EAPI void *livebox_acquire_fb(struct livebox *handler)
3418 if (!handler || handler->state != CREATE) {
3419 ErrPrint("Handler is invalid\n");
3423 if (!handler->common || handler->common->state != CREATE) {
3424 ErrPrint("Handler is invalid\n");
3428 if (!handler->common->id) {
3429 ErrPrint("Invalid handle\n");
3433 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3434 ErrPrint("Handler is not valid type\n");
3438 return fb_acquire_buffer(handler->common->lb.fb);
3441 EAPI int livebox_release_fb(void *buffer)
3443 return fb_release_buffer(buffer);
3446 EAPI int livebox_fb_refcnt(void *buffer)
3448 return fb_refcnt(buffer);
3451 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
3453 if (!handler || handler->state != CREATE) {
3454 ErrPrint("Handler is invalid\n");
3458 if (!handler->common || handler->common->state != CREATE) {
3459 ErrPrint("Handler is invalid\n");
3463 if (!handler->common->id) {
3464 ErrPrint("Invalid handler\n");
3468 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3469 ErrPrint("Handler is not valid type\n");
3473 return fb_acquire_buffer(handler->common->pd.fb);
3476 EAPI int livebox_release_pdfb(void *buffer)
3478 return fb_release_buffer(buffer);
3481 EAPI int livebox_pdfb_refcnt(void *buffer)
3483 return fb_refcnt(buffer);
3486 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
3488 if (!handler || handler->state != CREATE) {
3489 ErrPrint("Handler is invalid\n");
3490 return LB_STATUS_ERROR_INVALID;
3493 if (!handler->common || handler->common->state != CREATE) {
3494 ErrPrint("Handler is invalid\n");
3495 return LB_STATUS_ERROR_INVALID;
3498 if (!handler->common->id) {
3499 ErrPrint("Invalid handler\n");
3500 return LB_STATUS_ERROR_INVALID;
3503 return fb_size(handler->common->pd.fb);
3506 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
3508 if (!handler || handler->state != CREATE) {
3509 ErrPrint("Handler is invalid\n");
3510 return LB_STATUS_ERROR_INVALID;
3513 if (!handler->common || handler->common->state != CREATE) {
3514 ErrPrint("Handler is invalid\n");
3515 return LB_STATUS_ERROR_INVALID;
3518 if (!handler->common->id) {
3519 ErrPrint("Invalid handler\n");
3520 return LB_STATUS_ERROR_INVALID;
3523 return fb_size(handler->common->lb.fb);
3526 EAPI int livebox_is_user(struct livebox *handler)
3528 if (!handler || handler->state != CREATE) {
3529 ErrPrint("Handler is invalid\n");
3530 return LB_STATUS_ERROR_INVALID;
3533 if (!handler->common || handler->common->state != CREATE) {
3534 ErrPrint("Handler is invalid\n");
3535 return LB_STATUS_ERROR_INVALID;
3538 if (!handler->common->id) {
3539 ErrPrint("Invalid handler\n");
3540 return LB_STATUS_ERROR_INVALID;
3543 return handler->common->is_user;
3546 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
3548 struct packet *packet;
3551 if (!handler || handler->state != CREATE) {
3552 ErrPrint("Handler is invalid\n");
3553 return LB_STATUS_ERROR_INVALID;
3556 if (!handler->common || handler->common->state != CREATE) {
3557 ErrPrint("Handler is invalid\n");
3558 return LB_STATUS_ERROR_INVALID;
3561 if (!handler->common->id) {
3562 ErrPrint("Invalid handler\n");
3563 return LB_STATUS_ERROR_INVALID;
3566 if (handler->common->request.pinup) {
3567 ErrPrint("Previous pinup request is not finished\n");
3568 return LB_STATUS_ERROR_BUSY;
3571 if (handler->common->is_pinned_up == flag) {
3572 DbgPrint("No changes\n");
3573 return LB_STATUS_ERROR_ALREADY;
3576 packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
3578 ErrPrint("Failed to build a param\n");
3579 return LB_STATUS_ERROR_FAULT;
3583 cb = default_pinup_cb;
3586 ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
3587 if (ret == LB_STATUS_SUCCESS) {
3588 handler->cbs.pinup.cb = cb;
3589 handler->cbs.pinup.data = data;
3590 handler->common->request.pinup = 1;
3596 EAPI int livebox_is_pinned_up(struct livebox *handler)
3598 if (!handler || handler->state != CREATE) {
3599 ErrPrint("Handler is invalid\n");
3600 return LB_STATUS_ERROR_INVALID;
3603 if (!handler->common || handler->common->state != CREATE) {
3604 ErrPrint("Handler is invalid\n");
3605 return LB_STATUS_ERROR_INVALID;
3608 if (!handler->common->id) {
3609 ErrPrint("Invalid handler\n");
3610 return LB_STATUS_ERROR_INVALID;
3613 return handler->common->is_pinned_up;
3616 EAPI int livebox_has_pinup(struct livebox *handler)
3618 if (!handler || handler->state != CREATE) {
3619 ErrPrint("Handler is invalid\n");
3620 return LB_STATUS_ERROR_INVALID;
3623 if (!handler->common || handler->common->state != CREATE) {
3624 ErrPrint("Handler is invalid\n");
3625 return LB_STATUS_ERROR_INVALID;
3628 if (!handler->common->id) {
3629 ErrPrint("Invalid handler\n");
3630 return LB_STATUS_ERROR_INVALID;
3633 return handler->common->lb.pinup_supported;
3636 EAPI int livebox_set_data(struct livebox *handler, void *data)
3639 ErrPrint("Handler is NIL\n");
3640 return LB_STATUS_ERROR_INVALID;
3643 if (handler->state != CREATE) {
3644 ErrPrint("Handler is invalid\n");
3645 return LB_STATUS_ERROR_INVALID;
3648 handler->data = data;
3649 return LB_STATUS_SUCCESS;
3652 EAPI void *livebox_get_data(struct livebox *handler)
3655 ErrPrint("Handler is NIL\n");
3659 if (handler->state != CREATE) {
3660 ErrPrint("Handler is invalid\n");
3664 return handler->data;
3667 EAPI int livebox_is_exists(const char *pkgname)
3671 lb = lb_pkgname(pkgname);
3680 EAPI const char *livebox_content(struct livebox *handler)
3682 if (!handler || handler->state != CREATE) {
3683 ErrPrint("Handler is invalid\n");
3687 if (!handler->common || handler->common->state != CREATE) {
3688 ErrPrint("Invalid handle\n");
3692 return handler->common->content;
3695 EAPI const char *livebox_category_title(struct livebox *handler)
3697 if (!handler || handler->state != CREATE) {
3698 ErrPrint("Handler is invalid\n");
3702 if (!handler->common || handler->common->state != CREATE) {
3703 ErrPrint("Invalid handle\n");
3707 return handler->common->title;
3710 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)
3712 struct packet *packet;
3713 struct cb_info *cbinfo;
3716 if (!handler || handler->state != CREATE) {
3717 ErrPrint("Handler is invalid\n");
3718 return LB_STATUS_ERROR_INVALID;
3721 if (!handler->common || handler->common->state != CREATE) {
3722 ErrPrint("Handler is invalid\n");
3723 return LB_STATUS_ERROR_INVALID;
3726 if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
3727 ErrPrint("Handler is not valid\n");
3728 return LB_STATUS_ERROR_INVALID;
3739 packet = packet_create("text_signal", "ssssdddd",
3740 handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
3742 ErrPrint("Failed to build a param\n");
3743 return LB_STATUS_ERROR_FAULT;
3746 cbinfo = create_cb_info(cb, data);
3748 packet_destroy(packet);
3749 return LB_STATUS_ERROR_FAULT;
3752 ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
3754 destroy_cb_info(cbinfo);
3760 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
3762 struct packet *packet;
3766 * Validate the group info using DB
3767 * If the group info is not valid, do not send this request
3770 packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
3772 ErrPrint("Failed to create a packet\n");
3773 return LB_STATUS_ERROR_FAULT;
3776 return master_rpc_request_only(NULL, packet);
3779 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
3781 struct packet *packet;
3785 * Validate the group info using DB
3786 * If the group info is not valid, do not send this request
3787 * AND Check the subscribed or not too
3790 packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
3792 ErrPrint("Failed to create a packet\n");
3793 return LB_STATUS_ERROR_FAULT;
3796 return master_rpc_request_only(NULL, packet);
3799 EAPI int livebox_refresh(struct livebox *handler, int force)
3801 struct packet *packet;
3803 if (!handler || handler->state != CREATE) {
3804 ErrPrint("Handler is invalid\n");
3805 return LB_STATUS_ERROR_INVALID;
3808 if (!handler->common || handler->common->state != CREATE) {
3809 ErrPrint("Handler is not valid\n");
3810 return LB_STATUS_ERROR_INVALID;
3813 if (!handler->common->id) {
3814 ErrPrint("Handler is not valid\n");
3815 return LB_STATUS_ERROR_INVALID;
3818 packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
3820 ErrPrint("Failed to create a packet\n");
3821 return LB_STATUS_ERROR_FAULT;
3824 return master_rpc_request_only(handler, packet);
3827 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
3829 struct packet *packet;
3831 if (!cluster || !category) {
3832 ErrPrint("Invalid argument\n");
3833 return LB_STATUS_ERROR_INVALID;
3836 packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
3838 ErrPrint("Failed to create a packet\n");
3839 return LB_STATUS_ERROR_FAULT;
3842 return master_rpc_request_only(NULL, packet);
3845 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
3850 if (!handler || handler->state != CREATE) {
3851 ErrPrint("Handler is invalid\n");
3852 return LB_STATUS_ERROR_INVALID;
3855 if (!handler->common || handler->common->state != CREATE) {
3856 ErrPrint("Handler is not valid\n");
3857 return LB_STATUS_ERROR_INVALID;
3860 if (!handler->common->id) {
3861 ErrPrint("Handler is not valid\n");
3862 return LB_STATUS_ERROR_INVALID;
3865 if (!handler->common->is_user) {
3866 /* System cluster livebox cannot be changed its visible states */
3867 if (state == LB_HIDE_WITH_PAUSE) {
3868 ErrPrint("CA Livebox is not able to change the visibility\n");
3869 return LB_STATUS_ERROR_PERMISSION;
3873 DbgPrint("[%s] Change visiblity to 0x%x\n", handler->common->pkgname, state);
3875 if (handler->visible == state) {
3876 DbgPrint("%s has no changes\n", handler->common->pkgname);
3877 return LB_STATUS_ERROR_ALREADY;
3880 old_state = handler->visible;
3881 handler->visible = state;
3883 ret = lb_set_visibility(handler, state);
3885 handler->visible = old_state;
3891 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
3893 if (!handler || handler->state != CREATE) {
3894 ErrPrint("Handler is invalid\n");
3895 return LB_VISIBLE_ERROR;
3898 if (!handler->common || handler->common->state != CREATE) {
3899 ErrPrint("Handler is not valid\n");
3900 return LB_VISIBLE_ERROR;
3903 if (!handler->common->id) {
3904 ErrPrint("Handler is not valid\n");
3905 return LB_VISIBLE_ERROR;
3908 return handler->visible;
3911 int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
3917 pc = strdup(cluster);
3919 ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
3920 return LB_STATUS_ERROR_MEMORY;
3925 ps = strdup(category);
3927 ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
3929 return LB_STATUS_ERROR_MEMORY;
3933 if (common->cluster) {
3934 free(common->cluster);
3937 if (common->category) {
3938 free(common->category);
3941 common->cluster = pc;
3942 common->category = ps;
3944 return LB_STATUS_SUCCESS;
3947 void lb_set_size(struct livebox_common *common, int w, int h)
3949 common->lb.width = w;
3950 common->lb.height = h;
3953 void lb_set_update_mode(struct livebox_common *common, int active_mode)
3955 common->is_active_update = active_mode;
3958 void lb_set_pdsize(struct livebox_common *common, int w, int h)
3960 common->pd.width = w;
3961 common->pd.height = h;
3964 void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
3966 common->pd.default_width = w;
3967 common->pd.default_height = h;
3970 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
3974 struct fault_info *info;
3976 s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
3978 dlist_foreach_safe(s_info.fault_list, l, n, info) {
3979 if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
3980 info->is_deleted = 1;
3983 if (info->is_deleted) {
3984 s_info.fault_list = dlist_remove(s_info.fault_list, l);
3989 s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
3992 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
3996 struct event_info *info;
3998 if (event == LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
3999 if (handler->visible != LB_SHOW) {
4000 DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
4001 handler->paused_updating++;
4004 handler->paused_updating = 0;
4008 s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4010 dlist_foreach_safe(s_info.event_list, l, n, info) {
4011 if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
4012 DbgPrint("Event handler returns EXIT_FAILURE\n");
4013 info->is_deleted = 1;
4016 if (info->is_deleted) {
4017 s_info.event_list = dlist_remove(s_info.event_list, l);
4022 s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4025 struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
4028 struct livebox_common *common;
4030 dlist_foreach(s_info.livebox_common_list, l, common) {
4035 if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
4043 struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
4046 struct livebox_common *common;
4048 dlist_foreach(s_info.livebox_common_list, l, common) {
4049 if (common->timestamp == timestamp) {
4057 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
4059 struct livebox *handler;
4061 handler = calloc(1, sizeof(*handler));
4063 ErrPrint("Failed to create a new livebox\n");
4067 handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
4068 if (!handler->common) {
4069 ErrPrint("Heap: %s\n", strerror(errno));
4074 lb_common_ref(handler->common, handler);
4075 lb_set_id(handler->common, id);
4076 handler->common->timestamp = timestamp;
4077 handler->common->state = CREATE;
4078 handler->visible = LB_SHOW;
4079 s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
4081 return lb_ref(handler);
4084 int lb_delete_all(void)
4088 struct livebox *handler;
4090 dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
4091 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
4092 lb_unref(handler, 1);
4095 return LB_STATUS_SUCCESS;
4098 int lb_set_content(struct livebox_common *common, const char *content)
4103 pc = strdup(content);
4105 ErrPrint("heap: %s [%s]\n", strerror(errno), content);
4106 return LB_STATUS_ERROR_MEMORY;
4110 free(common->content);
4111 common->content = pc;
4112 return LB_STATUS_SUCCESS;
4115 int lb_set_title(struct livebox_common *common, const char *title)
4122 ErrPrint("heap: %s [%s]\n", strerror(errno), title);
4123 return LB_STATUS_ERROR_MEMORY;
4127 free(common->title);
4129 return LB_STATUS_SUCCESS;
4132 void lb_set_size_list(struct livebox_common *common, int size_list)
4134 common->lb.size_list = size_list;
4137 void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
4141 if (!auto_launch || !strlen(auto_launch)) {
4145 pa = strdup(auto_launch);
4147 ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
4151 free(common->lb.auto_launch);
4152 common->lb.auto_launch = pa;
4155 void lb_set_priority(struct livebox_common *common, double priority)
4157 common->lb.priority = priority;
4160 void lb_set_id(struct livebox_common *common, const char *id)
4167 ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
4176 void lb_set_filename(struct livebox_common *common, const char *filename)
4178 if (common->filename) {
4179 if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
4180 if (common->filename[0] && unlink(common->filename) < 0) {
4181 ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
4185 free(common->filename);
4188 common->filename = strdup(filename);
4189 if (!common->filename) {
4190 ErrPrint("Heap: %s\n", strerror(errno));
4194 void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
4199 if (icon && strlen(icon)) {
4200 _icon = strdup(icon);
4202 ErrPrint("Heap: %s\n", strerror(errno));
4206 if (name && strlen(name)) {
4207 _name = strdup(name);
4209 ErrPrint("Heap: %s\n", strerror(errno));
4213 free(common->alt.icon);
4214 common->alt.icon = _icon;
4216 free(common->alt.name);
4217 common->alt.name = _name;
4220 int lb_set_lb_fb(struct livebox_common *common, const char *filename)
4225 return LB_STATUS_ERROR_INVALID;
4229 if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
4230 return LB_STATUS_SUCCESS;
4233 common->lb.fb = NULL;
4235 if (!filename || filename[0] == '\0') {
4239 return LB_STATUS_SUCCESS;
4242 common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
4243 if (!common->lb.fb) {
4244 ErrPrint("Faield to create a FB\n");
4248 return LB_STATUS_ERROR_FAULT;
4255 return LB_STATUS_SUCCESS;
4258 int lb_set_pd_fb(struct livebox_common *common, const char *filename)
4262 if (!common || common->state != CREATE) {
4263 return LB_STATUS_ERROR_INVALID;
4267 if (fb && !strcmp(fb_id(fb), filename)) {
4268 /* BUFFER is not changed, just update the content */
4269 return LB_STATUS_ERROR_EXIST;
4271 common->pd.fb = NULL;
4273 if (!filename || filename[0] == '\0') {
4277 return LB_STATUS_SUCCESS;
4280 common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
4281 if (!common->pd.fb) {
4282 ErrPrint("Failed to create a FB\n");
4286 return LB_STATUS_ERROR_FAULT;
4292 return LB_STATUS_SUCCESS;
4295 struct fb_info *lb_get_lb_fb(struct livebox_common *common)
4297 return common->lb.fb;
4300 struct fb_info *lb_get_pd_fb(struct livebox_common *common)
4302 return common->pd.fb;
4305 void lb_set_user(struct livebox_common *common, int user)
4307 common->is_user = user;
4310 void lb_set_pinup(struct livebox_common *common, int pinup_supported)
4312 common->lb.pinup_supported = pinup_supported;
4315 void lb_set_text_lb(struct livebox_common *common)
4317 common->lb.type = _LB_TYPE_TEXT;
4320 void lb_set_text_pd(struct livebox_common *common)
4322 common->pd.type = _PD_TYPE_TEXT;
4325 int lb_text_lb(struct livebox_common *common)
4327 return common->lb.type == _LB_TYPE_TEXT;
4330 int lb_text_pd(struct livebox_common *common)
4332 return common->pd.type == _PD_TYPE_TEXT;
4335 void lb_set_period(struct livebox_common *common, double period)
4337 common->lb.period = period;
4340 struct livebox *lb_ref(struct livebox *handler)
4350 struct livebox *lb_unref(struct livebox *handler, int destroy_common)
4357 if (handler->refcnt > 0) {
4361 if (handler->cbs.created.cb) {
4362 handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
4363 handler->cbs.created.cb = NULL;
4364 handler->cbs.created.data = NULL;
4367 if (handler->cbs.deleted.cb) {
4368 handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
4369 handler->cbs.deleted.cb = NULL;
4370 handler->cbs.deleted.data = NULL;
4373 if (handler->cbs.pinup.cb) {
4374 handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
4375 handler->cbs.pinup.cb = NULL;
4376 handler->cbs.pinup.data = NULL;
4379 if (handler->cbs.group_changed.cb) {
4380 handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
4381 handler->cbs.group_changed.cb = NULL;
4382 handler->cbs.group_changed.data = NULL;
4385 if (handler->cbs.period_changed.cb) {
4386 handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
4387 handler->cbs.period_changed.cb = NULL;
4388 handler->cbs.period_changed.data = NULL;
4391 if (handler->cbs.size_changed.cb) {
4392 handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
4393 handler->cbs.size_changed.cb = NULL;
4394 handler->cbs.size_changed.data = NULL;
4397 if (handler->cbs.pd_created.cb) {
4398 handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
4399 handler->cbs.pd_created.cb = NULL;
4400 handler->cbs.pd_created.data = NULL;
4403 if (handler->cbs.pd_destroyed.cb) {
4404 handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
4405 handler->cbs.pd_destroyed.cb = NULL;
4406 handler->cbs.pd_destroyed.data = NULL;
4409 if (handler->cbs.update_mode.cb) {
4410 handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
4411 handler->cbs.update_mode.cb = NULL;
4412 handler->cbs.update_mode.data = NULL;
4415 if (handler->cbs.access_event.cb) {
4416 handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
4417 handler->cbs.access_event.cb = NULL;
4418 handler->cbs.access_event.data = NULL;
4421 if (handler->cbs.key_event.cb) {
4422 handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
4423 handler->cbs.key_event.cb = NULL;
4424 handler->cbs.key_event.data = NULL;
4427 dlist_remove_data(s_info.livebox_list, handler);
4429 handler->state = DESTROYED;
4430 if (lb_common_unref(handler->common, handler) == 0) {
4431 if (destroy_common) {
4434 * Lock file should be deleted after all callbacks are processed.
4436 lb_destroy_lock_file(handler->common, 0);
4437 lb_destroy_common_handle(handler->common);
4441 DbgPrint("Handler is released\n");
4445 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
4447 struct packet *packet;
4448 struct cb_info *cbinfo;
4451 if (handler->common->request.deleted) {
4452 ErrPrint("Already in-progress\n");
4454 cb(handler, LB_STATUS_SUCCESS, data);
4456 return LB_STATUS_ERROR_BUSY;
4460 cb = default_delete_cb;
4463 packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp);
4465 ErrPrint("Failed to build a param\n");
4467 cb(handler, LB_STATUS_ERROR_FAULT, data);
4470 return LB_STATUS_ERROR_FAULT;
4473 cbinfo = create_cb_info(cb, data);
4475 packet_destroy(packet);
4476 ErrPrint("Failed to create cbinfo\n");
4478 cb(handler, LB_STATUS_ERROR_FAULT, data);
4481 return LB_STATUS_ERROR_FAULT;
4484 ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
4487 * Packet is destroyed by master_rpc_async_request.
4489 destroy_cb_info(cbinfo);
4492 cb(handler, LB_STATUS_ERROR_FAULT, data);
4495 handler->common->request.deleted = 1;
4501 EAPI int livebox_client_paused(void)
4503 struct packet *packet;
4505 packet = packet_create_noack("client_paused", "d", util_timestamp());
4507 ErrPrint("Failed to create a pause packet\n");
4508 return LB_STATUS_ERROR_FAULT;
4511 return master_rpc_request_only(NULL, packet);
4514 EAPI int livebox_client_resumed(void)
4516 struct packet *packet;
4518 packet = packet_create_noack("client_resumed", "d", util_timestamp());
4520 ErrPrint("Failed to create a resume packet\n");
4521 return LB_STATUS_ERROR_FAULT;
4524 return master_rpc_request_only(NULL, packet);
4527 EAPI int livebox_sync_lb_fb(struct livebox *handler)
4529 if (!handler || handler->state != CREATE) {
4530 ErrPrint("Invalid handle\n");
4531 return LB_STATUS_ERROR_INVALID;
4534 if (!handler->common || handler->common->state != CREATE) {
4535 ErrPrint("Invalid handle\n");
4536 return LB_STATUS_ERROR_INVALID;
4539 if (!handler->common->id) {
4540 return LB_STATUS_ERROR_INVALID;
4543 return lb_sync_lb_fb(handler->common);
4546 int lb_sync_lb_fb(struct livebox_common *common)
4550 if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
4551 (void)do_fb_lock(common->lb.lock_fd);
4552 ret = fb_sync(lb_get_lb_fb(common));
4553 (void)do_fb_unlock(common->lb.lock_fd);
4555 ret = fb_sync(lb_get_lb_fb(common));
4561 int lb_sync_pd_fb(struct livebox_common *common)
4565 if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
4566 (void)do_fb_lock(common->pd.lock_fd);
4567 ret = fb_sync(lb_get_pd_fb(common));
4568 (void)do_fb_unlock(common->pd.lock_fd);
4570 ret = fb_sync(lb_get_pd_fb(common));
4576 EAPI int livebox_sync_pd_fb(struct livebox *handler)
4578 if (!handler || handler->state != CREATE) {
4579 ErrPrint("Invalid handle\n");
4580 return LB_STATUS_ERROR_INVALID;
4583 if (!handler->common || handler->common->state != CREATE) {
4584 ErrPrint("Invalid handle\n");
4585 return LB_STATUS_ERROR_INVALID;
4588 if (!handler->common->id) {
4589 ErrPrint("Invalid handle\n");
4590 return LB_STATUS_ERROR_INVALID;
4593 return lb_sync_pd_fb(handler->common);
4596 EAPI const char *livebox_alt_icon(struct livebox *handler)
4598 if (!handler || handler->state != CREATE) {
4599 ErrPrint("Handler is not valid[%p]\n", handler);
4603 if (!handler->common || handler->common->state != CREATE) {
4604 ErrPrint("Handler is not valid\n");
4608 return handler->common->alt.icon;
4611 EAPI const char *livebox_alt_name(struct livebox *handler)
4613 if (!handler || handler->state != CREATE) {
4614 ErrPrint("Handler is not valid[%p]\n", handler);
4618 if (!handler->common || handler->common->state != CREATE) {
4619 ErrPrint("Handler is not valid\n");
4623 return handler->common->alt.name;
4626 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
4628 int ret = LB_STATUS_SUCCESS;
4631 if (!handler || handler->state != CREATE) {
4632 ErrPrint("Handler is not valid[%p]\n", handler);
4633 return LB_STATUS_ERROR_INVALID;
4636 if (!handler->common || handler->common->state != CREATE) {
4637 ErrPrint("Handler is not valid\n");
4638 return LB_STATUS_ERROR_INVALID;
4641 if (!handler->common->id) {
4642 ErrPrint("Handler is not valid[%p]\n", handler);
4643 return LB_STATUS_ERROR_INVALID;
4647 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4648 DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4649 return LB_STATUS_ERROR_INVALID;
4652 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4653 return LB_STATUS_SUCCESS;
4656 fd = handler->common->pd.lock_fd;
4658 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4659 DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4660 return LB_STATUS_ERROR_INVALID;
4663 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4664 return LB_STATUS_SUCCESS;
4667 fd = handler->common->lb.lock_fd;
4670 ret = do_fb_lock(fd);
4672 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4675 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
4677 int ret = LB_STATUS_SUCCESS;
4680 if (!handler || handler->state != CREATE) {
4681 ErrPrint("Invalid handle\n");
4682 return LB_STATUS_ERROR_INVALID;
4685 if (!handler->common || handler->common->state != CREATE) {
4686 ErrPrint("Invalid handle\n");
4687 return LB_STATUS_ERROR_INVALID;
4690 if (!handler->common->id) {
4691 ErrPrint("Handler is not valid[%p]\n", handler);
4692 return LB_STATUS_ERROR_INVALID;
4696 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4697 DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4698 return LB_STATUS_ERROR_INVALID;
4701 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4702 return LB_STATUS_SUCCESS;
4705 fd = handler->common->pd.lock_fd;
4707 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4708 DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4709 return LB_STATUS_ERROR_INVALID;
4712 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4713 return LB_STATUS_SUCCESS;
4716 fd = handler->common->lb.lock_fd;
4719 ret = do_fb_unlock(fd);
4721 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4724 EAPI int livebox_set_option(enum livebox_option_type option, int state)
4726 int ret = LB_STATUS_SUCCESS;
4729 case LB_OPTION_MANUAL_SYNC:
4730 conf_set_manual_sync(state);
4732 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4733 conf_set_frame_drop_for_resizing(state);
4735 case LB_OPTION_SHARED_CONTENT:
4736 conf_set_shared_content(state);
4739 ret = LB_STATUS_ERROR_INVALID;
4746 EAPI int livebox_option(enum livebox_option_type option)
4751 case LB_OPTION_MANUAL_SYNC:
4752 ret = conf_manual_sync();
4754 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4755 ret = conf_frame_drop_for_resizing();
4757 case LB_OPTION_SHARED_CONTENT:
4758 ret = conf_shared_content();
4761 ret = LB_STATUS_ERROR_INVALID;