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")))
52 static int default_launch_handler(struct livebox *handler, const char *appid, void *data);
55 INFO_STATE_CALLBACK_IN_IDLE = 0x00,
56 INFO_STATE_CALLBACK_IN_PROCESSING = 0x01,
60 struct dlist *livebox_list;
61 struct dlist *livebox_common_list;
63 struct dlist *event_list;
64 struct dlist *fault_list;
67 int prevent_overwrite;
68 enum event_state event_state;
69 enum event_state fault_state;
71 struct dlist *job_list;
74 int (*handler)(struct livebox *handler, const char *appid, void *data);
82 .prevent_overwrite = 0,
83 .event_state = INFO_STATE_CALLBACK_IN_IDLE,
84 .fault_state = INFO_STATE_CALLBACK_IN_IDLE,
88 .handler = default_launch_handler,
100 int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data);
106 int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data);
110 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data);
111 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data);
113 static int default_launch_handler(struct livebox *handler, const char *appid, void *data)
117 ret = aul_launch_app(appid, NULL);
119 ErrPrint("Failed to launch an app %s (%d)\n", appid, ret);
125 DbgPrint("AUTO_LAUNCH [%s]\n", handler->common->lb.auto_launch);
127 ret = service_create(&service);
128 if (ret == SERVICE_ERROR_NONE) {
129 service_set_package(service, handler->common->lb.auto_launch);
130 service_send_launch_request(service, NULL, NULL);
131 service_destroy(service);
133 ErrPrint("Failed to launch an app %s (%d)\n", handler->common->lb.auto_launch, ret);
137 return ret > 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
140 static inline void default_create_cb(struct livebox *handler, int ret, void *data)
142 DbgPrint("Default created event handler: %d\n", ret);
145 static inline void default_delete_cb(struct livebox *handler, int ret, void *data)
147 DbgPrint("Default deleted event handler: %d\n", ret);
150 static inline void default_pinup_cb(struct livebox *handler, int ret, void *data)
152 DbgPrint("Default pinup event handler: %d\n", ret);
155 static inline void default_group_changed_cb(struct livebox *handler, int ret, void *data)
157 DbgPrint("Default group changed event handler: %d\n", ret);
160 static inline void default_period_changed_cb(struct livebox *handler, int ret, void *data)
162 DbgPrint("Default period changed event handler: %d\n", ret);
165 static inline void default_pd_created_cb(struct livebox *handler, int ret, void *data)
167 DbgPrint("Default PD created event handler: %d\n", ret);
170 static inline void default_pd_destroyed_cb(struct livebox *handler, int ret, void *data)
172 DbgPrint("Default PD destroyed event handler: %d\n", ret);
175 static inline void default_lb_size_changed_cb(struct livebox *handler, int ret, void *data)
177 DbgPrint("Default LB size changed event handler: %d\n", ret);
180 static inline void default_update_mode_cb(struct livebox *handler, int ret, void *data)
182 DbgPrint("Default update mode set event handler: %d\n", ret);
185 static inline void default_access_event_cb(struct livebox *handler, int ret, void *data)
187 DbgPrint("Default access event handler: %d\n", ret);
190 static inline void default_key_event_cb(struct livebox *handler, int ret, void *data)
192 DbgPrint("Default key event handler: %d\n", ret);
195 static inline __attribute__((always_inline)) struct cb_info *create_cb_info(ret_cb_t cb, void *data)
197 struct cb_info *info;
199 info = malloc(sizeof(*info));
201 ErrPrint("Heap: %s\n", strerror(errno));
210 static inline void destroy_cb_info(struct cb_info *info)
215 static int do_fb_lock(int fd)
220 flock.l_type = F_RDLCK;
221 flock.l_whence = SEEK_SET;
224 flock.l_pid = getpid();
227 ret = fcntl(fd, F_SETLKW, &flock);
230 ErrPrint("fcntl: %s\n", strerror(errno));
232 } while (ret == EINTR);
237 static int do_fb_unlock(int fd)
242 flock.l_type = F_UNLCK;
243 flock.l_whence = SEEK_SET;
246 flock.l_pid = getpid();
249 ret = fcntl(fd, F_SETLKW, &flock);
252 ErrPrint("fcntl: %s\n", strerror(errno));
254 } while (ret == EINTR);
259 int lb_destroy_lock_file(struct livebox_common *common, int is_pd)
262 if (!common->pd.lock) {
263 return LB_STATUS_ERROR_INVALID;
266 if (close(common->pd.lock_fd) < 0) {
267 ErrPrint("close: %s\n", strerror(errno));
269 common->pd.lock_fd = -1;
271 if (unlink(common->pd.lock) < 0) {
272 ErrPrint("unlink: %s\n", strerror(errno));
275 free(common->pd.lock);
276 common->pd.lock = NULL;
278 if (!common->lb.lock) {
279 return LB_STATUS_ERROR_INVALID;
282 if (close(common->lb.lock_fd) < 0) {
283 ErrPrint("close: %s\n", strerror(errno));
285 common->lb.lock_fd = -1;
287 if (unlink(common->lb.lock) < 0) {
288 ErrPrint("unlink: %s\n", strerror(errno));
291 free(common->lb.lock);
292 common->lb.lock = NULL;
295 return LB_STATUS_SUCCESS;
298 int lb_create_lock_file(struct livebox_common *common, int is_pd)
303 len = strlen(common->id);
304 file = malloc(len + 20);
306 ErrPrint("Heap: %s\n", strerror(errno));
307 return LB_STATUS_ERROR_MEMORY;
310 snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(common->id), is_pd ? "pd" : "lb");
313 common->pd.lock_fd = open(file, O_RDONLY);
314 if (common->pd.lock_fd < 0) {
315 ErrPrint("open: %s\n", strerror(errno));
317 return LB_STATUS_ERROR_IO;
320 common->pd.lock = file;
322 common->lb.lock_fd = open(file, O_RDONLY);
323 if (common->lb.lock_fd < 0) {
324 ErrPrint("open: %s\n", strerror(errno));
326 return LB_STATUS_ERROR_IO;
329 common->lb.lock = file;
332 return LB_STATUS_SUCCESS;
335 static void update_mode_cb(struct livebox *handler, const struct packet *result, void *data)
340 ret = LB_STATUS_ERROR_FAULT;
342 } else if (packet_get(result, "i", &ret) != 1) {
343 ErrPrint("Invalid argument\n");
344 ret = LB_STATUS_ERROR_INVALID;
349 ErrPrint("Resize request is failed: %d\n", ret);
356 handler->cbs.update_mode.cb(handler, ret, handler->cbs.update_mode.data);
357 handler->cbs.update_mode.cb = NULL;
358 handler->cbs.update_mode.data = NULL;
359 handler->common->request.update_mode = 0;
361 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
362 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
363 lb_unref(handler, 1);
367 static void resize_cb(struct livebox *handler, const struct packet *result, void *data)
372 ret = LB_STATUS_ERROR_FAULT;
374 } else if (packet_get(result, "i", &ret) != 1) {
375 ErrPrint("Invalid argument\n");
376 ret = LB_STATUS_ERROR_INVALID;
382 * In case of resize request,
383 * The livebox handler will not have resized value right after this callback,
384 * It can only get the new size when it makes updates.
386 * So the user can only get the resized value(result) from the first update event
387 * after this request.
390 ErrPrint("Resize request is failed: %d\n", ret);
397 handler->cbs.size_changed.cb(handler, ret, handler->cbs.size_changed.data);
398 handler->cbs.size_changed.cb = NULL;
399 handler->cbs.size_changed.data = NULL;
400 handler->common->request.size_changed = 0;
402 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
403 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
404 lb_unref(handler, 1);
408 static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data)
412 struct cb_info *info = data;
417 destroy_cb_info(info);
420 ret = LB_STATUS_ERROR_FAULT;
421 } else if (packet_get(result, "i", &ret) != 1) {
422 ErrPrint("Invalid argument\n");
423 ret = LB_STATUS_ERROR_INVALID;
427 cb(handler, ret, cbdata);
432 static void set_group_ret_cb(struct livebox *handler, const struct packet *result, void *data)
437 ret = LB_STATUS_ERROR_FAULT;
439 } else if (packet_get(result, "i", &ret) != 1) {
440 ErrPrint("Invalid argument\n");
441 ret = LB_STATUS_ERROR_INVALID;
452 handler->cbs.group_changed.cb(handler, ret, handler->cbs.group_changed.data);
453 handler->cbs.group_changed.cb = NULL;
454 handler->cbs.group_changed.data = NULL;
455 handler->common->request.group_changed = 0;
457 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
458 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
459 lb_unref(handler, 1);
463 static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data)
468 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;
483 handler->cbs.period_changed.cb(handler, ret, handler->cbs.period_changed.data);
484 handler->cbs.period_changed.cb = NULL;
485 handler->cbs.period_changed.data = NULL;
486 handler->common->request.period_changed = 0;
488 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
489 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
490 lb_unref(handler, 1);
494 static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data)
496 struct cb_info *info = data;
503 destroy_cb_info(info);
506 ErrPrint("Connection lost?\n");
507 ret = LB_STATUS_ERROR_FAULT;
508 } else if (packet_get(result, "i", &ret) != 1) {
509 ErrPrint("Invalid argument\n");
510 ret = LB_STATUS_ERROR_INVALID;
514 handler->cbs.deleted.cb = cb;
515 handler->cbs.deleted.data = cbdata;
517 cb(handler, ret, cbdata);
522 * Do not call the deleted callback from here.
523 * master will send the "deleted" event.
524 * Then invoke this callback.
526 * if (handler->cbs.deleted.cb)
527 * handler->cbs.deleted.cb(handler, ret, handler->cbs.deleted.data);
531 static void new_ret_cb(struct livebox *handler, const struct packet *result, void *data)
534 struct cb_info *info = data;
540 destroy_cb_info(info);
543 ret = LB_STATUS_ERROR_FAULT;
544 } else if (packet_get(result, "i", &ret) != 1) {
545 ret = LB_STATUS_ERROR_INVALID;
549 handler->cbs.created.cb = cb;
550 handler->cbs.created.data = cbdata;
554 * Don't go anymore ;)
560 * It means the current instance is not created,
561 * so user has to know about this.
562 * notice it to user using "deleted" event.
564 cb(handler, ret, cbdata);
567 lb_unref(handler, 1);
570 static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data)
575 ret = LB_STATUS_ERROR_FAULT;
577 } else if (packet_get(result, "i", &ret) != 1) {
578 ret = LB_STATUS_ERROR_INVALID;
583 ErrPrint("Failed to create a PD[%d]\n", ret);
590 handler->cbs.pd_created.cb(handler, ret, handler->cbs.pd_created.data);
591 handler->cbs.pd_created.cb = NULL;
592 handler->cbs.pd_created.data = NULL;
593 handler->common->request.pd_created = 0;
595 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
596 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
597 lb_unref(handler, 1);
601 static void activated_cb(struct livebox *handler, const struct packet *result, void *data)
604 struct cb_info *info = data;
607 const char *pkgname = "";
611 destroy_cb_info(info);
614 ret = LB_STATUS_ERROR_FAULT;
615 } else if (packet_get(result, "is", &ret, &pkgname) != 2) {
616 ret = LB_STATUS_ERROR_INVALID;
620 cb(handler, ret, cbdata);
624 static void pd_destroy_cb(struct livebox *handler, const struct packet *result, void *data)
629 struct cb_info *info = data;
633 destroy_cb_info(info);
636 ErrPrint("Result is NIL (may connection lost)\n");
637 ret = LB_STATUS_ERROR_FAULT;
638 } else if (packet_get(result, "i", &ret) != 1) {
639 ErrPrint("Invalid parameter\n");
640 ret = LB_STATUS_ERROR_INVALID;
643 if (ret == (int)LB_STATUS_SUCCESS) {
644 handler->cbs.pd_destroyed.cb = cb;
645 handler->cbs.pd_destroyed.data = cbdata;
647 handler->common->is_pd_created = 0;
648 handler->common->request.pd_destroyed = 0;
651 cb(handler, ret, cbdata);
656 static void delete_cluster_cb(struct livebox *handler, const struct packet *result, void *data)
658 struct cb_info *info = data;
665 destroy_cb_info(info);
668 ret = LB_STATUS_ERROR_FAULT;
669 } else if (packet_get(result, "i", &ret) != 1) {
670 ret = LB_STATUS_ERROR_INVALID;
674 cb(handler, ret, cbdata);
678 static void delete_category_cb(struct livebox *handler, const struct packet *result, void *data)
680 struct cb_info *info = data;
687 destroy_cb_info(info);
690 ret = LB_STATUS_ERROR_FAULT;
691 } else if (packet_get(result, "i", &ret) != 1) {
692 ret = LB_STATUS_ERROR_INVALID;
696 cb(handler, ret, cbdata);
700 static int lb_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
702 struct packet *packet;
703 struct cb_info *cbinfo;
707 id = fb_id(handler->common->lb.fb);
708 if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
709 return LB_STATUS_ERROR_INVALID;
712 packet = packet_create("lb_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
714 ErrPrint("Failed to build a param\n");
715 return LB_STATUS_ERROR_FAULT;
718 cbinfo = create_cb_info(cb, data);
720 packet_destroy(packet);
721 return LB_STATUS_ERROR_FAULT;
724 ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo);
726 destroy_cb_info(cbinfo);
732 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
735 int ret = LB_STATUS_ERROR_INVALID;
738 struct cb_info *info = data;
742 destroy_cb_info(info);
745 pixmap = 0; /* PIXMAP 0 means error */
746 } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
750 if (ret == (int)LB_STATUS_ERROR_BUSY) {
751 ret = lb_acquire_lb_pixmap(handler, cb, cbdata);
752 DbgPrint("Busy, Try again: %d\n", ret);
754 } else if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
756 cb(handler, pixmap, cbdata);
759 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
760 lb_unref(handler, 1);
763 cb(handler, pixmap, cbdata);
768 static int lb_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
770 struct packet *packet;
771 struct cb_info *cbinfo;
775 id = fb_id(handler->common->pd.fb);
776 if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
777 return LB_STATUS_ERROR_INVALID;
780 packet = packet_create("pd_acquire_pixmap", "ss", handler->common->pkgname, handler->common->id);
782 ErrPrint("Failed to build a param\n");
783 return LB_STATUS_ERROR_FAULT;
786 cbinfo = create_cb_info(cb, data);
788 packet_destroy(packet);
789 return LB_STATUS_ERROR_FAULT;
792 ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo);
796 * Packet will be destroyed by master_rpc_async_request
798 destroy_cb_info(cbinfo);
804 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
810 struct cb_info *info = data;
814 destroy_cb_info(info);
817 pixmap = 0; /* PIXMAP 0 means error */
818 ret = LB_STATUS_ERROR_FAULT;
819 } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
821 ret = LB_STATUS_ERROR_INVALID;
824 if (ret == (int)LB_STATUS_ERROR_BUSY) {
825 ret = lb_acquire_pd_pixmap(handler, cb, cbdata);
826 DbgPrint("Busy, Try again: %d\n", ret);
828 } else if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
830 cb(handler, pixmap, cbdata);
832 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
833 lb_unref(handler, 1);
836 DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap);
837 cb(handler, pixmap, cbdata);
842 static void pinup_done_cb(struct livebox *handler, const struct packet *result, void *data)
847 ret = LB_STATUS_ERROR_FAULT;
849 } else if (packet_get(result, "i", &ret) != 1) {
860 handler->cbs.pinup.cb(handler, ret, handler->cbs.pinup.data);
861 handler->cbs.pinup.cb = NULL;
862 handler->cbs.pinup.data = NULL;
863 handler->common->request.pinup = 0;
865 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
866 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
867 lb_unref(handler, 1);
871 static void key_ret_cb(struct livebox *handler, const struct packet *result, void *data)
876 ret = LB_STATUS_ERROR_FAULT;
880 if (packet_get(result, "i", &ret) != 1) {
881 ret = LB_STATUS_ERROR_INVALID;
885 if (ret != LB_STATUS_SUCCESS) {
891 handler->cbs.key_event.cb(handler, ret, handler->cbs.key_event.data);
892 handler->cbs.key_event.cb = NULL;
893 handler->cbs.key_event.data = NULL;
894 handler->common->request.key_event = 0;
896 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
897 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
898 lb_unref(handler, 1);
902 static void access_ret_cb(struct livebox *handler, const struct packet *result, void *data)
907 ret = LB_STATUS_ERROR_FAULT;
911 if (packet_get(result, "i", &ret) != 1) {
912 ret = LB_STATUS_ERROR_INVALID;
916 if (ret != LB_STATUS_SUCCESS) {
923 handler->cbs.access_event.cb(handler, ret, handler->cbs.access_event.data);
924 handler->cbs.access_event.cb = NULL;
925 handler->cbs.access_event.data = NULL;
926 handler->common->request.access_event = 0;
928 if (ret == (int)LB_STATUS_ERROR_NOT_EXIST && handler->refcnt == 2) {
929 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
930 lb_unref(handler, 1);
934 static int send_access_event(struct livebox *handler, const char *event, int x, int y)
936 struct packet *packet;
939 timestamp = util_timestamp();
941 packet = packet_create(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
943 ErrPrint("Failed to build packet\n");
944 return LB_STATUS_ERROR_FAULT;
947 return master_rpc_async_request(handler, packet, 0, access_ret_cb, NULL);
950 static int send_key_event(struct livebox *handler, const char *event, unsigned int keycode)
952 struct packet *packet;
955 timestamp = util_timestamp();
956 packet = packet_create(event, "ssdi", handler->common->pkgname, handler->common->id, timestamp, keycode);
958 ErrPrint("Failed to build packet\n");
959 return LB_STATUS_ERROR_FAULT;
962 return master_rpc_async_request(handler, packet, 0, key_ret_cb, NULL);
965 static int send_mouse_event(struct livebox *handler, const char *event, int x, int y)
967 struct packet *packet;
970 timestamp = util_timestamp();
971 packet = packet_create_noack(event, "ssdii", handler->common->pkgname, handler->common->id, timestamp, x, y);
973 ErrPrint("Failed to build param\n");
974 return LB_STATUS_ERROR_FAULT;
977 return master_rpc_request_only(handler, packet);
980 static void initialize_livebox(void *disp, int use_thread)
983 char filename[BUFSIZ];
984 snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid());
985 __file_log_fp = fopen(filename, "w+t");
986 if (!__file_log_fp) {
987 __file_log_fp = fdopen(1, "w+t");
990 livebox_service_init();
993 client_init(use_thread);
998 EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread)
1000 if (s_info.init_count > 0) {
1001 s_info.init_count++;
1002 return LB_STATUS_SUCCESS;
1007 * Some application doesn't want to use the environment value.
1008 * So set them using arguments.
1010 s_info.prevent_overwrite = prevent_overwrite;
1011 conf_set_event_filter(event_filter);
1013 initialize_livebox(disp, use_thread);
1014 return LB_STATUS_SUCCESS;
1017 EAPI int livebox_init(void *disp)
1021 if (s_info.init_count > 0) {
1022 s_info.init_count++;
1023 return LB_STATUS_SUCCESS;
1026 env = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE");
1027 if (env && !strcasecmp(env, "true")) {
1028 s_info.prevent_overwrite = 1;
1031 env = getenv("PROVIDER_EVENT_FILTER");
1033 double event_filter;
1034 if (sscanf(env, "%lf", &event_filter) == 1) {
1035 conf_set_event_filter(event_filter);
1039 initialize_livebox(disp, 0);
1040 return LB_STATUS_SUCCESS;
1043 EAPI int livebox_fini(void)
1045 if (s_info.init_count <= 0) {
1046 ErrPrint("Doesn't initialized\n");
1047 return LB_STATUS_ERROR_INVALID;
1050 s_info.init_count--;
1051 if (s_info.init_count > 0) {
1052 ErrPrint("init count : %d\n", s_info.init_count);
1053 return LB_STATUS_SUCCESS;
1058 livebox_service_fini();
1059 return LB_STATUS_SUCCESS;
1062 static inline char *lb_pkgname(const char *pkgname)
1066 lb = livebox_service_pkgname(pkgname);
1068 if (util_validate_livebox_package(pkgname) == 0) {
1069 return strdup(pkgname);
1076 static struct livebox_common *find_sharable_common_handle(const char *pkgname, const char *content, int w, int h, const char *cluster, const char *category)
1079 struct livebox_common *common;
1081 if (!conf_shared_content()) {
1083 * Shared content option is turnned off.
1088 dlist_foreach(s_info.livebox_common_list, l, common) {
1089 if (common->state != CREATE) {
1093 if (strcmp(common->pkgname, pkgname)) {
1097 if (strcmp(common->cluster, cluster)) {
1098 DbgPrint("Cluster mismatched\n");
1102 if (strcmp(common->category, category)) {
1103 DbgPrint("Category mismatched\n");
1107 if (common->content && content) {
1108 if (strcmp(common->content, content)) {
1109 DbgPrint("%s Content ([%s] <> [%s])\n", common->pkgname, common->content, content);
1118 * We assumes "" (ZERO length string) to NULL
1120 c1_len = common->content ? strlen(common->content) : 0;
1121 c2_len = content ? strlen(content) : 0;
1122 if (c1_len != c2_len) {
1123 DbgPrint("%s Content %p <> %p\n", common->pkgname, common->content, content);
1128 if (common->request.size_changed) {
1129 DbgPrint("Changing size\n");
1132 * Do not re-use resizing instance.
1133 * We will not use predicted size.
1138 if (common->request.created) {
1139 DbgPrint("Creating now but re-use it (%s)\n", common->pkgname);
1142 if (common->lb.width != w || common->lb.height != h) {
1143 DbgPrint("Size mismatched\n");
1147 DbgPrint("common handle is found: %p\n", common);
1155 * Just wrapping the livebox_add_with_size function.
1157 EAPI struct livebox *livebox_add(const char *pkgname, const char *content, const char *cluster, const char *category, double period, ret_cb_t cb, void *data)
1159 return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data);
1162 static gboolean job_execute_cb(void *data)
1164 struct job_item *item;
1167 l = dlist_nth(s_info.job_list, 0);
1169 s_info.job_timer = 0;
1173 item = dlist_data(l);
1174 s_info.job_list = dlist_remove(s_info.job_list, l);
1177 item->cb(item->handle, item->ret, item->data);
1178 lb_unref(item->handle, 1);
1185 static int job_add(struct livebox *handle, ret_cb_t job_cb, int ret, void *data)
1187 struct job_item *item;
1190 ErrPrint("Invalid argument\n");
1191 return LB_STATUS_ERROR_INVALID;
1194 item = malloc(sizeof(*item));
1196 ErrPrint("Heap: %s\n", strerror(errno));
1197 return LB_STATUS_ERROR_MEMORY;
1200 item->handle = lb_ref(handle);
1205 s_info.job_list = dlist_append(s_info.job_list, item);
1207 if (!s_info.job_timer) {
1208 s_info.job_timer = g_timeout_add(1, job_execute_cb, NULL);
1209 if (!s_info.job_timer) {
1210 ErrPrint("Failed to create a job timer\n");
1214 return LB_STATUS_SUCCESS;
1217 static int create_real_instance(struct livebox *handler, ret_cb_t cb, void *data)
1219 struct cb_info *cbinfo;
1220 struct packet *packet;
1221 struct livebox_common *common;
1224 common = handler->common;
1226 packet = packet_create("new", "dssssdii",
1227 common->timestamp, common->pkgname, common->content,
1228 common->cluster, common->category,
1229 common->lb.period, common->lb.width, common->lb.height);
1231 ErrPrint("Failed to create a new packet\n");
1232 return LB_STATUS_ERROR_FAULT;
1235 cbinfo = create_cb_info(cb, data);
1237 ErrPrint("Failed to create a cbinfo\n");
1238 packet_destroy(packet);
1239 return LB_STATUS_ERROR_MEMORY;
1244 * master_rpc_async_request will destroy the packet (decrease the refcnt)
1245 * So be aware the packet object after return from master_rpc_async_request.
1247 ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo);
1249 ErrPrint("Failed to send a new packet\n");
1250 destroy_cb_info(cbinfo);
1251 return LB_STATUS_ERROR_FAULT;
1253 handler->common->request.created = 1;
1254 return LB_STATUS_SUCCESS;
1257 static void create_cb(struct livebox *handle, int ret, void *data)
1259 struct cb_info *cbinfo = data;
1262 cbinfo->cb(handle, ret, cbinfo->data);
1265 destroy_cb_info(cbinfo);
1269 * Forcely generate "updated" event
1271 lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
1274 static int create_fake_instance(struct livebox *handler, ret_cb_t cb, void *data)
1276 struct cb_info *cbinfo;
1278 cbinfo = create_cb_info(cb, data);
1280 ErrPrint("Failed to create a cbinfo\n");
1281 return LB_STATUS_ERROR_MEMORY;
1284 if (job_add(handler, create_cb, LB_STATUS_SUCCESS, cbinfo) != LB_STATUS_SUCCESS) {
1285 destroy_cb_info(cbinfo);
1288 return LB_STATUS_SUCCESS;
1291 struct livebox_common *lb_create_common_handle(struct livebox *handle, const char *pkgname, const char *cluster, const char *category)
1293 struct livebox_common *common;
1295 common = calloc(1, sizeof(*common));
1297 ErrPrint("Heap: %s\n", strerror(errno));
1301 common->pkgname = strdup(pkgname);
1302 if (!common->pkgname) {
1307 common->cluster = strdup(cluster);
1308 if (!common->cluster) {
1309 ErrPrint("Error: %s\n", strerror(errno));
1310 free(common->pkgname);
1315 common->category = strdup(category);
1316 if (!common->category) {
1317 ErrPrint("Error: %s\n", strerror(errno));
1318 free(common->cluster);
1319 free(common->pkgname);
1324 /* Data provider will set this */
1325 common->lb.type = _LB_TYPE_FILE;
1326 common->pd.type = _PD_TYPE_SCRIPT;
1328 /* Used for handling the mouse event on a box */
1329 common->lb.mouse_event = 0;
1331 /* Cluster infomration is not determined yet */
1332 common->nr_of_sizes = 0x01;
1334 common->timestamp = util_timestamp();
1335 common->is_user = 1;
1336 common->delete_type = LB_DELETE_PERMANENTLY;
1337 common->pd.lock = NULL;
1338 common->pd.lock_fd = -1;
1339 common->lb.lock = NULL;
1340 common->lb.lock_fd = -1;
1342 common->state = CREATE;
1343 common->visible = LB_SHOW;
1345 s_info.livebox_common_list = dlist_append(s_info.livebox_common_list, common);
1349 int lb_destroy_common_handle(struct livebox_common *common)
1351 dlist_remove_data(s_info.livebox_common_list, common);
1353 common->state = DESTROYED;
1355 if (common->filename) {
1356 (void)util_unlink(common->filename);
1359 free(common->cluster);
1360 free(common->category);
1362 free(common->pkgname);
1363 free(common->filename);
1364 free(common->lb.auto_launch);
1365 free(common->alt.icon);
1366 free(common->alt.name);
1368 if (common->lb.fb) {
1369 fb_destroy(common->lb.fb);
1370 common->lb.fb = NULL;
1373 if (common->pd.fb) {
1374 fb_destroy(common->pd.fb);
1375 common->pd.fb = NULL;
1381 int lb_common_ref(struct livebox_common *common, struct livebox *handle)
1383 common->livebox_list = dlist_append(common->livebox_list, handle);
1386 return common->refcnt;
1389 int lb_common_unref(struct livebox_common *common, struct livebox *handle)
1392 dlist_remove_data(common->livebox_list, handle);
1393 refcnt = --common->refcnt;
1398 static void refresh_for_paused_updating_cb(struct livebox *handle, int ret, void *data)
1400 if (handle->paused_updating == 0) {
1401 DbgPrint("Paused updates are cleared\n");
1405 DbgPrint("Pending updates are found\n");
1406 lb_invoke_event_handler(handle, LB_EVENT_LB_UPDATED);
1409 static int lb_set_visibility(struct livebox *handler, enum livebox_visible_state state)
1411 struct packet *packet;
1412 int need_to_add_job = 0;
1415 if (handler->common->visible != LB_SHOW && state == LB_SHOW) {
1416 need_to_add_job = !!handler->paused_updating;
1417 } else if (handler->common->visible == LB_SHOW && state != LB_SHOW) {
1419 struct livebox *item;
1421 dlist_foreach(handler->common->livebox_list, l, item) {
1422 if (item->visible == LB_SHOW) {
1423 DbgPrint("%s visibility is not changed\n", handler->common->pkgname);
1424 return LB_STATUS_SUCCESS;
1427 } else if (handler->common->visible == LB_SHOW && state == LB_SHOW && handler->paused_updating) {
1428 if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1429 ErrPrint("Unable to add a new job for refreshing box\n");
1432 return LB_STATUS_SUCCESS;
1436 * No need to send this to the master
1438 return LB_STATUS_SUCCESS;
1441 packet = packet_create_noack("change,visibility", "ssi", handler->common->pkgname, handler->common->id, (int)state);
1443 ErrPrint("Failed to create a packet\n");
1444 return LB_STATUS_ERROR_FAULT;
1447 ret = master_rpc_request_only(handler, packet);
1448 if (ret == (int)LB_STATUS_SUCCESS) {
1449 DbgPrint("[%s] visibility is changed 0x[%x]\n", handler->common->pkgname, state);
1450 handler->common->visible = state;
1452 if (need_to_add_job) {
1453 if (job_add(handler, refresh_for_paused_updating_cb, LB_STATUS_SUCCESS, NULL) < 0) {
1454 ErrPrint("Unable to add a new job for refreshing box\n");
1462 EAPI struct livebox *livebox_add_with_size(const char *pkgname, const char *content, const char *cluster, const char *category, double period, int type, ret_cb_t cb, void *data)
1465 struct livebox *handler;
1469 if (!pkgname || !cluster || !category) {
1470 ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
1471 pkgname, cluster, category);
1475 lbid = lb_pkgname(pkgname);
1477 ErrPrint("Invalid package: %s\n", pkgname);
1481 if (livebox_service_is_enabled(lbid) == 0) {
1482 DbgPrint("Livebox [%s](%s) is disabled package\n", lbid, pkgname);
1487 if (type != LB_SIZE_TYPE_UNKNOWN) {
1488 (void)livebox_service_get_size(type, &w, &h);
1491 handler = calloc(1, sizeof(*handler));
1493 ErrPrint("Error: %s\n", strerror(errno));
1499 cb = default_create_cb;
1502 handler->common = find_sharable_common_handle(lbid, content, w, h, cluster, category);
1503 if (!handler->common) {
1504 handler->common = lb_create_common_handle(handler, lbid, cluster, category);
1506 if (!handler->common) {
1507 ErrPrint("Failed to find common handle\n");
1512 if (!content || !strlen(content)) {
1516 * I know the content should not be modified. use it temporarly without "const"
1518 pc = livebox_service_content(handler->common->pkgname);
1519 lb_set_content(handler->common, pc);
1522 lb_set_content(handler->common, content);
1525 lb_set_period(handler->common, period);
1526 lb_set_size(handler->common, w, h);
1527 lb_common_ref(handler->common, handler);
1529 if (create_real_instance(handler, cb, data) < 0) {
1530 if (lb_common_unref(handler->common, handler) == 0) {
1534 lb_destroy_common_handle(handler->common);
1535 handler->common = NULL;
1543 lb_common_ref(handler->common, handler);
1545 if (handler->common->request.created) {
1547 * If a box is in creating, wait its result too
1549 handler->cbs.created.cb = cb;
1550 handler->cbs.created.data = data;
1553 * or fire the fake created_event
1555 if (create_fake_instance(handler, cb, data) < 0) {
1556 if (lb_common_unref(handler->common, handler) == 0) {
1560 lb_destroy_common_handle(handler->common);
1568 handler->visible = LB_SHOW;
1569 handler->state = CREATE;
1570 handler = lb_ref(handler);
1572 if (handler->common->visible != LB_SHOW) {
1573 lb_set_visibility(handler, LB_SHOW);
1579 EAPI double livebox_period(struct livebox *handler)
1581 if (!handler || handler->state != CREATE) {
1582 ErrPrint("Handler is not valid\n");
1586 if (!handler->common || handler->common->state != CREATE) {
1587 ErrPrint("Invalid handle\n");
1591 if (!handler->common->id) {
1592 ErrPrint("Hnalder is not valid\n");
1596 return handler->common->lb.period;
1599 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
1601 struct packet *packet;
1604 if (!handler || handler->state != CREATE) {
1605 ErrPrint("Handler is not valid\n");
1606 return LB_STATUS_ERROR_INVALID;
1609 if (!handler->common || handler->common->state != CREATE) {
1610 ErrPrint("Invalid handle\n");
1611 return LB_STATUS_ERROR_INVALID;
1614 if (!handler->common->id) {
1615 ErrPrint("Handler is not valid\n");
1616 return LB_STATUS_ERROR_INVALID;
1619 if (handler->common->request.period_changed) {
1620 ErrPrint("Previous request for changing period is not finished\n");
1621 return LB_STATUS_ERROR_BUSY;
1624 if (!handler->common->is_user) {
1625 ErrPrint("CA Livebox is not able to change the period\n");
1626 return LB_STATUS_ERROR_PERMISSION;
1629 if (handler->common->lb.period == period) {
1630 DbgPrint("No changes\n");
1631 return LB_STATUS_ERROR_ALREADY;
1634 packet = packet_create("set_period", "ssd", handler->common->pkgname, handler->common->id, period);
1636 ErrPrint("Failed to build a packet %s\n", handler->common->pkgname);
1637 return LB_STATUS_ERROR_FAULT;
1641 cb = default_period_changed_cb;
1644 ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
1645 if (ret == (int)LB_STATUS_SUCCESS) {
1646 handler->cbs.period_changed.cb = cb;
1647 handler->cbs.period_changed.data = data;
1648 handler->common->request.period_changed = 1;
1654 static void lb_update_visibility(struct livebox_common *old_common)
1657 struct livebox *item;
1660 dlist_foreach(old_common->livebox_list, l, item) {
1661 if (item->visible == LB_SHOW) {
1669 l = dlist_nth(old_common->livebox_list, 0);
1670 item = dlist_data(l);
1673 lb_set_visibility(item, LB_HIDE_WITH_PAUSE);
1675 ErrPrint("Unable to get the valid handle from common handler\n");
1678 lb_set_visibility(item, LB_SHOW);
1684 * The second parameter should be the "return value",
1685 * But in this case, we will use it for "type of deleting instance".
1687 static void job_del_cb(struct livebox *handle, int type, void *data)
1689 struct cb_info *cbinfo = data;
1692 if (handle->visible == LB_SHOW) {
1693 lb_update_visibility(handle->common);
1697 data = cbinfo->data;
1698 destroy_cb_info(cbinfo);
1700 if (handle->common->state != CREATE) {
1701 DbgPrint("[%s] %d\n", handle->common->pkgname, handle->refcnt);
1703 cb(handle, LB_STATUS_SUCCESS, data);
1709 if (handle->common->refcnt == 1) {
1710 handle->common->delete_type = type;
1711 handle->common->state = DELETE;
1713 if (!handle->common->id) {
1716 * The id is not determined yet.
1717 * It means a user didn't receive created event yet.
1718 * Then just stop to delete procedure from here.
1719 * Because the "created" event handle will release this.
1720 * By the way, if the user adds any callback for getting return status of this,
1724 cb(handle, LB_STATUS_SUCCESS, data);
1728 DbgPrint("Send delete request\n");
1729 lb_send_delete(handle, type, cb, data);
1732 cb(handle, LB_STATUS_SUCCESS, data);
1735 DbgPrint("Before unref: %d\n", handle->common->refcnt);
1736 lb_unref(handle, 1);
1740 EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data)
1742 struct cb_info *cbinfo;
1745 ErrPrint("Handler is NIL\n");
1746 return LB_STATUS_ERROR_INVALID;
1749 if (handler->state != CREATE) {
1750 ErrPrint("Handler is already deleted\n");
1751 return LB_STATUS_ERROR_INVALID;
1754 handler->state = DELETE;
1756 cbinfo = create_cb_info(cb, data);
1758 ErrPrint("Failed to create a cbinfo\n");
1759 return LB_STATUS_ERROR_MEMORY;
1762 if (job_add(handler, job_del_cb, type, cbinfo) != LB_STATUS_SUCCESS) {
1763 ErrPrint("Failed to add a new job\n");
1764 destroy_cb_info(cbinfo);
1765 return LB_STATUS_ERROR_FAULT;
1768 return LB_STATUS_SUCCESS;
1771 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
1773 return livebox_del_NEW(handler, LB_DELETE_PERMANENTLY, cb, data);
1776 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
1778 struct fault_info *info;
1781 return LB_STATUS_ERROR_INVALID;
1784 info = malloc(sizeof(*info));
1786 ErrPrint("Heap: %s\n", strerror(errno));
1787 return LB_STATUS_ERROR_MEMORY;
1791 info->user_data = data;
1792 info->is_deleted = 0;
1794 s_info.fault_list = dlist_append(s_info.fault_list, info);
1795 return LB_STATUS_SUCCESS;
1798 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
1800 struct fault_info *info;
1803 dlist_foreach(s_info.fault_list, l, info) {
1804 if (info->handler == cb) {
1807 data = info->user_data;
1809 if (s_info.fault_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1810 info->is_deleted = 1;
1812 s_info.fault_list = dlist_remove(s_info.fault_list, l);
1823 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
1825 struct event_info *info;
1828 ErrPrint("Invalid argument cb is nil\n");
1829 return LB_STATUS_ERROR_INVALID;
1832 info = malloc(sizeof(*info));
1834 ErrPrint("Heap: %s\n", strerror(errno));
1835 return LB_STATUS_ERROR_MEMORY;
1839 info->user_data = data;
1840 info->is_deleted = 0;
1842 s_info.event_list = dlist_append(s_info.event_list, info);
1843 return LB_STATUS_SUCCESS;
1846 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
1848 struct event_info *info;
1851 dlist_foreach(s_info.event_list, l, info) {
1852 if (info->handler == cb) {
1855 data = info->user_data;
1857 if (s_info.event_state == INFO_STATE_CALLBACK_IN_PROCESSING) {
1858 info->is_deleted = 1;
1860 s_info.event_list = dlist_remove(s_info.event_list, l);
1871 EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data)
1873 struct packet *packet;
1876 if (!handler || handler->state != CREATE) {
1877 ErrPrint("Handler is Invalid\n");
1878 return LB_STATUS_ERROR_INVALID;
1881 if (!handler->common || handler->common->state != CREATE) {
1882 ErrPrint("Handler is Invalid\n");
1883 return LB_STATUS_ERROR_INVALID;
1886 if (!handler->common->id) {
1887 ErrPrint("Handler is Invalid\n");
1888 return LB_STATUS_ERROR_INVALID;
1891 if (handler->common->request.update_mode) {
1892 ErrPrint("Previous update_mode cb is not finished yet\n");
1893 return LB_STATUS_ERROR_BUSY;
1896 if (handler->common->is_active_update == active_update) {
1897 return LB_STATUS_ERROR_ALREADY;
1900 if (!handler->common->is_user) {
1901 return LB_STATUS_ERROR_PERMISSION;
1904 packet = packet_create("update_mode", "ssi", handler->common->pkgname, handler->common->id, active_update);
1906 return LB_STATUS_ERROR_FAULT;
1910 cb = default_update_mode_cb;
1913 ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL);
1914 if (ret == (int)LB_STATUS_SUCCESS) {
1915 handler->cbs.update_mode.cb = cb;
1916 handler->cbs.update_mode.data = data;
1917 handler->common->request.update_mode = 1;
1923 EAPI int livebox_is_active_update(struct livebox *handler)
1925 if (!handler || handler->state != CREATE) {
1926 ErrPrint("Handler is Invalid\n");
1927 return LB_STATUS_ERROR_INVALID;
1930 if (!handler->common || handler->common->state != CREATE) {
1931 ErrPrint("Handler is Invalid\n");
1932 return LB_STATUS_ERROR_INVALID;
1935 if (!handler->common->id) {
1936 return LB_STATUS_ERROR_INVALID;
1939 return handler->common->is_active_update;
1942 static void resize_job_cb(struct livebox *handler, int ret, void *data)
1944 struct cb_info *info = data;
1947 info->cb(handler, ret, info->data);
1954 * Forcely update the box
1956 lb_invoke_event_handler(handler, LB_EVENT_LB_UPDATED);
1959 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
1961 struct livebox_common *common;
1968 * If this handle is host instance or link instance,
1969 * Create a new instance or find another linkable instance.
1972 if (!handler || handler->state != CREATE) {
1973 ErrPrint("Handler is not valid\n");
1974 return LB_STATUS_ERROR_INVALID;
1977 if (!handler->common || handler->common->state != CREATE) {
1978 ErrPrint("Invalid handle\n");
1979 return LB_STATUS_ERROR_INVALID;
1982 if (!handler->common->id) {
1983 ErrPrint("Handler is not valid\n");
1984 return LB_STATUS_ERROR_INVALID;
1989 * resize operation should be separated by each handler.
1990 * If a handler is resizing, the other handler can request resize too.
1991 * So we should not use the common->request.size_changed flag.
1993 if (handler->cbs.size_changed.cb) {
1994 ErrPrint("Previous resize request is not finished yet\n");
1995 return LB_STATUS_ERROR_BUSY;
1998 if (livebox_service_get_size(type, &w, &h) != 0) {
1999 ErrPrint("Invalid size type\n");
2000 return LB_STATUS_ERROR_INVALID;
2003 if (handler->common->lb.width == w && handler->common->lb.height == h) {
2004 DbgPrint("No changes\n");
2005 return LB_STATUS_ERROR_ALREADY;
2008 if (!handler->common->is_user) {
2009 ErrPrint("CA Livebox is not able to be resized\n");
2010 return LB_STATUS_ERROR_PERMISSION;
2013 if (handler->common->refcnt <= 1) {
2014 struct packet *packet;
2016 /* Only 1 instance */
2017 packet = packet_create("resize", "ssii", handler->common->pkgname, handler->common->id, w, h);
2019 ErrPrint("Failed to build param\n");
2020 return LB_STATUS_ERROR_FAULT;
2024 cb = default_lb_size_changed_cb;
2027 ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
2028 if (ret == (int)LB_STATUS_SUCCESS) {
2029 handler->cbs.size_changed.cb = cb;
2030 handler->cbs.size_changed.data = data;
2031 handler->common->request.size_changed = 1;
2034 common = find_sharable_common_handle(handler->common->pkgname, handler->common->content, w, h, handler->common->cluster, handler->common->category);
2036 struct livebox_common *old_common;
2039 * If the common handler is in resizing,
2040 * if user tries to resize a hander, then simply create new one even if the requested size is same with this.
2042 if (handler->common->request.size_changed) {
2047 old_common = handler->common;
2049 common = lb_create_common_handle(handler, old_common->pkgname, old_common->cluster, old_common->category);
2051 ErrPrint("Failed to create common handle\n");
2052 return LB_STATUS_ERROR_FAULT;
2055 lb_set_size(common, w, h);
2056 lb_set_content(common, old_common->content);
2057 lb_set_period(common, old_common->lb.period);
2061 * Disconnecting from old one.
2063 if (lb_common_unref(old_common, handler) == 0) {
2068 ErrPrint("Common has no associated handler\n");
2071 lb_common_ref(common, handler);
2074 * Connect to a new one
2076 handler->common = common;
2080 * Need to care, if it fails to create a common handle,
2081 * the resize operation will be failed.
2082 * in that case, we should reuse the old common handle
2084 ret = create_real_instance(handler, cb, data);
2086 lb_common_unref(common, handler);
2087 lb_destroy_common_handle(common);
2089 lb_common_ref(old_common, handler);
2090 handler->common = old_common;
2093 * In this case, we should update visibility of old_common's liveboxes
2095 if (handler->visible == LB_SHOW) {
2096 lb_update_visibility(old_common);
2100 struct cb_info *cbinfo;
2102 cbinfo = create_cb_info(cb, data);
2104 ErrPrint("Failed to create a cbinfo\n");
2105 ret = LB_STATUS_ERROR_MEMORY;
2107 ret = job_add(handler, resize_job_cb, LB_STATUS_SUCCESS, cbinfo);
2108 if (ret == (int)LB_STATUS_SUCCESS) {
2109 struct livebox_common *old_common;
2111 old_common = handler->common;
2113 if (lb_common_unref(handler->common, handler) == 0) {
2114 ErrPrint("Old common has no associated handler\n");
2117 lb_common_ref(common, handler);
2118 handler->common = common;
2120 if (handler->visible == LB_SHOW) {
2121 lb_update_visibility(old_common); /* To update visibility: Show --> Paused */
2122 lb_update_visibility(common); /* To update visibility: Paused --> Show */
2125 destroy_cb_info(cbinfo);
2134 EAPI int livebox_click(struct livebox *handler, double x, double y)
2136 struct packet *packet;
2140 if (!handler || handler->state != CREATE) {
2141 ErrPrint("Handler is invalid\n");
2142 return LB_STATUS_ERROR_INVALID;
2145 if (!handler->common || handler->common->state != CREATE) {
2146 ErrPrint("Handler is invalid\n");
2147 return LB_STATUS_ERROR_INVALID;
2150 if (!handler->common->id) {
2151 ErrPrint("Handler is not valid\n");
2152 return LB_STATUS_ERROR_INVALID;
2155 if (handler->common->lb.auto_launch) {
2156 if (s_info.launch.handler) {
2157 ret = s_info.launch.handler(handler, handler->common->lb.auto_launch, s_info.launch.data);
2159 ErrPrint("launch handler app %s (%d)\n", handler->common->lb.auto_launch, ret);
2164 timestamp = util_timestamp();
2165 DbgPrint("CLICKED: %lf\n", timestamp);
2167 packet = packet_create_noack("clicked", "sssddd", handler->common->pkgname, handler->common->id, "clicked", timestamp, x, y);
2169 ErrPrint("Failed to build param\n");
2170 return LB_STATUS_ERROR_FAULT;
2173 ret = master_rpc_request_only(handler, packet);
2175 if (!handler->common->lb.mouse_event && (handler->common->lb.type == _LB_TYPE_BUFFER || handler->common->lb.type == _LB_TYPE_SCRIPT)) {
2176 int ret; /* Shadow variable */
2177 ret = send_mouse_event(handler, "lb_mouse_down", x * handler->common->lb.width, y * handler->common->lb.height);
2179 ErrPrint("Failed to send Down: %d\n", ret);
2182 ret = send_mouse_event(handler, "lb_mouse_move", x * handler->common->lb.width, y * handler->common->lb.height);
2184 ErrPrint("Failed to send Move: %d\n", ret);
2187 ret = send_mouse_event(handler, "lb_mouse_up", x * handler->common->lb.width, y * handler->common->lb.height);
2189 ErrPrint("Failed to send Up: %d\n", ret);
2196 EAPI int livebox_has_pd(struct livebox *handler)
2198 if (!handler || handler->state != CREATE) {
2199 ErrPrint("Handler is invalid\n");
2200 return LB_STATUS_ERROR_INVALID;
2203 if (!handler->common || handler->common->state != CREATE) {
2204 ErrPrint("Handler is invalid\n");
2205 return LB_STATUS_ERROR_INVALID;
2208 if (!handler->common->id) {
2209 ErrPrint("Handler is not valid\n");
2210 return LB_STATUS_ERROR_INVALID;
2213 return !!handler->common->pd.fb;
2216 EAPI int livebox_pd_is_created(struct livebox *handler)
2218 if (!handler || handler->state != CREATE) {
2219 ErrPrint("Handler is invalid\n");
2220 return LB_STATUS_ERROR_INVALID;
2223 if (!handler->common || handler->common->state != CREATE) {
2224 ErrPrint("Handler is invalid\n");
2225 return LB_STATUS_ERROR_INVALID;
2228 if (!handler->common->pd.fb || !handler->common->id) {
2229 ErrPrint("Handler is not valid\n");
2230 return LB_STATUS_ERROR_INVALID;
2233 return handler->common->is_pd_created;
2236 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
2238 return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
2241 static void turn_off_pd_destroyed_flag_cb(struct livebox *handler, int ret, void *data)
2243 if (handler->common->request.pd_destroyed) {
2247 DbgPrint("pd_destroyed request is canceled\n");
2248 handler->common->request.pd_destroyed = 0;
2249 cb = handler->cbs.pd_destroyed.cb;
2250 data = handler->cbs.pd_destroyed.data;
2251 handler->cbs.pd_destroyed.cb = NULL;
2252 handler->cbs.pd_destroyed.data = NULL;
2255 cb(handler, ret, data);
2260 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
2262 struct packet *packet;
2265 if (!handler || handler->state != CREATE) {
2266 ErrPrint("Handler is invalid\n");
2267 return LB_STATUS_ERROR_INVALID;
2270 if (!handler->common || handler->common->state != CREATE) {
2271 ErrPrint("Handler is invalid\n");
2272 return LB_STATUS_ERROR_INVALID;
2275 if (!handler->common->pd.fb || !handler->common->id) {
2276 ErrPrint("Handler is not valid\n");
2277 return LB_STATUS_ERROR_INVALID;
2282 * Only one handler can have a PD
2284 if (handler->common->is_pd_created) {
2285 DbgPrint("PD is already created\n");
2286 return LB_STATUS_SUCCESS;
2289 if (handler->common->request.pd_created) {
2290 ErrPrint("Previous request is not completed yet\n");
2291 return LB_STATUS_ERROR_BUSY;
2296 * Turn off the pd_destroyed request flag
2298 if (handler->common->request.pd_destroyed) {
2299 if (job_add(handler, turn_off_pd_destroyed_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2300 ErrPrint("Failed to add pd_destroyed job\n");
2304 packet = packet_create("create_pd", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2306 ErrPrint("Failed to build param\n");
2307 return LB_STATUS_ERROR_FAULT;
2311 cb = default_pd_created_cb;
2314 DbgPrint("PERF_DBOX\n");
2315 ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
2316 if (ret == (int)LB_STATUS_SUCCESS) {
2317 handler->cbs.pd_created.cb = cb;
2318 handler->cbs.pd_created.data = data;
2319 handler->common->request.pd_created = 1;
2325 EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
2327 struct packet *packet;
2329 if (!handler || handler->state != CREATE) {
2330 ErrPrint("Handler is invalid\n");
2331 return LB_STATUS_ERROR_INVALID;
2334 if (!handler->common || handler->common->state != CREATE) {
2335 ErrPrint("Handler is invalid\n");
2336 return LB_STATUS_ERROR_INVALID;
2339 if (!handler->common->pd.fb || !handler->common->id) {
2340 ErrPrint("Handler is not valid\n");
2341 return LB_STATUS_ERROR_INVALID;
2344 if (!handler->common->is_pd_created) {
2345 ErrPrint("PD is not created\n");
2346 return LB_STATUS_ERROR_INVALID;
2349 packet = packet_create_noack("pd_move", "ssdd", handler->common->pkgname, handler->common->id, x, y);
2351 ErrPrint("Failed to build param\n");
2352 return LB_STATUS_ERROR_FAULT;
2355 return master_rpc_request_only(handler, packet);
2358 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
2360 struct packet *packet;
2361 struct cb_info *cbinfo;
2365 return LB_STATUS_ERROR_INVALID;
2368 packet = packet_create("activate_package", "s", pkgname);
2370 ErrPrint("Failed to build a param\n");
2371 return LB_STATUS_ERROR_FAULT;
2374 cbinfo = create_cb_info(cb, data);
2376 ErrPrint("Unable to create cbinfo\n");
2377 packet_destroy(packet);
2378 return LB_STATUS_ERROR_FAULT;
2381 ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo);
2383 destroy_cb_info(cbinfo);
2389 static void turn_off_pd_created_flag_cb(struct livebox *handler, int ret, void *data)
2391 if (handler->common->request.pd_created) {
2395 DbgPrint("pd_created request is canceled\n");
2396 handler->common->request.pd_created = 0;
2397 cb = handler->cbs.pd_created.cb;
2398 data = handler->cbs.pd_created.data;
2399 handler->cbs.pd_created.cb = NULL;
2400 handler->cbs.pd_created.data = NULL;
2403 cb(handler, ret, data);
2408 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
2410 struct packet *packet;
2411 struct cb_info *cbinfo;
2414 if (!handler || handler->state != CREATE) {
2415 ErrPrint("Handler is invalid\n");
2416 return LB_STATUS_ERROR_INVALID;
2419 if (!handler->common || handler->common->state != CREATE) {
2420 ErrPrint("Handler is invalid\n");
2421 return LB_STATUS_ERROR_INVALID;
2424 if (!handler->common->pd.fb || !handler->common->id) {
2425 ErrPrint("Handler is not valid\n");
2426 return LB_STATUS_ERROR_INVALID;
2431 * Replace the callback check code.
2432 * Use the flag instead of callback.
2433 * the flag should be in the ADT "common"
2435 if (!handler->common->is_pd_created && !handler->common->request.pd_created) {
2436 ErrPrint("PD is not created\n");
2437 return LB_STATUS_ERROR_INVALID;
2440 if (handler->common->request.pd_destroyed) {
2441 ErrPrint("PD destroy request is already sent\n");
2442 return LB_STATUS_ERROR_ALREADY;
2447 * Disable the pd_created request flag
2449 if (handler->common->request.pd_created) {
2450 if (job_add(handler, turn_off_pd_created_flag_cb, LB_STATUS_ERROR_CANCEL, NULL) < 0) {
2451 ErrPrint("Failed to add a new job\n");
2455 DbgPrint("[%s]\n", handler->common->pkgname);
2457 packet = packet_create("destroy_pd", "ss", handler->common->pkgname, handler->common->id);
2459 ErrPrint("Failed to build a param\n");
2460 return LB_STATUS_ERROR_FAULT;
2464 cb = default_pd_destroyed_cb;
2467 cbinfo = create_cb_info(cb, data);
2469 packet_destroy(packet);
2470 return LB_STATUS_ERROR_FAULT;
2473 ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo);
2475 destroy_cb_info(cbinfo);
2477 handler->common->request.pd_destroyed = 1;
2483 EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data)
2487 char cmd[32] = { '\0', };
2491 if (!handler || handler->state != CREATE) {
2492 ErrPrint("Handler is invalid\n");
2493 return LB_STATUS_ERROR_INVALID;
2496 if (!handler->common || handler->common->state != CREATE) {
2497 ErrPrint("Handler is invalid\n");
2498 return LB_STATUS_ERROR_INVALID;
2501 if (!handler->common->id) {
2502 ErrPrint("Handler is not valid\n");
2503 return LB_STATUS_ERROR_INVALID;
2506 if (handler->common->request.access_event) {
2507 ErrPrint("Previous access event is not yet done\n");
2508 return LB_STATUS_ERROR_BUSY;
2511 if (type & ACCESS_EVENT_PD_MASK) {
2512 if (!handler->common->is_pd_created) {
2513 ErrPrint("PD is not created\n");
2514 return LB_STATUS_ERROR_INVALID;
2518 w = handler->common->pd.width;
2519 h = handler->common->pd.height;
2520 } else if (type & ACCESS_EVENT_LB_MASK) {
2523 w = handler->common->lb.width;
2524 h = handler->common->lb.height;
2526 ErrPrint("Invalid event type\n");
2527 return LB_STATUS_ERROR_INVALID;
2530 switch (type & ~ACCESS_EVENT_PD_MASK) {
2531 case ACCESS_EVENT_HIGHLIGHT:
2532 strcpy(ptr, "_access_hl");
2534 case ACCESS_EVENT_HIGHLIGHT_NEXT:
2535 strcpy(ptr, "_access_hl_next");
2537 case ACCESS_EVENT_HIGHLIGHT_PREV:
2538 strcpy(ptr, "_access_hl_prev");
2540 case ACCESS_EVENT_ACTIVATE:
2541 strcpy(ptr, "_access_activate");
2543 case ACCESS_EVENT_ACTION_DOWN:
2544 strcpy(ptr, "_access_action_down");
2546 case ACCESS_EVENT_ACTION_UP:
2547 strcpy(ptr, "_access_action_up");
2549 case ACCESS_EVENT_UNHIGHLIGHT:
2550 strcpy(ptr, "_access_unhighlight");
2552 case ACCESS_EVENT_SCROLL_DOWN:
2553 strcpy(ptr, "_access_scroll_down");
2555 case ACCESS_EVENT_SCROLL_MOVE:
2556 strcpy(ptr, "_access_scroll_move");
2558 case ACCESS_EVENT_SCROLL_UP:
2559 strcpy(ptr, "_access_scroll_up");
2562 return LB_STATUS_ERROR_INVALID;
2566 cb = default_access_event_cb;
2569 ret = send_access_event(handler, cmd, x * w, y * h);
2570 if (ret == (int)LB_STATUS_SUCCESS) {
2571 handler->cbs.access_event.cb = cb;
2572 handler->cbs.access_event.data = data;
2573 handler->common->request.access_event = 1;
2579 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
2581 return livebox_mouse_event(handler, type, x, y);
2584 EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y)
2588 char cmd[32] = { '\0', };
2591 if (!handler || handler->state != CREATE) {
2592 ErrPrint("Handler is invalid\n");
2593 return LB_STATUS_ERROR_INVALID;
2596 if (!handler->common || handler->common->state != CREATE) {
2597 ErrPrint("Handler is invalid\n");
2598 return LB_STATUS_ERROR_INVALID;
2601 if (!handler->common->id) {
2602 ErrPrint("Handler is not valid\n");
2603 return LB_STATUS_ERROR_INVALID;
2606 if (!(type & CONTENT_EVENT_MOUSE_MASK)) {
2607 ErrPrint("Invalid content event is used\n");
2608 return LB_STATUS_ERROR_INVALID;
2611 if (type & CONTENT_EVENT_PD_MASK) {
2614 if (!handler->common->is_pd_created) {
2615 ErrPrint("PD is not created\n");
2616 return LB_STATUS_ERROR_INVALID;
2619 if (!handler->common->pd.fb) {
2620 ErrPrint("Handler is not valid\n");
2621 return LB_STATUS_ERROR_INVALID;
2624 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2625 if (fabs(x - handler->common->pd.x) < conf_event_filter() && fabs(y - handler->common->pd.y) < conf_event_filter()) {
2626 return LB_STATUS_ERROR_BUSY;
2628 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2633 w = handler->common->pd.width;
2634 h = handler->common->pd.height;
2635 handler->common->pd.x = x;
2636 handler->common->pd.y = y;
2640 } else if (type & CONTENT_EVENT_LB_MASK) {
2643 if (!handler->common->lb.mouse_event) {
2644 return LB_STATUS_ERROR_INVALID;
2647 if (!handler->common->lb.fb) {
2648 ErrPrint("Handler is not valid\n");
2649 return LB_STATUS_ERROR_INVALID;
2652 if (type & CONTENT_EVENT_MOUSE_MOVE) {
2653 if (fabs(x - handler->common->lb.x) < conf_event_filter() && fabs(y - handler->common->lb.y) < conf_event_filter()) {
2654 return LB_STATUS_ERROR_BUSY;
2656 } else if (type & CONTENT_EVENT_MOUSE_SET) {
2661 w = handler->common->lb.width;
2662 h = handler->common->lb.height;
2663 handler->common->lb.x = x;
2664 handler->common->lb.y = y;
2669 ErrPrint("Invalid event type\n");
2670 return LB_STATUS_ERROR_INVALID;
2674 * Must be shorter than 29 bytes.
2676 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2677 case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
2678 strcpy(ptr, "_mouse_enter");
2680 case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
2681 strcpy(ptr, "_mouse_leave");
2683 case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
2684 strcpy(ptr, "_mouse_up");
2686 case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
2687 strcpy(ptr, "_mouse_down");
2689 case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
2690 strcpy(ptr, "_mouse_move");
2692 case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
2693 strcpy(ptr, "_mouse_set");
2695 case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
2696 strcpy(ptr, "_mouse_unset");
2698 case CONTENT_EVENT_ON_SCROLL | CONTENT_EVENT_MOUSE_MASK:
2699 strcpy(ptr, "_mouse_on_scroll");
2701 case CONTENT_EVENT_ON_HOLD | CONTENT_EVENT_MOUSE_MASK:
2702 strcpy(ptr, "_mouse_on_hold");
2704 case CONTENT_EVENT_OFF_SCROLL | CONTENT_EVENT_MOUSE_MASK:
2705 strcpy(ptr, "_mouse_off_scroll");
2707 case CONTENT_EVENT_OFF_HOLD | CONTENT_EVENT_MOUSE_MASK:
2708 strcpy(ptr, "_mouse_off_hold");
2711 ErrPrint("Invalid event type\n");
2712 return LB_STATUS_ERROR_INVALID;
2715 return send_mouse_event(handler, cmd, x * w, y * h);
2718 EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data)
2720 char cmd[32] = { '\0', };
2724 if (!handler || handler->state != CREATE) {
2725 ErrPrint("Handler is invalid\n");
2726 return LB_STATUS_ERROR_INVALID;
2729 if (!handler->common || handler->common->state != CREATE) {
2730 ErrPrint("Handler is invalid\n");
2731 return LB_STATUS_ERROR_INVALID;
2734 if (!handler->common->id) {
2735 ErrPrint("Handler is not valid\n");
2736 return LB_STATUS_ERROR_INVALID;
2739 if (!(type & CONTENT_EVENT_KEY_MASK)) {
2740 ErrPrint("Invalid key event is used\n");
2741 return LB_STATUS_ERROR_INVALID;
2744 if (handler->common->request.key_event) {
2745 ErrPrint("Previous key event is not completed yet\n");
2746 return LB_STATUS_ERROR_BUSY;
2749 if (type & CONTENT_EVENT_PD_MASK) {
2750 if (!handler->common->is_pd_created) {
2751 ErrPrint("PD is not created\n");
2752 return LB_STATUS_ERROR_INVALID;
2755 if (!handler->common->pd.fb) {
2756 ErrPrint("Handler is not valid\n");
2757 return LB_STATUS_ERROR_INVALID;
2760 if (type & CONTENT_EVENT_KEY_DOWN) {
2763 * filtering the reproduced events if it is too fast
2765 } else if (type & CONTENT_EVENT_KEY_SET) {
2768 * What can I do for this case?
2774 } else if (type & CONTENT_EVENT_LB_MASK) {
2775 if (!handler->common->lb.mouse_event) {
2776 return LB_STATUS_ERROR_INVALID;
2779 if (!handler->common->lb.fb) {
2780 ErrPrint("Handler is not valid\n");
2781 return LB_STATUS_ERROR_INVALID;
2784 if (type & CONTENT_EVENT_KEY_DOWN) {
2787 * filtering the reproduced events if it is too fast
2789 } else if (type & CONTENT_EVENT_KEY_SET) {
2791 * What can I do for this case?
2798 ErrPrint("Invalid event type\n");
2799 return LB_STATUS_ERROR_INVALID;
2803 * Must be short than 29 bytes.
2805 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2806 case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK:
2807 strcpy(ptr, "_key_focus_in");
2809 case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK:
2810 strcpy(ptr, "_key_focus_out");
2812 case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
2813 strcpy(ptr, "_key_up");
2815 case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
2816 strcpy(ptr, "_key_down");
2818 case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK:
2819 strcpy(ptr, "_key_set");
2821 case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK:
2822 strcpy(ptr, "_key_unset");
2825 ErrPrint("Invalid event type\n");
2826 return LB_STATUS_ERROR_INVALID;
2830 cb = default_key_event_cb;
2833 ret = send_key_event(handler, cmd, keycode);
2834 if (ret == (int)LB_STATUS_SUCCESS) {
2835 handler->cbs.key_event.cb = cb;
2836 handler->cbs.key_event.data = data;
2837 handler->common->request.key_event = 1;
2843 EAPI const char *livebox_filename(struct livebox *handler)
2845 if (!handler || handler->state != CREATE) {
2846 ErrPrint("Handler is invalid\n");
2850 if (!handler->common || handler->common->state != CREATE) {
2851 ErrPrint("Handler is invalid\n");
2855 if (!handler->common->id) {
2856 ErrPrint("Handler is not valid\n");
2860 if (handler->common->filename) {
2861 return handler->common->filename;
2865 return util_uri_to_path(handler->common->id);
2868 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
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;
2895 if (!handler->common->is_pd_created) {
2896 *w = handler->common->pd.default_width;
2897 *h = handler->common->pd.default_height;
2899 *w = handler->common->pd.width;
2900 *h = handler->common->pd.height;
2903 return LB_STATUS_SUCCESS;
2906 EAPI int livebox_size(struct livebox *handler)
2911 if (!handler || handler->state != CREATE) {
2912 ErrPrint("Handler is invalid\n");
2913 return LB_STATUS_ERROR_INVALID;
2916 if (!handler->common || handler->common->state != CREATE) {
2917 ErrPrint("Handler is invalid\n");
2918 return LB_STATUS_ERROR_INVALID;
2921 if (!handler->common->id) {
2922 ErrPrint("Handler is not valid\n");
2923 return LB_STATUS_ERROR_INVALID;
2926 w = handler->common->lb.width;
2927 h = handler->common->lb.height;
2929 switch (handler->common->lb.type) {
2930 case _LB_TYPE_BUFFER:
2931 case _LB_TYPE_SCRIPT:
2932 if (!fb_is_created(handler->common->lb.fb)) {
2941 return livebox_service_size_type(w, h);
2944 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
2946 struct packet *packet;
2950 ErrPrint("Handler is NIL\n");
2951 return LB_STATUS_ERROR_INVALID;
2954 if (!cluster || !category || handler->state != CREATE) {
2955 ErrPrint("Invalid argument\n");
2956 return LB_STATUS_ERROR_INVALID;
2959 if (!handler->common || handler->common->state != CREATE) {
2960 ErrPrint("Invalid argument\n");
2961 return LB_STATUS_ERROR_INVALID;
2964 if (!handler->common->id) {
2965 ErrPrint("Invalid argument\n");
2966 return LB_STATUS_ERROR_INVALID;
2969 if (handler->common->request.group_changed) {
2970 ErrPrint("Previous group changing request is not finished yet\n");
2971 return LB_STATUS_ERROR_BUSY;
2974 if (!handler->common->is_user) {
2975 ErrPrint("CA Livebox is not able to change the group\n");
2976 return LB_STATUS_ERROR_PERMISSION;
2979 if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) {
2980 DbgPrint("No changes\n");
2981 return LB_STATUS_ERROR_ALREADY;
2984 packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category);
2986 ErrPrint("Failed to build a param\n");
2987 return LB_STATUS_ERROR_FAULT;
2991 cb = default_group_changed_cb;
2994 ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
2995 if (ret == (int)LB_STATUS_SUCCESS) {
2996 handler->cbs.group_changed.cb = cb;
2997 handler->cbs.group_changed.data = data;
2998 handler->common->request.group_changed = 1;
3004 EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category)
3007 ErrPrint("Handler is NIL\n");
3008 return LB_STATUS_ERROR_INVALID;
3011 if (!cluster || !category || handler->state != CREATE) {
3012 ErrPrint("Invalid argument\n");
3013 return LB_STATUS_ERROR_INVALID;
3016 if (!handler->common || handler->common->state != CREATE) {
3017 ErrPrint("Invalid argument\n");
3018 return LB_STATUS_ERROR_INVALID;
3021 if (!handler->common->id) {
3022 ErrPrint("Invalid argument\n");
3023 return LB_STATUS_ERROR_INVALID;
3026 *cluster = handler->common->cluster;
3027 *category = handler->common->category;
3028 return LB_STATUS_SUCCESS;
3031 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
3036 if (!handler || !size_list) {
3037 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
3038 return LB_STATUS_ERROR_INVALID;
3041 if (!cnt || handler->state != CREATE) {
3042 ErrPrint("Handler is not valid\n");
3043 return LB_STATUS_ERROR_INVALID;
3046 if (!handler->common || handler->common->state != CREATE) {
3047 ErrPrint("Handler is not valid\n");
3048 return LB_STATUS_ERROR_INVALID;
3051 if (!handler->common->id) {
3052 ErrPrint("Handler is not valid\n");
3053 return LB_STATUS_ERROR_INVALID;
3056 for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
3057 if (handler->common->lb.size_list & (0x01 << i)) {
3062 size_list[j++] = (0x01 << i);
3067 return LB_STATUS_SUCCESS;
3070 EAPI const char *livebox_pkgname(struct livebox *handler)
3073 ErrPrint("Handler is NIL\n");
3077 if (handler->state != CREATE) {
3078 ErrPrint("Handler is not valid\n");
3082 if (!handler->common || handler->common->state != CREATE) {
3083 ErrPrint("Handler is not valid\n");
3087 return handler->common->pkgname;
3090 EAPI double livebox_priority(struct livebox *handler)
3092 if (!handler || handler->state != CREATE) {
3093 ErrPrint("Handler is invalid\n");
3097 if (!handler->common || handler->common->state != CREATE) {
3098 ErrPrint("Handler is invalid\n");
3102 if (!handler->common->id) {
3103 ErrPrint("Handler is not valid (%p)\n", handler);
3107 return handler->common->lb.priority;
3110 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
3112 struct packet *packet;
3113 struct cb_info *cbinfo;
3116 packet = packet_create("delete_cluster", "s", cluster);
3118 ErrPrint("Failed to build a param\n");
3119 return LB_STATUS_ERROR_FAULT;
3122 cbinfo = create_cb_info(cb, data);
3124 packet_destroy(packet);
3125 return LB_STATUS_ERROR_FAULT;
3128 ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
3130 destroy_cb_info(cbinfo);
3136 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
3138 struct packet *packet;
3139 struct cb_info *cbinfo;
3142 packet = packet_create("delete_category", "ss", cluster, category);
3144 ErrPrint("Failed to build a param\n");
3145 return LB_STATUS_ERROR_FAULT;
3148 cbinfo = create_cb_info(cb, data);
3150 packet_destroy(packet);
3151 return LB_STATUS_ERROR_FAULT;
3154 ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
3156 destroy_cb_info(cbinfo);
3162 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
3164 if (!handler || handler->state != CREATE) {
3165 ErrPrint("Handler is invalid\n");
3166 return LB_TYPE_INVALID;
3169 if (!handler->common || handler->common->state != CREATE) {
3170 ErrPrint("Handler is invalid\n");
3171 return LB_TYPE_INVALID;
3174 if (!handler->common->id) {
3175 ErrPrint("Handler is not valid\n");
3176 return LB_TYPE_INVALID;
3179 switch (handler->common->lb.type) {
3181 return LB_TYPE_IMAGE;
3182 case _LB_TYPE_BUFFER:
3183 case _LB_TYPE_SCRIPT:
3186 id = fb_id(handler->common->lb.fb);
3187 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3188 return LB_TYPE_PIXMAP;
3191 return LB_TYPE_BUFFER;
3193 return LB_TYPE_TEXT;
3198 return LB_TYPE_INVALID;
3201 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
3203 if (!handler || handler->state != CREATE) {
3204 ErrPrint("Handler is invalid\n");
3205 return PD_TYPE_INVALID;
3208 if (!handler->common || handler->common->state != CREATE) {
3209 ErrPrint("Handler is invalid\n");
3210 return PD_TYPE_INVALID;
3213 if (!handler->common->id) {
3214 ErrPrint("Handler is not valid\n");
3215 return PD_TYPE_INVALID;
3218 switch (handler->common->pd.type) {
3220 return PD_TYPE_TEXT;
3221 case _PD_TYPE_BUFFER:
3222 case _PD_TYPE_SCRIPT:
3225 id = fb_id(handler->common->pd.fb);
3226 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3227 return PD_TYPE_PIXMAP;
3230 return PD_TYPE_BUFFER;
3235 return PD_TYPE_INVALID;
3238 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3241 ErrPrint("Handler is NIL\n");
3242 return LB_STATUS_ERROR_INVALID;
3245 if (handler->state != CREATE) {
3246 ErrPrint("Handler is not valid\n");
3247 return LB_STATUS_ERROR_INVALID;
3250 memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops));
3251 return LB_STATUS_SUCCESS;
3254 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3257 ErrPrint("Handler is NIL\n");
3258 return LB_STATUS_ERROR_INVALID;
3261 if (handler->state != CREATE) {
3262 ErrPrint("Handler is not valid\n");
3263 return LB_STATUS_ERROR_INVALID;
3266 memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops));
3267 return LB_STATUS_SUCCESS;
3270 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3272 if (!handler || handler->state != CREATE) {
3273 ErrPrint("Handler is invalid\n");
3274 return LB_STATUS_ERROR_INVALID;
3277 if (!handler->common || handler->common->state != CREATE) {
3278 ErrPrint("Handler is invalid\n");
3279 return LB_STATUS_ERROR_INVALID;
3282 if (!handler->common->id) {
3283 ErrPrint("Invalid handle\n");
3284 return LB_STATUS_ERROR_INVALID;
3287 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3288 ErrPrint("Handler is not valid type\n");
3289 return LB_STATUS_ERROR_INVALID;
3292 return lb_acquire_lb_pixmap(handler, cb, data);
3297 * Do not check the state of handler and common-handler.
3298 * If this function is used in the deleted callback,
3299 * the handler and common-handler's state would be DELETE
3300 * if this function check the state of handles,
3301 * user cannot release the pixmap.
3303 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
3305 struct packet *packet;
3306 const char *pkgname;
3309 if (pixmap == 0 /* || handler->state != CREATE */ ) {
3310 ErrPrint("Handler is invalid [%d]\n", pixmap);
3311 return LB_STATUS_ERROR_INVALID;
3317 * Even though the handler is NULL, we should send the release request to the master.
3318 * Because the pixmap resource can be released after the handler is destroyed.
3319 * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3320 * In some cases, the pixmap can be released after the handler is deleted.
3322 * Its implementation is up to the viewer app.
3323 * But we cannot force it to use only with valid handler.
3325 DbgPrint("Using NULL handler\n");
3330 * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3333 if (!handler->common /* || handler->common->state != CREATE */) {
3334 ErrPrint("Handler is invalid\n");
3335 return LB_STATUS_ERROR_INVALID;
3338 if (!handler->common->id) {
3339 ErrPrint("Invalid handle\n");
3340 return LB_STATUS_ERROR_INVALID;
3343 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3344 ErrPrint("Handler is not valid type\n");
3345 return LB_STATUS_ERROR_INVALID;
3348 pkgname = handler->common->pkgname;
3349 id = handler->common->id;
3352 packet = packet_create_noack("lb_release_pixmap", "ssi", pkgname, id, pixmap);
3354 ErrPrint("Failed to build a param\n");
3355 return LB_STATUS_ERROR_INVALID;
3358 return master_rpc_request_only(handler, packet);
3361 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3363 if (!handler || handler->state != CREATE) {
3364 ErrPrint("Handler is invalid\n");
3365 return LB_STATUS_ERROR_INVALID;
3368 if (!handler->common || handler->common->state != CREATE) {
3369 ErrPrint("Handler is invalid\n");
3370 return LB_STATUS_ERROR_INVALID;
3373 if (!handler->common->id) {
3374 ErrPrint("Invalid handle\n");
3375 return LB_STATUS_ERROR_INVALID;
3378 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3379 ErrPrint("Handler is not valid type\n");
3380 return LB_STATUS_ERROR_INVALID;
3383 return lb_acquire_pd_pixmap(handler, cb, data);
3386 EAPI int livebox_pd_pixmap(const struct livebox *handler)
3391 if (!handler || handler->state != CREATE) {
3392 ErrPrint("Handler is invalid\n");
3396 if (!handler->common || handler->common->state != CREATE) {
3397 ErrPrint("Handler is invalid\n");
3401 if (!handler->common->id) {
3402 ErrPrint("Invalid handler\n");
3406 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3407 ErrPrint("Invalid handler\n");
3411 id = fb_id(handler->common->pd.fb);
3412 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3413 ErrPrint("PIXMAP Id is not valid\n");
3420 EAPI int livebox_lb_pixmap(const struct livebox *handler)
3425 if (!handler || handler->state != CREATE) {
3426 ErrPrint("Handler is invalid\n");
3430 if (!handler->common || handler->common->state != CREATE) {
3431 ErrPrint("Handler is invalid\n");
3435 if (!handler->common->id) {
3436 ErrPrint("Invalid handler\n");
3440 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3441 ErrPrint("Invalid handler\n");
3445 id = fb_id(handler->common->lb.fb);
3446 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3447 ErrPrint("PIXMAP Id is not valid\n");
3456 * Do not check the state of handler and common-handler.
3457 * If this function is used in the deleted callback,
3458 * the handler and common-handler's state would be DELETE
3459 * if this function check the state of handles,
3460 * user cannot release the pixmap.
3462 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
3464 struct packet *packet;
3465 const char *pkgname;
3468 if (pixmap == 0 /* || handler->state != CREATE */) {
3469 ErrPrint("Pixmap is invalid [%d]\n", pixmap);
3470 return LB_STATUS_ERROR_INVALID;
3476 * Even though the handler is NULL, we should send the release request to the master.
3477 * Because the pixmap resource can be released after the handler is destroyed.
3478 * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3479 * In some cases, the pixmap can be released after the handler is deleted.
3481 * Its implementation is up to the viewer app.
3482 * But we cannot force it to use only with valid handler.
3484 DbgPrint("Using NULL handler\n");
3489 * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3492 if (!handler->common /* || handler-common->state != CREATE */) {
3493 ErrPrint("Handler is invalid\n");
3494 return LB_STATUS_ERROR_INVALID;
3497 if (!handler->common->id) {
3498 ErrPrint("Invalid handle\n");
3499 return LB_STATUS_ERROR_INVALID;
3502 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3503 ErrPrint("Handler is not valid type\n");
3504 return LB_STATUS_ERROR_INVALID;
3507 pkgname = handler->common->pkgname;
3508 id = handler->common->id;
3511 packet = packet_create_noack("pd_release_pixmap", "ssi", pkgname, id, pixmap);
3513 ErrPrint("Failed to build a param\n");
3514 return LB_STATUS_ERROR_FAULT;
3517 return master_rpc_request_only(handler, packet);
3520 EAPI void *livebox_acquire_fb(struct livebox *handler)
3522 if (!handler || handler->state != CREATE) {
3523 ErrPrint("Handler is invalid\n");
3527 if (!handler->common || handler->common->state != CREATE) {
3528 ErrPrint("Handler is invalid\n");
3532 if (!handler->common->id) {
3533 ErrPrint("Invalid handle\n");
3537 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3538 ErrPrint("Handler is not valid type\n");
3542 return fb_acquire_buffer(handler->common->lb.fb);
3545 EAPI int livebox_release_fb(void *buffer)
3547 return fb_release_buffer(buffer);
3550 EAPI int livebox_fb_refcnt(void *buffer)
3552 return fb_refcnt(buffer);
3555 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
3557 if (!handler || handler->state != CREATE) {
3558 ErrPrint("Handler is invalid\n");
3562 if (!handler->common || handler->common->state != CREATE) {
3563 ErrPrint("Handler is invalid\n");
3567 if (!handler->common->id) {
3568 ErrPrint("Invalid handler\n");
3572 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3573 ErrPrint("Handler is not valid type\n");
3577 return fb_acquire_buffer(handler->common->pd.fb);
3580 EAPI int livebox_release_pdfb(void *buffer)
3582 return fb_release_buffer(buffer);
3585 EAPI int livebox_pdfb_refcnt(void *buffer)
3587 return fb_refcnt(buffer);
3590 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
3592 if (!handler || handler->state != CREATE) {
3593 ErrPrint("Handler is invalid\n");
3594 return LB_STATUS_ERROR_INVALID;
3597 if (!handler->common || handler->common->state != CREATE) {
3598 ErrPrint("Handler is invalid\n");
3599 return LB_STATUS_ERROR_INVALID;
3602 if (!handler->common->id) {
3603 ErrPrint("Invalid handler\n");
3604 return LB_STATUS_ERROR_INVALID;
3607 return fb_size(handler->common->pd.fb);
3610 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
3612 if (!handler || handler->state != CREATE) {
3613 ErrPrint("Handler is invalid\n");
3614 return LB_STATUS_ERROR_INVALID;
3617 if (!handler->common || handler->common->state != CREATE) {
3618 ErrPrint("Handler is invalid\n");
3619 return LB_STATUS_ERROR_INVALID;
3622 if (!handler->common->id) {
3623 ErrPrint("Invalid handler\n");
3624 return LB_STATUS_ERROR_INVALID;
3627 return fb_size(handler->common->lb.fb);
3630 EAPI int livebox_is_user(struct livebox *handler)
3632 if (!handler || handler->state != CREATE) {
3633 ErrPrint("Handler is invalid\n");
3634 return LB_STATUS_ERROR_INVALID;
3637 if (!handler->common || handler->common->state != CREATE) {
3638 ErrPrint("Handler is invalid\n");
3639 return LB_STATUS_ERROR_INVALID;
3642 if (!handler->common->id) {
3643 ErrPrint("Invalid handler\n");
3644 return LB_STATUS_ERROR_INVALID;
3647 return handler->common->is_user;
3650 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
3652 struct packet *packet;
3655 if (!handler || handler->state != CREATE) {
3656 ErrPrint("Handler is invalid\n");
3657 return LB_STATUS_ERROR_INVALID;
3660 if (!handler->common || handler->common->state != CREATE) {
3661 ErrPrint("Handler is invalid\n");
3662 return LB_STATUS_ERROR_INVALID;
3665 if (!handler->common->id) {
3666 ErrPrint("Invalid handler\n");
3667 return LB_STATUS_ERROR_INVALID;
3670 if (handler->common->request.pinup) {
3671 ErrPrint("Previous pinup request is not finished\n");
3672 return LB_STATUS_ERROR_BUSY;
3675 if (handler->common->is_pinned_up == flag) {
3676 DbgPrint("No changes\n");
3677 return LB_STATUS_ERROR_ALREADY;
3680 packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
3682 ErrPrint("Failed to build a param\n");
3683 return LB_STATUS_ERROR_FAULT;
3687 cb = default_pinup_cb;
3690 ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
3691 if (ret == (int)LB_STATUS_SUCCESS) {
3692 handler->cbs.pinup.cb = cb;
3693 handler->cbs.pinup.data = data;
3694 handler->common->request.pinup = 1;
3700 EAPI int livebox_is_pinned_up(struct livebox *handler)
3702 if (!handler || handler->state != CREATE) {
3703 ErrPrint("Handler is invalid\n");
3704 return LB_STATUS_ERROR_INVALID;
3707 if (!handler->common || handler->common->state != CREATE) {
3708 ErrPrint("Handler is invalid\n");
3709 return LB_STATUS_ERROR_INVALID;
3712 if (!handler->common->id) {
3713 ErrPrint("Invalid handler\n");
3714 return LB_STATUS_ERROR_INVALID;
3717 return handler->common->is_pinned_up;
3720 EAPI int livebox_has_pinup(struct livebox *handler)
3722 if (!handler || handler->state != CREATE) {
3723 ErrPrint("Handler is invalid\n");
3724 return LB_STATUS_ERROR_INVALID;
3727 if (!handler->common || handler->common->state != CREATE) {
3728 ErrPrint("Handler is invalid\n");
3729 return LB_STATUS_ERROR_INVALID;
3732 if (!handler->common->id) {
3733 ErrPrint("Invalid handler\n");
3734 return LB_STATUS_ERROR_INVALID;
3737 return handler->common->lb.pinup_supported;
3740 EAPI int livebox_set_data(struct livebox *handler, void *data)
3743 ErrPrint("Handler is NIL\n");
3744 return LB_STATUS_ERROR_INVALID;
3747 if (handler->state != CREATE) {
3748 ErrPrint("Handler is invalid\n");
3749 return LB_STATUS_ERROR_INVALID;
3752 handler->data = data;
3753 return LB_STATUS_SUCCESS;
3756 EAPI void *livebox_get_data(struct livebox *handler)
3759 ErrPrint("Handler is NIL\n");
3763 if (handler->state != CREATE) {
3764 ErrPrint("Handler is invalid\n");
3768 return handler->data;
3771 EAPI int livebox_is_exists(const char *pkgname)
3775 lb = lb_pkgname(pkgname);
3784 EAPI const char *livebox_content(struct livebox *handler)
3786 if (!handler || handler->state != CREATE) {
3787 ErrPrint("Handler is invalid\n");
3791 if (!handler->common || handler->common->state != CREATE) {
3792 ErrPrint("Invalid handle\n");
3796 return handler->common->content;
3799 EAPI const char *livebox_category_title(struct livebox *handler)
3801 if (!handler || handler->state != CREATE) {
3802 ErrPrint("Handler is invalid\n");
3806 if (!handler->common || handler->common->state != CREATE) {
3807 ErrPrint("Invalid handle\n");
3811 return handler->common->title;
3814 EAPI int livebox_emit_text_signal(struct livebox *handler, const char *emission, const char *source, double sx, double sy, double ex, double ey, ret_cb_t cb, void *data)
3816 struct packet *packet;
3817 struct cb_info *cbinfo;
3820 if (!handler || handler->state != CREATE) {
3821 ErrPrint("Handler is invalid\n");
3822 return LB_STATUS_ERROR_INVALID;
3825 if (!handler->common || handler->common->state != CREATE) {
3826 ErrPrint("Handler is invalid\n");
3827 return LB_STATUS_ERROR_INVALID;
3830 if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
3831 ErrPrint("Handler is not valid\n");
3832 return LB_STATUS_ERROR_INVALID;
3843 packet = packet_create("text_signal", "ssssdddd",
3844 handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
3846 ErrPrint("Failed to build a param\n");
3847 return LB_STATUS_ERROR_FAULT;
3850 cbinfo = create_cb_info(cb, data);
3852 packet_destroy(packet);
3853 return LB_STATUS_ERROR_FAULT;
3856 ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
3858 destroy_cb_info(cbinfo);
3864 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
3866 struct packet *packet;
3870 * Validate the group info using DB
3871 * If the group info is not valid, do not send this request
3874 packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
3876 ErrPrint("Failed to create a packet\n");
3877 return LB_STATUS_ERROR_FAULT;
3880 return master_rpc_request_only(NULL, packet);
3883 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
3885 struct packet *packet;
3889 * Validate the group info using DB
3890 * If the group info is not valid, do not send this request
3891 * AND Check the subscribed or not too
3894 packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
3896 ErrPrint("Failed to create a packet\n");
3897 return LB_STATUS_ERROR_FAULT;
3900 return master_rpc_request_only(NULL, packet);
3903 EAPI int livebox_refresh(struct livebox *handler, int force)
3905 struct packet *packet;
3907 if (!handler || handler->state != CREATE) {
3908 ErrPrint("Handler is invalid\n");
3909 return LB_STATUS_ERROR_INVALID;
3912 if (!handler->common || handler->common->state != CREATE) {
3913 ErrPrint("Handler is not valid\n");
3914 return LB_STATUS_ERROR_INVALID;
3917 if (!handler->common->id) {
3918 ErrPrint("Handler is not valid\n");
3919 return LB_STATUS_ERROR_INVALID;
3922 packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
3924 ErrPrint("Failed to create a packet\n");
3925 return LB_STATUS_ERROR_FAULT;
3928 return master_rpc_request_only(handler, packet);
3931 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
3933 struct packet *packet;
3935 if (!cluster || !category) {
3936 ErrPrint("Invalid argument\n");
3937 return LB_STATUS_ERROR_INVALID;
3940 packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
3942 ErrPrint("Failed to create a packet\n");
3943 return LB_STATUS_ERROR_FAULT;
3946 return master_rpc_request_only(NULL, packet);
3949 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
3954 if (!handler || handler->state != CREATE) {
3955 ErrPrint("Handler is invalid\n");
3956 return LB_STATUS_ERROR_INVALID;
3959 if (!handler->common || handler->common->state != CREATE) {
3960 ErrPrint("Handler is not valid\n");
3961 return LB_STATUS_ERROR_INVALID;
3964 if (!handler->common->id) {
3965 ErrPrint("Handler is not valid\n");
3966 return LB_STATUS_ERROR_INVALID;
3969 if (!handler->common->is_user) {
3970 /* System cluster livebox cannot be changed its visible states */
3971 if (state == LB_HIDE_WITH_PAUSE) {
3972 ErrPrint("CA Livebox is not able to change the visibility\n");
3973 return LB_STATUS_ERROR_PERMISSION;
3977 if (handler->visible == state) {
3978 DbgPrint("%s has no changes\n", handler->common->pkgname);
3979 return LB_STATUS_ERROR_ALREADY;
3982 old_state = handler->visible;
3983 handler->visible = state;
3985 ret = lb_set_visibility(handler, state);
3987 handler->visible = old_state;
3993 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
3995 if (!handler || handler->state != CREATE) {
3996 ErrPrint("Handler is invalid\n");
3997 return LB_VISIBLE_ERROR;
4000 if (!handler->common || handler->common->state != CREATE) {
4001 ErrPrint("Handler is not valid\n");
4002 return LB_VISIBLE_ERROR;
4005 if (!handler->common->id) {
4006 ErrPrint("Handler is not valid\n");
4007 return LB_VISIBLE_ERROR;
4010 return handler->visible;
4013 int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
4019 pc = strdup(cluster);
4021 ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
4022 return LB_STATUS_ERROR_MEMORY;
4027 ps = strdup(category);
4029 ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
4031 return LB_STATUS_ERROR_MEMORY;
4035 if (common->cluster) {
4036 free(common->cluster);
4039 if (common->category) {
4040 free(common->category);
4043 common->cluster = pc;
4044 common->category = ps;
4046 return LB_STATUS_SUCCESS;
4049 void lb_set_size(struct livebox_common *common, int w, int h)
4053 common->lb.width = w;
4054 common->lb.height = h;
4056 size_type = livebox_service_size_type(w, h);
4057 if (size_type != LB_SIZE_TYPE_UNKNOWN) {
4058 common->lb.mouse_event = livebox_service_mouse_event(common->pkgname, size_type);
4062 void lb_set_update_mode(struct livebox_common *common, int active_mode)
4064 common->is_active_update = active_mode;
4067 void lb_set_pdsize(struct livebox_common *common, int w, int h)
4069 common->pd.width = w;
4070 common->pd.height = h;
4073 void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
4075 common->pd.default_width = w;
4076 common->pd.default_height = h;
4079 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
4083 struct fault_info *info;
4085 s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4087 dlist_foreach_safe(s_info.fault_list, l, n, info) {
4088 if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
4089 info->is_deleted = 1;
4092 if (info->is_deleted) {
4093 s_info.fault_list = dlist_remove(s_info.fault_list, l);
4098 s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4101 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
4105 struct event_info *info;
4107 if (event == LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
4108 if (handler->visible != LB_SHOW) {
4109 DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
4110 handler->paused_updating++;
4113 handler->paused_updating = 0;
4117 s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4119 dlist_foreach_safe(s_info.event_list, l, n, info) {
4120 if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
4121 DbgPrint("Event handler returns EXIT_FAILURE\n");
4122 info->is_deleted = 1;
4125 if (info->is_deleted) {
4126 s_info.event_list = dlist_remove(s_info.event_list, l);
4131 s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4134 struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
4137 struct livebox_common *common;
4139 dlist_foreach(s_info.livebox_common_list, l, common) {
4144 if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
4152 struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
4155 struct livebox_common *common;
4157 dlist_foreach(s_info.livebox_common_list, l, common) {
4158 if (common->timestamp == timestamp) {
4166 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
4168 struct livebox *handler;
4170 handler = calloc(1, sizeof(*handler));
4172 ErrPrint("Failed to create a new livebox\n");
4176 handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
4177 if (!handler->common) {
4178 ErrPrint("Heap: %s\n", strerror(errno));
4183 lb_common_ref(handler->common, handler);
4184 lb_set_id(handler->common, id);
4185 handler->common->timestamp = timestamp;
4186 handler->common->state = CREATE;
4187 handler->visible = LB_SHOW;
4188 s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
4190 return lb_ref(handler);
4193 int lb_delete_all(void)
4197 struct livebox *handler;
4199 dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
4200 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
4201 lb_unref(handler, 1);
4204 return LB_STATUS_SUCCESS;
4207 int lb_set_content(struct livebox_common *common, const char *content)
4212 pc = strdup(content);
4214 ErrPrint("heap: %s [%s]\n", strerror(errno), content);
4215 return LB_STATUS_ERROR_MEMORY;
4219 free(common->content);
4220 common->content = pc;
4221 return LB_STATUS_SUCCESS;
4224 int lb_set_title(struct livebox_common *common, const char *title)
4231 ErrPrint("heap: %s [%s]\n", strerror(errno), title);
4232 return LB_STATUS_ERROR_MEMORY;
4236 free(common->title);
4238 return LB_STATUS_SUCCESS;
4241 void lb_set_size_list(struct livebox_common *common, int size_list)
4243 common->lb.size_list = size_list;
4246 void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
4250 if (!auto_launch || !strlen(auto_launch)) {
4254 pa = strdup(auto_launch);
4256 ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
4260 free(common->lb.auto_launch);
4261 common->lb.auto_launch = pa;
4264 void lb_set_priority(struct livebox_common *common, double priority)
4266 common->lb.priority = priority;
4269 void lb_set_id(struct livebox_common *common, const char *id)
4276 ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
4285 void lb_set_filename(struct livebox_common *common, const char *filename)
4287 if (common->filename) {
4288 if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
4289 if (common->filename[0] && unlink(common->filename) < 0) {
4290 ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
4294 free(common->filename);
4297 common->filename = strdup(filename);
4298 if (!common->filename) {
4299 ErrPrint("Heap: %s\n", strerror(errno));
4303 void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
4308 if (icon && strlen(icon)) {
4309 _icon = strdup(icon);
4311 ErrPrint("Heap: %s\n", strerror(errno));
4315 if (name && strlen(name)) {
4316 _name = strdup(name);
4318 ErrPrint("Heap: %s\n", strerror(errno));
4322 free(common->alt.icon);
4323 common->alt.icon = _icon;
4325 free(common->alt.name);
4326 common->alt.name = _name;
4329 int lb_set_lb_fb(struct livebox_common *common, const char *filename)
4334 return LB_STATUS_ERROR_INVALID;
4338 if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
4339 return LB_STATUS_SUCCESS;
4342 common->lb.fb = NULL;
4344 if (!filename || filename[0] == '\0') {
4348 return LB_STATUS_SUCCESS;
4351 common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
4352 if (!common->lb.fb) {
4353 ErrPrint("Faield to create a FB\n");
4357 return LB_STATUS_ERROR_FAULT;
4364 return LB_STATUS_SUCCESS;
4367 int lb_set_pd_fb(struct livebox_common *common, const char *filename)
4371 if (!common || common->state != CREATE) {
4372 return LB_STATUS_ERROR_INVALID;
4376 if (fb && !strcmp(fb_id(fb), filename)) {
4377 /* BUFFER is not changed, just update the content */
4378 return LB_STATUS_ERROR_EXIST;
4380 common->pd.fb = NULL;
4382 if (!filename || filename[0] == '\0') {
4386 return LB_STATUS_SUCCESS;
4389 common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
4390 if (!common->pd.fb) {
4391 ErrPrint("Failed to create a FB\n");
4395 return LB_STATUS_ERROR_FAULT;
4401 return LB_STATUS_SUCCESS;
4404 struct fb_info *lb_get_lb_fb(struct livebox_common *common)
4406 return common->lb.fb;
4409 struct fb_info *lb_get_pd_fb(struct livebox_common *common)
4411 return common->pd.fb;
4414 void lb_set_user(struct livebox_common *common, int user)
4416 common->is_user = user;
4419 void lb_set_pinup(struct livebox_common *common, int pinup_supported)
4421 common->lb.pinup_supported = pinup_supported;
4424 void lb_set_text_lb(struct livebox_common *common)
4426 common->lb.type = _LB_TYPE_TEXT;
4429 void lb_set_text_pd(struct livebox_common *common)
4431 common->pd.type = _PD_TYPE_TEXT;
4434 int lb_text_lb(struct livebox_common *common)
4436 return common->lb.type == _LB_TYPE_TEXT;
4439 int lb_text_pd(struct livebox_common *common)
4441 return common->pd.type == _PD_TYPE_TEXT;
4444 void lb_set_period(struct livebox_common *common, double period)
4446 common->lb.period = period;
4449 struct livebox *lb_ref(struct livebox *handler)
4459 struct livebox *lb_unref(struct livebox *handler, int destroy_common)
4466 if (handler->refcnt > 0) {
4470 if (handler->cbs.created.cb) {
4471 handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
4472 handler->cbs.created.cb = NULL;
4473 handler->cbs.created.data = NULL;
4476 if (handler->cbs.deleted.cb) {
4477 handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
4478 handler->cbs.deleted.cb = NULL;
4479 handler->cbs.deleted.data = NULL;
4482 if (handler->cbs.pinup.cb) {
4483 handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
4484 handler->cbs.pinup.cb = NULL;
4485 handler->cbs.pinup.data = NULL;
4488 if (handler->cbs.group_changed.cb) {
4489 handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
4490 handler->cbs.group_changed.cb = NULL;
4491 handler->cbs.group_changed.data = NULL;
4494 if (handler->cbs.period_changed.cb) {
4495 handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
4496 handler->cbs.period_changed.cb = NULL;
4497 handler->cbs.period_changed.data = NULL;
4500 if (handler->cbs.size_changed.cb) {
4501 handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
4502 handler->cbs.size_changed.cb = NULL;
4503 handler->cbs.size_changed.data = NULL;
4506 if (handler->cbs.pd_created.cb) {
4507 handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
4508 handler->cbs.pd_created.cb = NULL;
4509 handler->cbs.pd_created.data = NULL;
4512 if (handler->cbs.pd_destroyed.cb) {
4513 handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
4514 handler->cbs.pd_destroyed.cb = NULL;
4515 handler->cbs.pd_destroyed.data = NULL;
4518 if (handler->cbs.update_mode.cb) {
4519 handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
4520 handler->cbs.update_mode.cb = NULL;
4521 handler->cbs.update_mode.data = NULL;
4524 if (handler->cbs.access_event.cb) {
4525 handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
4526 handler->cbs.access_event.cb = NULL;
4527 handler->cbs.access_event.data = NULL;
4530 if (handler->cbs.key_event.cb) {
4531 handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
4532 handler->cbs.key_event.cb = NULL;
4533 handler->cbs.key_event.data = NULL;
4536 dlist_remove_data(s_info.livebox_list, handler);
4538 handler->state = DESTROYED;
4539 if (lb_common_unref(handler->common, handler) == 0) {
4540 if (destroy_common) {
4543 * Lock file should be deleted after all callbacks are processed.
4545 lb_destroy_lock_file(handler->common, 0);
4546 lb_destroy_common_handle(handler->common);
4550 DbgPrint("Handler is released\n");
4554 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
4556 struct packet *packet;
4557 struct cb_info *cbinfo;
4560 if (handler->common->request.deleted) {
4561 ErrPrint("Already in-progress\n");
4563 cb(handler, LB_STATUS_SUCCESS, data);
4565 return LB_STATUS_ERROR_BUSY;
4569 cb = default_delete_cb;
4572 packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp);
4574 ErrPrint("Failed to build a param\n");
4576 cb(handler, LB_STATUS_ERROR_FAULT, data);
4579 return LB_STATUS_ERROR_FAULT;
4582 cbinfo = create_cb_info(cb, data);
4584 packet_destroy(packet);
4585 ErrPrint("Failed to create cbinfo\n");
4587 cb(handler, LB_STATUS_ERROR_FAULT, data);
4590 return LB_STATUS_ERROR_FAULT;
4593 ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
4596 * Packet is destroyed by master_rpc_async_request.
4598 destroy_cb_info(cbinfo);
4601 cb(handler, LB_STATUS_ERROR_FAULT, data);
4604 handler->common->request.deleted = 1;
4610 EAPI int livebox_client_paused(void)
4612 struct packet *packet;
4614 packet = packet_create_noack("client_paused", "d", util_timestamp());
4616 ErrPrint("Failed to create a pause packet\n");
4617 return LB_STATUS_ERROR_FAULT;
4620 return master_rpc_request_only(NULL, packet);
4623 EAPI int livebox_client_resumed(void)
4625 struct packet *packet;
4627 packet = packet_create_noack("client_resumed", "d", util_timestamp());
4629 ErrPrint("Failed to create a resume packet\n");
4630 return LB_STATUS_ERROR_FAULT;
4633 return master_rpc_request_only(NULL, packet);
4636 EAPI int livebox_sync_lb_fb(struct livebox *handler)
4638 if (!handler || handler->state != CREATE) {
4639 ErrPrint("Invalid handle\n");
4640 return LB_STATUS_ERROR_INVALID;
4643 if (!handler->common || handler->common->state != CREATE) {
4644 ErrPrint("Invalid handle\n");
4645 return LB_STATUS_ERROR_INVALID;
4648 if (!handler->common->id) {
4649 return LB_STATUS_ERROR_INVALID;
4652 return lb_sync_lb_fb(handler->common);
4655 int lb_sync_lb_fb(struct livebox_common *common)
4659 if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
4660 (void)do_fb_lock(common->lb.lock_fd);
4661 ret = fb_sync(lb_get_lb_fb(common));
4662 (void)do_fb_unlock(common->lb.lock_fd);
4664 ret = fb_sync(lb_get_lb_fb(common));
4670 int lb_sync_pd_fb(struct livebox_common *common)
4674 if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
4675 (void)do_fb_lock(common->pd.lock_fd);
4676 ret = fb_sync(lb_get_pd_fb(common));
4677 (void)do_fb_unlock(common->pd.lock_fd);
4679 ret = fb_sync(lb_get_pd_fb(common));
4685 EAPI int livebox_sync_pd_fb(struct livebox *handler)
4687 if (!handler || handler->state != CREATE) {
4688 ErrPrint("Invalid handle\n");
4689 return LB_STATUS_ERROR_INVALID;
4692 if (!handler->common || handler->common->state != CREATE) {
4693 ErrPrint("Invalid handle\n");
4694 return LB_STATUS_ERROR_INVALID;
4697 if (!handler->common->id) {
4698 ErrPrint("Invalid handle\n");
4699 return LB_STATUS_ERROR_INVALID;
4702 return lb_sync_pd_fb(handler->common);
4705 EAPI const char *livebox_alt_icon(struct livebox *handler)
4707 if (!handler || handler->state != CREATE) {
4708 ErrPrint("Handler is not valid[%p]\n", handler);
4712 if (!handler->common || handler->common->state != CREATE) {
4713 ErrPrint("Handler is not valid\n");
4717 return handler->common->alt.icon;
4720 EAPI const char *livebox_alt_name(struct livebox *handler)
4722 if (!handler || handler->state != CREATE) {
4723 ErrPrint("Handler is not valid[%p]\n", handler);
4727 if (!handler->common || handler->common->state != CREATE) {
4728 ErrPrint("Handler is not valid\n");
4732 return handler->common->alt.name;
4735 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
4737 int ret = LB_STATUS_SUCCESS;
4740 if (!handler || handler->state != CREATE) {
4741 ErrPrint("Handler is not valid[%p]\n", handler);
4742 return LB_STATUS_ERROR_INVALID;
4745 if (!handler->common || handler->common->state != CREATE) {
4746 ErrPrint("Handler is not valid\n");
4747 return LB_STATUS_ERROR_INVALID;
4750 if (!handler->common->id) {
4751 ErrPrint("Handler is not valid[%p]\n", handler);
4752 return LB_STATUS_ERROR_INVALID;
4756 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4757 DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4758 return LB_STATUS_ERROR_INVALID;
4761 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4762 return LB_STATUS_SUCCESS;
4765 fd = handler->common->pd.lock_fd;
4767 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4768 DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4769 return LB_STATUS_ERROR_INVALID;
4772 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4773 return LB_STATUS_SUCCESS;
4776 fd = handler->common->lb.lock_fd;
4779 ret = do_fb_lock(fd);
4781 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4784 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
4786 int ret = LB_STATUS_SUCCESS;
4789 if (!handler || handler->state != CREATE) {
4790 ErrPrint("Invalid handle\n");
4791 return LB_STATUS_ERROR_INVALID;
4794 if (!handler->common || handler->common->state != CREATE) {
4795 ErrPrint("Invalid handle\n");
4796 return LB_STATUS_ERROR_INVALID;
4799 if (!handler->common->id) {
4800 ErrPrint("Handler is not valid[%p]\n", handler);
4801 return LB_STATUS_ERROR_INVALID;
4805 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4806 DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4807 return LB_STATUS_ERROR_INVALID;
4810 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4811 return LB_STATUS_SUCCESS;
4814 fd = handler->common->pd.lock_fd;
4816 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4817 DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4818 return LB_STATUS_ERROR_INVALID;
4821 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4822 return LB_STATUS_SUCCESS;
4825 fd = handler->common->lb.lock_fd;
4828 ret = do_fb_unlock(fd);
4830 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4833 EAPI int livebox_set_option(enum livebox_option_type option, int state)
4835 int ret = LB_STATUS_SUCCESS;
4838 case LB_OPTION_MANUAL_SYNC:
4839 conf_set_manual_sync(state);
4841 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4842 conf_set_frame_drop_for_resizing(state);
4844 case LB_OPTION_SHARED_CONTENT:
4845 conf_set_shared_content(state);
4848 ret = LB_STATUS_ERROR_INVALID;
4855 EAPI int livebox_option(enum livebox_option_type option)
4860 case LB_OPTION_MANUAL_SYNC:
4861 ret = conf_manual_sync();
4863 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4864 ret = conf_frame_drop_for_resizing();
4866 case LB_OPTION_SHARED_CONTENT:
4867 ret = conf_shared_content();
4870 ret = LB_STATUS_ERROR_INVALID;
4877 EAPI int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data)
4879 s_info.launch.handler = launch_handler;
4880 s_info.launch.data = data;
4882 return LB_STATUS_SUCCESS;