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);
3259 * Do not check the state of handler and common-handler.
3260 * If this function is used in the deleted callback,
3261 * the handler and common-handler's state would be DELETE
3262 * if this function check the state of handles,
3263 * user cannot release the pixmap.
3265 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
3267 struct packet *packet;
3269 if (!handler || pixmap == 0 /* || handler->state != CREATE */ ) {
3270 ErrPrint("Handler is invalid [%d]\n", pixmap);
3271 return LB_STATUS_ERROR_INVALID;
3274 if (!handler->common /* || handler->common->state != CREATE */) {
3275 ErrPrint("Handler is invalid\n");
3276 return LB_STATUS_ERROR_INVALID;
3279 if (!handler->common->id) {
3280 ErrPrint("Invalid handle\n");
3281 return LB_STATUS_ERROR_INVALID;
3284 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3285 ErrPrint("Handler is not valid type\n");
3286 return LB_STATUS_ERROR_INVALID;
3289 packet = packet_create_noack("lb_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
3291 ErrPrint("Failed to build a param\n");
3292 return LB_STATUS_ERROR_INVALID;
3295 return master_rpc_request_only(handler, packet);
3298 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3300 if (!handler || handler->state != CREATE) {
3301 ErrPrint("Handler is invalid\n");
3302 return LB_STATUS_ERROR_INVALID;
3305 if (!handler->common || handler->common->state != CREATE) {
3306 ErrPrint("Handler is invalid\n");
3307 return LB_STATUS_ERROR_INVALID;
3310 if (!handler->common->id) {
3311 ErrPrint("Invalid handle\n");
3312 return LB_STATUS_ERROR_INVALID;
3315 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3316 ErrPrint("Handler is not valid type\n");
3317 return LB_STATUS_ERROR_INVALID;
3320 return lb_acquire_pd_pixmap(handler, cb, data);
3323 EAPI int livebox_pd_pixmap(const struct livebox *handler)
3328 if (!handler || handler->state != CREATE) {
3329 ErrPrint("Handler is invalid\n");
3333 if (!handler->common || handler->common->state != CREATE) {
3334 ErrPrint("Handler is invalid\n");
3338 if (!handler->common->id) {
3339 ErrPrint("Invalid handler\n");
3343 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3344 ErrPrint("Invalid handler\n");
3348 id = fb_id(handler->common->pd.fb);
3349 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3350 ErrPrint("PIXMAP Id is not valid\n");
3357 EAPI int livebox_lb_pixmap(const struct livebox *handler)
3362 if (!handler || handler->state != CREATE) {
3363 ErrPrint("Handler is invalid\n");
3367 if (!handler->common || handler->common->state != CREATE) {
3368 ErrPrint("Handler is invalid\n");
3372 if (!handler->common->id) {
3373 ErrPrint("Invalid handler\n");
3377 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3378 ErrPrint("Invalid handler\n");
3382 id = fb_id(handler->common->lb.fb);
3383 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3384 ErrPrint("PIXMAP Id is not valid\n");
3393 * Do not check the state of handler and common-handler.
3394 * If this function is used in the deleted callback,
3395 * the handler and common-handler's state would be DELETE
3396 * if this function check the state of handles,
3397 * user cannot release the pixmap.
3399 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
3401 struct packet *packet;
3403 if (!handler || pixmap == 0 /* || handler->state != CREATE */) {
3404 ErrPrint("Handler is invalid [%d]\n", pixmap);
3405 return LB_STATUS_ERROR_INVALID;
3408 if (!handler->common /* || handler-common->state != CREATE */) {
3409 ErrPrint("Handler is invalid\n");
3410 return LB_STATUS_ERROR_INVALID;
3413 if (!handler->common->id) {
3414 ErrPrint("Invalid handle\n");
3415 return LB_STATUS_ERROR_INVALID;
3418 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3419 ErrPrint("Handler is not valid type\n");
3420 return LB_STATUS_ERROR_INVALID;
3423 packet = packet_create_noack("pd_release_pixmap", "ssi", handler->common->pkgname, handler->common->id, pixmap);
3425 ErrPrint("Failed to build a param\n");
3426 return LB_STATUS_ERROR_FAULT;
3429 return master_rpc_request_only(handler, packet);
3432 EAPI void *livebox_acquire_fb(struct livebox *handler)
3434 if (!handler || handler->state != CREATE) {
3435 ErrPrint("Handler is invalid\n");
3439 if (!handler->common || handler->common->state != CREATE) {
3440 ErrPrint("Handler is invalid\n");
3444 if (!handler->common->id) {
3445 ErrPrint("Invalid handle\n");
3449 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3450 ErrPrint("Handler is not valid type\n");
3454 return fb_acquire_buffer(handler->common->lb.fb);
3457 EAPI int livebox_release_fb(void *buffer)
3459 return fb_release_buffer(buffer);
3462 EAPI int livebox_fb_refcnt(void *buffer)
3464 return fb_refcnt(buffer);
3467 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
3469 if (!handler || handler->state != CREATE) {
3470 ErrPrint("Handler is invalid\n");
3474 if (!handler->common || handler->common->state != CREATE) {
3475 ErrPrint("Handler is invalid\n");
3479 if (!handler->common->id) {
3480 ErrPrint("Invalid handler\n");
3484 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3485 ErrPrint("Handler is not valid type\n");
3489 return fb_acquire_buffer(handler->common->pd.fb);
3492 EAPI int livebox_release_pdfb(void *buffer)
3494 return fb_release_buffer(buffer);
3497 EAPI int livebox_pdfb_refcnt(void *buffer)
3499 return fb_refcnt(buffer);
3502 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
3504 if (!handler || handler->state != CREATE) {
3505 ErrPrint("Handler is invalid\n");
3506 return LB_STATUS_ERROR_INVALID;
3509 if (!handler->common || handler->common->state != CREATE) {
3510 ErrPrint("Handler is invalid\n");
3511 return LB_STATUS_ERROR_INVALID;
3514 if (!handler->common->id) {
3515 ErrPrint("Invalid handler\n");
3516 return LB_STATUS_ERROR_INVALID;
3519 return fb_size(handler->common->pd.fb);
3522 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
3524 if (!handler || handler->state != CREATE) {
3525 ErrPrint("Handler is invalid\n");
3526 return LB_STATUS_ERROR_INVALID;
3529 if (!handler->common || handler->common->state != CREATE) {
3530 ErrPrint("Handler is invalid\n");
3531 return LB_STATUS_ERROR_INVALID;
3534 if (!handler->common->id) {
3535 ErrPrint("Invalid handler\n");
3536 return LB_STATUS_ERROR_INVALID;
3539 return fb_size(handler->common->lb.fb);
3542 EAPI int livebox_is_user(struct livebox *handler)
3544 if (!handler || handler->state != CREATE) {
3545 ErrPrint("Handler is invalid\n");
3546 return LB_STATUS_ERROR_INVALID;
3549 if (!handler->common || handler->common->state != CREATE) {
3550 ErrPrint("Handler is invalid\n");
3551 return LB_STATUS_ERROR_INVALID;
3554 if (!handler->common->id) {
3555 ErrPrint("Invalid handler\n");
3556 return LB_STATUS_ERROR_INVALID;
3559 return handler->common->is_user;
3562 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
3564 struct packet *packet;
3567 if (!handler || handler->state != CREATE) {
3568 ErrPrint("Handler is invalid\n");
3569 return LB_STATUS_ERROR_INVALID;
3572 if (!handler->common || handler->common->state != CREATE) {
3573 ErrPrint("Handler is invalid\n");
3574 return LB_STATUS_ERROR_INVALID;
3577 if (!handler->common->id) {
3578 ErrPrint("Invalid handler\n");
3579 return LB_STATUS_ERROR_INVALID;
3582 if (handler->common->request.pinup) {
3583 ErrPrint("Previous pinup request is not finished\n");
3584 return LB_STATUS_ERROR_BUSY;
3587 if (handler->common->is_pinned_up == flag) {
3588 DbgPrint("No changes\n");
3589 return LB_STATUS_ERROR_ALREADY;
3592 packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
3594 ErrPrint("Failed to build a param\n");
3595 return LB_STATUS_ERROR_FAULT;
3599 cb = default_pinup_cb;
3602 ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
3603 if (ret == LB_STATUS_SUCCESS) {
3604 handler->cbs.pinup.cb = cb;
3605 handler->cbs.pinup.data = data;
3606 handler->common->request.pinup = 1;
3612 EAPI int livebox_is_pinned_up(struct livebox *handler)
3614 if (!handler || handler->state != CREATE) {
3615 ErrPrint("Handler is invalid\n");
3616 return LB_STATUS_ERROR_INVALID;
3619 if (!handler->common || handler->common->state != CREATE) {
3620 ErrPrint("Handler is invalid\n");
3621 return LB_STATUS_ERROR_INVALID;
3624 if (!handler->common->id) {
3625 ErrPrint("Invalid handler\n");
3626 return LB_STATUS_ERROR_INVALID;
3629 return handler->common->is_pinned_up;
3632 EAPI int livebox_has_pinup(struct livebox *handler)
3634 if (!handler || handler->state != CREATE) {
3635 ErrPrint("Handler is invalid\n");
3636 return LB_STATUS_ERROR_INVALID;
3639 if (!handler->common || handler->common->state != CREATE) {
3640 ErrPrint("Handler is invalid\n");
3641 return LB_STATUS_ERROR_INVALID;
3644 if (!handler->common->id) {
3645 ErrPrint("Invalid handler\n");
3646 return LB_STATUS_ERROR_INVALID;
3649 return handler->common->lb.pinup_supported;
3652 EAPI int livebox_set_data(struct livebox *handler, void *data)
3655 ErrPrint("Handler is NIL\n");
3656 return LB_STATUS_ERROR_INVALID;
3659 if (handler->state != CREATE) {
3660 ErrPrint("Handler is invalid\n");
3661 return LB_STATUS_ERROR_INVALID;
3664 handler->data = data;
3665 return LB_STATUS_SUCCESS;
3668 EAPI void *livebox_get_data(struct livebox *handler)
3671 ErrPrint("Handler is NIL\n");
3675 if (handler->state != CREATE) {
3676 ErrPrint("Handler is invalid\n");
3680 return handler->data;
3683 EAPI int livebox_is_exists(const char *pkgname)
3687 lb = lb_pkgname(pkgname);
3696 EAPI const char *livebox_content(struct livebox *handler)
3698 if (!handler || handler->state != CREATE) {
3699 ErrPrint("Handler is invalid\n");
3703 if (!handler->common || handler->common->state != CREATE) {
3704 ErrPrint("Invalid handle\n");
3708 return handler->common->content;
3711 EAPI const char *livebox_category_title(struct livebox *handler)
3713 if (!handler || handler->state != CREATE) {
3714 ErrPrint("Handler is invalid\n");
3718 if (!handler->common || handler->common->state != CREATE) {
3719 ErrPrint("Invalid handle\n");
3723 return handler->common->title;
3726 EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data)
3728 struct packet *packet;
3729 struct cb_info *cbinfo;
3732 if (!handler || handler->state != CREATE) {
3733 ErrPrint("Handler is invalid\n");
3734 return LB_STATUS_ERROR_INVALID;
3737 if (!handler->common || handler->common->state != CREATE) {
3738 ErrPrint("Handler is invalid\n");
3739 return LB_STATUS_ERROR_INVALID;
3742 if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
3743 ErrPrint("Handler is not valid\n");
3744 return LB_STATUS_ERROR_INVALID;
3755 packet = packet_create("text_signal", "ssssdddd",
3756 handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
3758 ErrPrint("Failed to build a param\n");
3759 return LB_STATUS_ERROR_FAULT;
3762 cbinfo = create_cb_info(cb, data);
3764 packet_destroy(packet);
3765 return LB_STATUS_ERROR_FAULT;
3768 ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
3770 destroy_cb_info(cbinfo);
3776 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
3778 struct packet *packet;
3782 * Validate the group info using DB
3783 * If the group info is not valid, do not send this request
3786 packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
3788 ErrPrint("Failed to create a packet\n");
3789 return LB_STATUS_ERROR_FAULT;
3792 return master_rpc_request_only(NULL, packet);
3795 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
3797 struct packet *packet;
3801 * Validate the group info using DB
3802 * If the group info is not valid, do not send this request
3803 * AND Check the subscribed or not too
3806 packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
3808 ErrPrint("Failed to create a packet\n");
3809 return LB_STATUS_ERROR_FAULT;
3812 return master_rpc_request_only(NULL, packet);
3815 EAPI int livebox_refresh(struct livebox *handler, int force)
3817 struct packet *packet;
3819 if (!handler || handler->state != CREATE) {
3820 ErrPrint("Handler is invalid\n");
3821 return LB_STATUS_ERROR_INVALID;
3824 if (!handler->common || handler->common->state != CREATE) {
3825 ErrPrint("Handler is not valid\n");
3826 return LB_STATUS_ERROR_INVALID;
3829 if (!handler->common->id) {
3830 ErrPrint("Handler is not valid\n");
3831 return LB_STATUS_ERROR_INVALID;
3834 packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
3836 ErrPrint("Failed to create a packet\n");
3837 return LB_STATUS_ERROR_FAULT;
3840 return master_rpc_request_only(handler, packet);
3843 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
3845 struct packet *packet;
3847 if (!cluster || !category) {
3848 ErrPrint("Invalid argument\n");
3849 return LB_STATUS_ERROR_INVALID;
3852 packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
3854 ErrPrint("Failed to create a packet\n");
3855 return LB_STATUS_ERROR_FAULT;
3858 return master_rpc_request_only(NULL, packet);
3861 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
3866 if (!handler || handler->state != CREATE) {
3867 ErrPrint("Handler is invalid\n");
3868 return LB_STATUS_ERROR_INVALID;
3871 if (!handler->common || handler->common->state != CREATE) {
3872 ErrPrint("Handler is not valid\n");
3873 return LB_STATUS_ERROR_INVALID;
3876 if (!handler->common->id) {
3877 ErrPrint("Handler is not valid\n");
3878 return LB_STATUS_ERROR_INVALID;
3881 if (!handler->common->is_user) {
3882 /* System cluster livebox cannot be changed its visible states */
3883 if (state == LB_HIDE_WITH_PAUSE) {
3884 ErrPrint("CA Livebox is not able to change the visibility\n");
3885 return LB_STATUS_ERROR_PERMISSION;
3889 DbgPrint("[%s] Change visiblity to 0x%x\n", handler->common->pkgname, state);
3891 if (handler->visible == state) {
3892 DbgPrint("%s has no changes\n", handler->common->pkgname);
3893 return LB_STATUS_ERROR_ALREADY;
3896 old_state = handler->visible;
3897 handler->visible = state;
3899 ret = lb_set_visibility(handler, state);
3901 handler->visible = old_state;
3907 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
3909 if (!handler || handler->state != CREATE) {
3910 ErrPrint("Handler is invalid\n");
3911 return LB_VISIBLE_ERROR;
3914 if (!handler->common || handler->common->state != CREATE) {
3915 ErrPrint("Handler is not valid\n");
3916 return LB_VISIBLE_ERROR;
3919 if (!handler->common->id) {
3920 ErrPrint("Handler is not valid\n");
3921 return LB_VISIBLE_ERROR;
3924 return handler->visible;
3927 int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
3933 pc = strdup(cluster);
3935 ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
3936 return LB_STATUS_ERROR_MEMORY;
3941 ps = strdup(category);
3943 ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
3945 return LB_STATUS_ERROR_MEMORY;
3949 if (common->cluster) {
3950 free(common->cluster);
3953 if (common->category) {
3954 free(common->category);
3957 common->cluster = pc;
3958 common->category = ps;
3960 return LB_STATUS_SUCCESS;
3963 void lb_set_size(struct livebox_common *common, int w, int h)
3965 common->lb.width = w;
3966 common->lb.height = h;
3969 void lb_set_update_mode(struct livebox_common *common, int active_mode)
3971 common->is_active_update = active_mode;
3974 void lb_set_pdsize(struct livebox_common *common, int w, int h)
3976 common->pd.width = w;
3977 common->pd.height = h;
3980 void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
3982 common->pd.default_width = w;
3983 common->pd.default_height = h;
3986 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
3990 struct fault_info *info;
3992 s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
3994 dlist_foreach_safe(s_info.fault_list, l, n, info) {
3995 if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
3996 info->is_deleted = 1;
3999 if (info->is_deleted) {
4000 s_info.fault_list = dlist_remove(s_info.fault_list, l);
4005 s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4008 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
4012 struct event_info *info;
4014 if (event == LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
4015 if (handler->visible != LB_SHOW) {
4016 DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
4017 handler->paused_updating++;
4020 handler->paused_updating = 0;
4024 s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4026 dlist_foreach_safe(s_info.event_list, l, n, info) {
4027 if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
4028 DbgPrint("Event handler returns EXIT_FAILURE\n");
4029 info->is_deleted = 1;
4032 if (info->is_deleted) {
4033 s_info.event_list = dlist_remove(s_info.event_list, l);
4038 s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4041 struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
4044 struct livebox_common *common;
4046 dlist_foreach(s_info.livebox_common_list, l, common) {
4051 if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
4059 struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
4062 struct livebox_common *common;
4064 dlist_foreach(s_info.livebox_common_list, l, common) {
4065 if (common->timestamp == timestamp) {
4073 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
4075 struct livebox *handler;
4077 handler = calloc(1, sizeof(*handler));
4079 ErrPrint("Failed to create a new livebox\n");
4083 handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
4084 if (!handler->common) {
4085 ErrPrint("Heap: %s\n", strerror(errno));
4090 lb_common_ref(handler->common, handler);
4091 lb_set_id(handler->common, id);
4092 handler->common->timestamp = timestamp;
4093 handler->common->state = CREATE;
4094 handler->visible = LB_SHOW;
4095 s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
4097 return lb_ref(handler);
4100 int lb_delete_all(void)
4104 struct livebox *handler;
4106 dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
4107 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
4108 lb_unref(handler, 1);
4111 return LB_STATUS_SUCCESS;
4114 int lb_set_content(struct livebox_common *common, const char *content)
4119 pc = strdup(content);
4121 ErrPrint("heap: %s [%s]\n", strerror(errno), content);
4122 return LB_STATUS_ERROR_MEMORY;
4126 free(common->content);
4127 common->content = pc;
4128 return LB_STATUS_SUCCESS;
4131 int lb_set_title(struct livebox_common *common, const char *title)
4138 ErrPrint("heap: %s [%s]\n", strerror(errno), title);
4139 return LB_STATUS_ERROR_MEMORY;
4143 free(common->title);
4145 return LB_STATUS_SUCCESS;
4148 void lb_set_size_list(struct livebox_common *common, int size_list)
4150 common->lb.size_list = size_list;
4153 void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
4157 if (!auto_launch || !strlen(auto_launch)) {
4161 pa = strdup(auto_launch);
4163 ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
4167 free(common->lb.auto_launch);
4168 common->lb.auto_launch = pa;
4171 void lb_set_priority(struct livebox_common *common, double priority)
4173 common->lb.priority = priority;
4176 void lb_set_id(struct livebox_common *common, const char *id)
4183 ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
4192 void lb_set_filename(struct livebox_common *common, const char *filename)
4194 if (common->filename) {
4195 if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
4196 if (common->filename[0] && unlink(common->filename) < 0) {
4197 ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
4201 free(common->filename);
4204 common->filename = strdup(filename);
4205 if (!common->filename) {
4206 ErrPrint("Heap: %s\n", strerror(errno));
4210 void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
4215 if (icon && strlen(icon)) {
4216 _icon = strdup(icon);
4218 ErrPrint("Heap: %s\n", strerror(errno));
4222 if (name && strlen(name)) {
4223 _name = strdup(name);
4225 ErrPrint("Heap: %s\n", strerror(errno));
4229 free(common->alt.icon);
4230 common->alt.icon = _icon;
4232 free(common->alt.name);
4233 common->alt.name = _name;
4236 int lb_set_lb_fb(struct livebox_common *common, const char *filename)
4241 return LB_STATUS_ERROR_INVALID;
4245 if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
4246 return LB_STATUS_SUCCESS;
4249 common->lb.fb = NULL;
4251 if (!filename || filename[0] == '\0') {
4255 return LB_STATUS_SUCCESS;
4258 common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
4259 if (!common->lb.fb) {
4260 ErrPrint("Faield to create a FB\n");
4264 return LB_STATUS_ERROR_FAULT;
4271 return LB_STATUS_SUCCESS;
4274 int lb_set_pd_fb(struct livebox_common *common, const char *filename)
4278 if (!common || common->state != CREATE) {
4279 return LB_STATUS_ERROR_INVALID;
4283 if (fb && !strcmp(fb_id(fb), filename)) {
4284 /* BUFFER is not changed, just update the content */
4285 return LB_STATUS_ERROR_EXIST;
4287 common->pd.fb = NULL;
4289 if (!filename || filename[0] == '\0') {
4293 return LB_STATUS_SUCCESS;
4296 common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
4297 if (!common->pd.fb) {
4298 ErrPrint("Failed to create a FB\n");
4302 return LB_STATUS_ERROR_FAULT;
4308 return LB_STATUS_SUCCESS;
4311 struct fb_info *lb_get_lb_fb(struct livebox_common *common)
4313 return common->lb.fb;
4316 struct fb_info *lb_get_pd_fb(struct livebox_common *common)
4318 return common->pd.fb;
4321 void lb_set_user(struct livebox_common *common, int user)
4323 common->is_user = user;
4326 void lb_set_pinup(struct livebox_common *common, int pinup_supported)
4328 common->lb.pinup_supported = pinup_supported;
4331 void lb_set_text_lb(struct livebox_common *common)
4333 common->lb.type = _LB_TYPE_TEXT;
4336 void lb_set_text_pd(struct livebox_common *common)
4338 common->pd.type = _PD_TYPE_TEXT;
4341 int lb_text_lb(struct livebox_common *common)
4343 return common->lb.type == _LB_TYPE_TEXT;
4346 int lb_text_pd(struct livebox_common *common)
4348 return common->pd.type == _PD_TYPE_TEXT;
4351 void lb_set_period(struct livebox_common *common, double period)
4353 common->lb.period = period;
4356 struct livebox *lb_ref(struct livebox *handler)
4366 struct livebox *lb_unref(struct livebox *handler, int destroy_common)
4373 if (handler->refcnt > 0) {
4377 if (handler->cbs.created.cb) {
4378 handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
4379 handler->cbs.created.cb = NULL;
4380 handler->cbs.created.data = NULL;
4383 if (handler->cbs.deleted.cb) {
4384 handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
4385 handler->cbs.deleted.cb = NULL;
4386 handler->cbs.deleted.data = NULL;
4389 if (handler->cbs.pinup.cb) {
4390 handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
4391 handler->cbs.pinup.cb = NULL;
4392 handler->cbs.pinup.data = NULL;
4395 if (handler->cbs.group_changed.cb) {
4396 handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
4397 handler->cbs.group_changed.cb = NULL;
4398 handler->cbs.group_changed.data = NULL;
4401 if (handler->cbs.period_changed.cb) {
4402 handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
4403 handler->cbs.period_changed.cb = NULL;
4404 handler->cbs.period_changed.data = NULL;
4407 if (handler->cbs.size_changed.cb) {
4408 handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
4409 handler->cbs.size_changed.cb = NULL;
4410 handler->cbs.size_changed.data = NULL;
4413 if (handler->cbs.pd_created.cb) {
4414 handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
4415 handler->cbs.pd_created.cb = NULL;
4416 handler->cbs.pd_created.data = NULL;
4419 if (handler->cbs.pd_destroyed.cb) {
4420 handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
4421 handler->cbs.pd_destroyed.cb = NULL;
4422 handler->cbs.pd_destroyed.data = NULL;
4425 if (handler->cbs.update_mode.cb) {
4426 handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
4427 handler->cbs.update_mode.cb = NULL;
4428 handler->cbs.update_mode.data = NULL;
4431 if (handler->cbs.access_event.cb) {
4432 handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
4433 handler->cbs.access_event.cb = NULL;
4434 handler->cbs.access_event.data = NULL;
4437 if (handler->cbs.key_event.cb) {
4438 handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
4439 handler->cbs.key_event.cb = NULL;
4440 handler->cbs.key_event.data = NULL;
4443 dlist_remove_data(s_info.livebox_list, handler);
4445 handler->state = DESTROYED;
4446 if (lb_common_unref(handler->common, handler) == 0) {
4447 if (destroy_common) {
4450 * Lock file should be deleted after all callbacks are processed.
4452 lb_destroy_lock_file(handler->common, 0);
4453 lb_destroy_common_handle(handler->common);
4457 DbgPrint("Handler is released\n");
4461 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
4463 struct packet *packet;
4464 struct cb_info *cbinfo;
4467 if (handler->common->request.deleted) {
4468 ErrPrint("Already in-progress\n");
4470 cb(handler, LB_STATUS_SUCCESS, data);
4472 return LB_STATUS_ERROR_BUSY;
4476 cb = default_delete_cb;
4479 packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp);
4481 ErrPrint("Failed to build a param\n");
4483 cb(handler, LB_STATUS_ERROR_FAULT, data);
4486 return LB_STATUS_ERROR_FAULT;
4489 cbinfo = create_cb_info(cb, data);
4491 packet_destroy(packet);
4492 ErrPrint("Failed to create cbinfo\n");
4494 cb(handler, LB_STATUS_ERROR_FAULT, data);
4497 return LB_STATUS_ERROR_FAULT;
4500 ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
4503 * Packet is destroyed by master_rpc_async_request.
4505 destroy_cb_info(cbinfo);
4508 cb(handler, LB_STATUS_ERROR_FAULT, data);
4511 handler->common->request.deleted = 1;
4517 EAPI int livebox_client_paused(void)
4519 struct packet *packet;
4521 packet = packet_create_noack("client_paused", "d", util_timestamp());
4523 ErrPrint("Failed to create a pause packet\n");
4524 return LB_STATUS_ERROR_FAULT;
4527 return master_rpc_request_only(NULL, packet);
4530 EAPI int livebox_client_resumed(void)
4532 struct packet *packet;
4534 packet = packet_create_noack("client_resumed", "d", util_timestamp());
4536 ErrPrint("Failed to create a resume packet\n");
4537 return LB_STATUS_ERROR_FAULT;
4540 return master_rpc_request_only(NULL, packet);
4543 EAPI int livebox_sync_lb_fb(struct livebox *handler)
4545 if (!handler || handler->state != CREATE) {
4546 ErrPrint("Invalid handle\n");
4547 return LB_STATUS_ERROR_INVALID;
4550 if (!handler->common || handler->common->state != CREATE) {
4551 ErrPrint("Invalid handle\n");
4552 return LB_STATUS_ERROR_INVALID;
4555 if (!handler->common->id) {
4556 return LB_STATUS_ERROR_INVALID;
4559 return lb_sync_lb_fb(handler->common);
4562 int lb_sync_lb_fb(struct livebox_common *common)
4566 if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
4567 (void)do_fb_lock(common->lb.lock_fd);
4568 ret = fb_sync(lb_get_lb_fb(common));
4569 (void)do_fb_unlock(common->lb.lock_fd);
4571 ret = fb_sync(lb_get_lb_fb(common));
4577 int lb_sync_pd_fb(struct livebox_common *common)
4581 if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
4582 (void)do_fb_lock(common->pd.lock_fd);
4583 ret = fb_sync(lb_get_pd_fb(common));
4584 (void)do_fb_unlock(common->pd.lock_fd);
4586 ret = fb_sync(lb_get_pd_fb(common));
4592 EAPI int livebox_sync_pd_fb(struct livebox *handler)
4594 if (!handler || handler->state != CREATE) {
4595 ErrPrint("Invalid handle\n");
4596 return LB_STATUS_ERROR_INVALID;
4599 if (!handler->common || handler->common->state != CREATE) {
4600 ErrPrint("Invalid handle\n");
4601 return LB_STATUS_ERROR_INVALID;
4604 if (!handler->common->id) {
4605 ErrPrint("Invalid handle\n");
4606 return LB_STATUS_ERROR_INVALID;
4609 return lb_sync_pd_fb(handler->common);
4612 EAPI const char *livebox_alt_icon(struct livebox *handler)
4614 if (!handler || handler->state != CREATE) {
4615 ErrPrint("Handler is not valid[%p]\n", handler);
4619 if (!handler->common || handler->common->state != CREATE) {
4620 ErrPrint("Handler is not valid\n");
4624 return handler->common->alt.icon;
4627 EAPI const char *livebox_alt_name(struct livebox *handler)
4629 if (!handler || handler->state != CREATE) {
4630 ErrPrint("Handler is not valid[%p]\n", handler);
4634 if (!handler->common || handler->common->state != CREATE) {
4635 ErrPrint("Handler is not valid\n");
4639 return handler->common->alt.name;
4642 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
4644 int ret = LB_STATUS_SUCCESS;
4647 if (!handler || handler->state != CREATE) {
4648 ErrPrint("Handler is not valid[%p]\n", handler);
4649 return LB_STATUS_ERROR_INVALID;
4652 if (!handler->common || handler->common->state != CREATE) {
4653 ErrPrint("Handler is not valid\n");
4654 return LB_STATUS_ERROR_INVALID;
4657 if (!handler->common->id) {
4658 ErrPrint("Handler is not valid[%p]\n", handler);
4659 return LB_STATUS_ERROR_INVALID;
4663 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4664 DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4665 return LB_STATUS_ERROR_INVALID;
4668 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4669 return LB_STATUS_SUCCESS;
4672 fd = handler->common->pd.lock_fd;
4674 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4675 DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4676 return LB_STATUS_ERROR_INVALID;
4679 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4680 return LB_STATUS_SUCCESS;
4683 fd = handler->common->lb.lock_fd;
4686 ret = do_fb_lock(fd);
4688 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4691 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
4693 int ret = LB_STATUS_SUCCESS;
4696 if (!handler || handler->state != CREATE) {
4697 ErrPrint("Invalid handle\n");
4698 return LB_STATUS_ERROR_INVALID;
4701 if (!handler->common || handler->common->state != CREATE) {
4702 ErrPrint("Invalid handle\n");
4703 return LB_STATUS_ERROR_INVALID;
4706 if (!handler->common->id) {
4707 ErrPrint("Handler is not valid[%p]\n", handler);
4708 return LB_STATUS_ERROR_INVALID;
4712 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4713 DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4714 return LB_STATUS_ERROR_INVALID;
4717 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4718 return LB_STATUS_SUCCESS;
4721 fd = handler->common->pd.lock_fd;
4723 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4724 DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4725 return LB_STATUS_ERROR_INVALID;
4728 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4729 return LB_STATUS_SUCCESS;
4732 fd = handler->common->lb.lock_fd;
4735 ret = do_fb_unlock(fd);
4737 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4740 EAPI int livebox_set_option(enum livebox_option_type option, int state)
4742 int ret = LB_STATUS_SUCCESS;
4745 case LB_OPTION_MANUAL_SYNC:
4746 conf_set_manual_sync(state);
4748 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4749 conf_set_frame_drop_for_resizing(state);
4751 case LB_OPTION_SHARED_CONTENT:
4752 conf_set_shared_content(state);
4755 ret = LB_STATUS_ERROR_INVALID;
4762 EAPI int livebox_option(enum livebox_option_type option)
4767 case LB_OPTION_MANUAL_SYNC:
4768 ret = conf_manual_sync();
4770 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4771 ret = conf_frame_drop_for_resizing();
4773 case LB_OPTION_SHARED_CONTENT:
4774 ret = conf_shared_content();
4777 ret = LB_STATUS_ERROR_INVALID;