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 = livebox_service_mouse_event(common->pkgname);
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 == (int)LB_SHOW) {
1416 need_to_add_job = !!handler->paused_updating;
1417 } else if (handler->common->visible == (int)LB_SHOW && state != LB_SHOW) {
1419 struct livebox *item;
1421 dlist_foreach(handler->common->livebox_list, l, item) {
1422 if (item->visible == (int)LB_SHOW) {
1423 DbgPrint("%s visibility is not changed\n", handler->common->pkgname);
1424 return LB_STATUS_SUCCESS;
1427 } else if (handler->common->visible == (int)LB_SHOW && state == (int)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 == (int)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 == (int)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 == (int)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 == (int)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 short 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");
2699 ErrPrint("Invalid event type\n");
2700 return LB_STATUS_ERROR_INVALID;
2703 return send_mouse_event(handler, cmd, x * w, y * h);
2706 EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data)
2708 char cmd[32] = { '\0', };
2712 if (!handler || handler->state != CREATE) {
2713 ErrPrint("Handler is invalid\n");
2714 return LB_STATUS_ERROR_INVALID;
2717 if (!handler->common || handler->common->state != CREATE) {
2718 ErrPrint("Handler is invalid\n");
2719 return LB_STATUS_ERROR_INVALID;
2722 if (!handler->common->id) {
2723 ErrPrint("Handler is not valid\n");
2724 return LB_STATUS_ERROR_INVALID;
2727 if (!(type & CONTENT_EVENT_KEY_MASK)) {
2728 ErrPrint("Invalid key event is used\n");
2729 return LB_STATUS_ERROR_INVALID;
2732 if (handler->common->request.key_event) {
2733 ErrPrint("Previous key event is not completed yet\n");
2734 return LB_STATUS_ERROR_BUSY;
2737 if (type & CONTENT_EVENT_PD_MASK) {
2738 if (!handler->common->is_pd_created) {
2739 ErrPrint("PD is not created\n");
2740 return LB_STATUS_ERROR_INVALID;
2743 if (!handler->common->pd.fb) {
2744 ErrPrint("Handler is not valid\n");
2745 return LB_STATUS_ERROR_INVALID;
2748 if (type & CONTENT_EVENT_KEY_DOWN) {
2751 * filtering the reproduced events if it is too fast
2753 } else if (type & CONTENT_EVENT_KEY_SET) {
2756 * What can I do for this case?
2762 } else if (type & CONTENT_EVENT_LB_MASK) {
2763 if (!handler->common->lb.mouse_event) {
2764 return LB_STATUS_ERROR_INVALID;
2767 if (!handler->common->lb.fb) {
2768 ErrPrint("Handler is not valid\n");
2769 return LB_STATUS_ERROR_INVALID;
2772 if (type & CONTENT_EVENT_KEY_DOWN) {
2775 * filtering the reproduced events if it is too fast
2777 } else if (type & CONTENT_EVENT_KEY_SET) {
2779 * What can I do for this case?
2786 ErrPrint("Invalid event type\n");
2787 return LB_STATUS_ERROR_INVALID;
2791 * Must be short than 29 bytes.
2793 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
2794 case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK:
2795 strcpy(ptr, "_key_focus_in");
2797 case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK:
2798 strcpy(ptr, "_key_focus_out");
2800 case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
2801 strcpy(ptr, "_key_up");
2803 case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
2804 strcpy(ptr, "_key_down");
2806 case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK:
2807 strcpy(ptr, "_key_set");
2809 case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK:
2810 strcpy(ptr, "_key_unset");
2813 ErrPrint("Invalid event type\n");
2814 return LB_STATUS_ERROR_INVALID;
2818 cb = default_key_event_cb;
2821 ret = send_key_event(handler, cmd, keycode);
2822 if (ret == (int)LB_STATUS_SUCCESS) {
2823 handler->cbs.key_event.cb = cb;
2824 handler->cbs.key_event.data = data;
2825 handler->common->request.key_event = 1;
2831 EAPI const char *livebox_filename(struct livebox *handler)
2833 if (!handler || handler->state != CREATE) {
2834 ErrPrint("Handler is invalid\n");
2838 if (!handler->common || handler->common->state != CREATE) {
2839 ErrPrint("Handler is invalid\n");
2843 if (!handler->common->id) {
2844 ErrPrint("Handler is not valid\n");
2848 if (handler->common->filename) {
2849 return handler->common->filename;
2853 return util_uri_to_path(handler->common->id);
2856 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
2861 if (!handler || handler->state != CREATE) {
2862 ErrPrint("Handler is invalid\n");
2863 return LB_STATUS_ERROR_INVALID;
2866 if (!handler->common || handler->common->state != CREATE) {
2867 ErrPrint("Handler is invalid\n");
2868 return LB_STATUS_ERROR_INVALID;
2871 if (!handler->common->id) {
2872 ErrPrint("Handler is not valid\n");
2873 return LB_STATUS_ERROR_INVALID;
2883 if (!handler->common->is_pd_created) {
2884 *w = handler->common->pd.default_width;
2885 *h = handler->common->pd.default_height;
2887 *w = handler->common->pd.width;
2888 *h = handler->common->pd.height;
2891 return LB_STATUS_SUCCESS;
2894 EAPI int livebox_size(struct livebox *handler)
2899 if (!handler || handler->state != CREATE) {
2900 ErrPrint("Handler is invalid\n");
2901 return LB_STATUS_ERROR_INVALID;
2904 if (!handler->common || handler->common->state != CREATE) {
2905 ErrPrint("Handler is invalid\n");
2906 return LB_STATUS_ERROR_INVALID;
2909 if (!handler->common->id) {
2910 ErrPrint("Handler is not valid\n");
2911 return LB_STATUS_ERROR_INVALID;
2914 w = handler->common->lb.width;
2915 h = handler->common->lb.height;
2917 switch (handler->common->lb.type) {
2918 case _LB_TYPE_BUFFER:
2919 case _LB_TYPE_SCRIPT:
2920 if (!fb_is_created(handler->common->lb.fb)) {
2929 return livebox_service_size_type(w, h);
2932 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
2934 struct packet *packet;
2938 ErrPrint("Handler is NIL\n");
2939 return LB_STATUS_ERROR_INVALID;
2942 if (!cluster || !category || handler->state != CREATE) {
2943 ErrPrint("Invalid argument\n");
2944 return LB_STATUS_ERROR_INVALID;
2947 if (!handler->common || handler->common->state != CREATE) {
2948 ErrPrint("Invalid argument\n");
2949 return LB_STATUS_ERROR_INVALID;
2952 if (!handler->common->id) {
2953 ErrPrint("Invalid argument\n");
2954 return LB_STATUS_ERROR_INVALID;
2957 if (handler->common->request.group_changed) {
2958 ErrPrint("Previous group changing request is not finished yet\n");
2959 return LB_STATUS_ERROR_BUSY;
2962 if (!handler->common->is_user) {
2963 ErrPrint("CA Livebox is not able to change the group\n");
2964 return LB_STATUS_ERROR_PERMISSION;
2967 if (!strcmp(handler->common->cluster, cluster) && !strcmp(handler->common->category, category)) {
2968 DbgPrint("No changes\n");
2969 return LB_STATUS_ERROR_ALREADY;
2972 packet = packet_create("change_group", "ssss", handler->common->pkgname, handler->common->id, cluster, category);
2974 ErrPrint("Failed to build a param\n");
2975 return LB_STATUS_ERROR_FAULT;
2979 cb = default_group_changed_cb;
2982 ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
2983 if (ret == (int)LB_STATUS_SUCCESS) {
2984 handler->cbs.group_changed.cb = cb;
2985 handler->cbs.group_changed.data = data;
2986 handler->common->request.group_changed = 1;
2992 EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category)
2995 ErrPrint("Handler is NIL\n");
2996 return LB_STATUS_ERROR_INVALID;
2999 if (!cluster || !category || handler->state != CREATE) {
3000 ErrPrint("Invalid argument\n");
3001 return LB_STATUS_ERROR_INVALID;
3004 if (!handler->common || handler->common->state != CREATE) {
3005 ErrPrint("Invalid argument\n");
3006 return LB_STATUS_ERROR_INVALID;
3009 if (!handler->common->id) {
3010 ErrPrint("Invalid argument\n");
3011 return LB_STATUS_ERROR_INVALID;
3014 *cluster = handler->common->cluster;
3015 *category = handler->common->category;
3016 return LB_STATUS_SUCCESS;
3019 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
3024 if (!handler || !size_list) {
3025 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
3026 return LB_STATUS_ERROR_INVALID;
3029 if (!cnt || handler->state != CREATE) {
3030 ErrPrint("Handler is not valid\n");
3031 return LB_STATUS_ERROR_INVALID;
3034 if (!handler->common || handler->common->state != CREATE) {
3035 ErrPrint("Handler is not valid\n");
3036 return LB_STATUS_ERROR_INVALID;
3039 if (!handler->common->id) {
3040 ErrPrint("Handler is not valid\n");
3041 return LB_STATUS_ERROR_INVALID;
3044 for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
3045 if (handler->common->lb.size_list & (0x01 << i)) {
3050 size_list[j++] = (0x01 << i);
3055 return LB_STATUS_SUCCESS;
3058 EAPI const char *livebox_pkgname(struct livebox *handler)
3061 ErrPrint("Handler is NIL\n");
3065 if (handler->state != CREATE) {
3066 ErrPrint("Handler is not valid\n");
3070 if (!handler->common || handler->common->state != CREATE) {
3071 ErrPrint("Handler is not valid\n");
3075 return handler->common->pkgname;
3078 EAPI double livebox_priority(struct livebox *handler)
3080 if (!handler || handler->state != CREATE) {
3081 ErrPrint("Handler is invalid\n");
3085 if (!handler->common || handler->common->state != CREATE) {
3086 ErrPrint("Handler is invalid\n");
3090 if (!handler->common->id) {
3091 ErrPrint("Handler is not valid (%p)\n", handler);
3095 return handler->common->lb.priority;
3098 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
3100 struct packet *packet;
3101 struct cb_info *cbinfo;
3104 packet = packet_create("delete_cluster", "s", cluster);
3106 ErrPrint("Failed to build a param\n");
3107 return LB_STATUS_ERROR_FAULT;
3110 cbinfo = create_cb_info(cb, data);
3112 packet_destroy(packet);
3113 return LB_STATUS_ERROR_FAULT;
3116 ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
3118 destroy_cb_info(cbinfo);
3124 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
3126 struct packet *packet;
3127 struct cb_info *cbinfo;
3130 packet = packet_create("delete_category", "ss", cluster, category);
3132 ErrPrint("Failed to build a param\n");
3133 return LB_STATUS_ERROR_FAULT;
3136 cbinfo = create_cb_info(cb, data);
3138 packet_destroy(packet);
3139 return LB_STATUS_ERROR_FAULT;
3142 ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
3144 destroy_cb_info(cbinfo);
3150 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
3152 if (!handler || handler->state != CREATE) {
3153 ErrPrint("Handler is invalid\n");
3154 return LB_TYPE_INVALID;
3157 if (!handler->common || handler->common->state != CREATE) {
3158 ErrPrint("Handler is invalid\n");
3159 return LB_TYPE_INVALID;
3162 if (!handler->common->id) {
3163 ErrPrint("Handler is not valid\n");
3164 return LB_TYPE_INVALID;
3167 switch (handler->common->lb.type) {
3169 return LB_TYPE_IMAGE;
3170 case _LB_TYPE_BUFFER:
3171 case _LB_TYPE_SCRIPT:
3174 id = fb_id(handler->common->lb.fb);
3175 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3176 return LB_TYPE_PIXMAP;
3179 return LB_TYPE_BUFFER;
3181 return LB_TYPE_TEXT;
3186 return LB_TYPE_INVALID;
3189 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
3191 if (!handler || handler->state != CREATE) {
3192 ErrPrint("Handler is invalid\n");
3193 return PD_TYPE_INVALID;
3196 if (!handler->common || handler->common->state != CREATE) {
3197 ErrPrint("Handler is invalid\n");
3198 return PD_TYPE_INVALID;
3201 if (!handler->common->id) {
3202 ErrPrint("Handler is not valid\n");
3203 return PD_TYPE_INVALID;
3206 switch (handler->common->pd.type) {
3208 return PD_TYPE_TEXT;
3209 case _PD_TYPE_BUFFER:
3210 case _PD_TYPE_SCRIPT:
3213 id = fb_id(handler->common->pd.fb);
3214 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
3215 return PD_TYPE_PIXMAP;
3218 return PD_TYPE_BUFFER;
3223 return PD_TYPE_INVALID;
3226 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3229 ErrPrint("Handler is NIL\n");
3230 return LB_STATUS_ERROR_INVALID;
3233 if (handler->state != CREATE) {
3234 ErrPrint("Handler is not valid\n");
3235 return LB_STATUS_ERROR_INVALID;
3238 memcpy(&handler->cbs.pd_ops, ops, sizeof(*ops));
3239 return LB_STATUS_SUCCESS;
3242 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
3245 ErrPrint("Handler is NIL\n");
3246 return LB_STATUS_ERROR_INVALID;
3249 if (handler->state != CREATE) {
3250 ErrPrint("Handler is not valid\n");
3251 return LB_STATUS_ERROR_INVALID;
3254 memcpy(&handler->cbs.lb_ops, ops, sizeof(*ops));
3255 return LB_STATUS_SUCCESS;
3258 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3260 if (!handler || handler->state != CREATE) {
3261 ErrPrint("Handler is invalid\n");
3262 return LB_STATUS_ERROR_INVALID;
3265 if (!handler->common || handler->common->state != CREATE) {
3266 ErrPrint("Handler is invalid\n");
3267 return LB_STATUS_ERROR_INVALID;
3270 if (!handler->common->id) {
3271 ErrPrint("Invalid handle\n");
3272 return LB_STATUS_ERROR_INVALID;
3275 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3276 ErrPrint("Handler is not valid type\n");
3277 return LB_STATUS_ERROR_INVALID;
3280 return lb_acquire_lb_pixmap(handler, cb, data);
3285 * Do not check the state of handler and common-handler.
3286 * If this function is used in the deleted callback,
3287 * the handler and common-handler's state would be DELETE
3288 * if this function check the state of handles,
3289 * user cannot release the pixmap.
3291 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
3293 struct packet *packet;
3294 const char *pkgname;
3297 if (pixmap == 0 /* || handler->state != CREATE */ ) {
3298 ErrPrint("Handler is invalid [%d]\n", pixmap);
3299 return LB_STATUS_ERROR_INVALID;
3305 * Even though the handler is NULL, we should send the release request to the master.
3306 * Because the pixmap resource can be released after the handler is destroyed.
3307 * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3308 * In some cases, the pixmap can be released after the handler is deleted.
3310 * Its implementation is up to the viewer app.
3311 * But we cannot force it to use only with valid handler.
3313 DbgPrint("Using NULL handler\n");
3318 * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3321 if (!handler->common /* || handler->common->state != CREATE */) {
3322 ErrPrint("Handler is invalid\n");
3323 return LB_STATUS_ERROR_INVALID;
3326 if (!handler->common->id) {
3327 ErrPrint("Invalid handle\n");
3328 return LB_STATUS_ERROR_INVALID;
3331 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3332 ErrPrint("Handler is not valid type\n");
3333 return LB_STATUS_ERROR_INVALID;
3336 pkgname = handler->common->pkgname;
3337 id = handler->common->id;
3340 packet = packet_create_noack("lb_release_pixmap", "ssi", pkgname, id, pixmap);
3342 ErrPrint("Failed to build a param\n");
3343 return LB_STATUS_ERROR_INVALID;
3346 return master_rpc_request_only(handler, packet);
3349 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
3351 if (!handler || handler->state != CREATE) {
3352 ErrPrint("Handler is invalid\n");
3353 return LB_STATUS_ERROR_INVALID;
3356 if (!handler->common || handler->common->state != CREATE) {
3357 ErrPrint("Handler is invalid\n");
3358 return LB_STATUS_ERROR_INVALID;
3361 if (!handler->common->id) {
3362 ErrPrint("Invalid handle\n");
3363 return LB_STATUS_ERROR_INVALID;
3366 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3367 ErrPrint("Handler is not valid type\n");
3368 return LB_STATUS_ERROR_INVALID;
3371 return lb_acquire_pd_pixmap(handler, cb, data);
3374 EAPI int livebox_pd_pixmap(const struct livebox *handler)
3379 if (!handler || handler->state != CREATE) {
3380 ErrPrint("Handler is invalid\n");
3384 if (!handler->common || handler->common->state != CREATE) {
3385 ErrPrint("Handler is invalid\n");
3389 if (!handler->common->id) {
3390 ErrPrint("Invalid handler\n");
3394 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3395 ErrPrint("Invalid handler\n");
3399 id = fb_id(handler->common->pd.fb);
3400 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3401 ErrPrint("PIXMAP Id is not valid\n");
3408 EAPI int livebox_lb_pixmap(const struct livebox *handler)
3413 if (!handler || handler->state != CREATE) {
3414 ErrPrint("Handler is invalid\n");
3418 if (!handler->common || handler->common->state != CREATE) {
3419 ErrPrint("Handler is invalid\n");
3423 if (!handler->common->id) {
3424 ErrPrint("Invalid handler\n");
3428 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3429 ErrPrint("Invalid handler\n");
3433 id = fb_id(handler->common->lb.fb);
3434 if (id && sscanf(id, SCHEMA_PIXMAP "%u", (unsigned int *)&pixmap) != 1) {
3435 ErrPrint("PIXMAP Id is not valid\n");
3444 * Do not check the state of handler and common-handler.
3445 * If this function is used in the deleted callback,
3446 * the handler and common-handler's state would be DELETE
3447 * if this function check the state of handles,
3448 * user cannot release the pixmap.
3450 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
3452 struct packet *packet;
3453 const char *pkgname;
3456 if (pixmap == 0 /* || handler->state != CREATE */) {
3457 ErrPrint("Pixmap is invalid [%d]\n", pixmap);
3458 return LB_STATUS_ERROR_INVALID;
3464 * Even though the handler is NULL, we should send the release request to the master.
3465 * Because the pixmap resource can be released after the handler is destroyed.
3466 * Pixmap resource is used by client. and it cannot be guaranteed to release pixmap.
3467 * In some cases, the pixmap can be released after the handler is deleted.
3469 * Its implementation is up to the viewer app.
3470 * But we cannot force it to use only with valid handler.
3472 DbgPrint("Using NULL handler\n");
3477 * Master will try to find the buffer handler using given pixmap. if the pkgname and id is not valid.
3480 if (!handler->common /* || handler-common->state != CREATE */) {
3481 ErrPrint("Handler is invalid\n");
3482 return LB_STATUS_ERROR_INVALID;
3485 if (!handler->common->id) {
3486 ErrPrint("Invalid handle\n");
3487 return LB_STATUS_ERROR_INVALID;
3490 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3491 ErrPrint("Handler is not valid type\n");
3492 return LB_STATUS_ERROR_INVALID;
3495 pkgname = handler->common->pkgname;
3496 id = handler->common->id;
3499 packet = packet_create_noack("pd_release_pixmap", "ssi", pkgname, id, pixmap);
3501 ErrPrint("Failed to build a param\n");
3502 return LB_STATUS_ERROR_FAULT;
3505 return master_rpc_request_only(handler, packet);
3508 EAPI void *livebox_acquire_fb(struct livebox *handler)
3510 if (!handler || handler->state != CREATE) {
3511 ErrPrint("Handler is invalid\n");
3515 if (!handler->common || handler->common->state != CREATE) {
3516 ErrPrint("Handler is invalid\n");
3520 if (!handler->common->id) {
3521 ErrPrint("Invalid handle\n");
3525 if (handler->common->lb.type != _LB_TYPE_SCRIPT && handler->common->lb.type != _LB_TYPE_BUFFER) {
3526 ErrPrint("Handler is not valid type\n");
3530 return fb_acquire_buffer(handler->common->lb.fb);
3533 EAPI int livebox_release_fb(void *buffer)
3535 return fb_release_buffer(buffer);
3538 EAPI int livebox_fb_refcnt(void *buffer)
3540 return fb_refcnt(buffer);
3543 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
3545 if (!handler || handler->state != CREATE) {
3546 ErrPrint("Handler is invalid\n");
3550 if (!handler->common || handler->common->state != CREATE) {
3551 ErrPrint("Handler is invalid\n");
3555 if (!handler->common->id) {
3556 ErrPrint("Invalid handler\n");
3560 if (handler->common->pd.type != _PD_TYPE_SCRIPT && handler->common->pd.type != _PD_TYPE_BUFFER) {
3561 ErrPrint("Handler is not valid type\n");
3565 return fb_acquire_buffer(handler->common->pd.fb);
3568 EAPI int livebox_release_pdfb(void *buffer)
3570 return fb_release_buffer(buffer);
3573 EAPI int livebox_pdfb_refcnt(void *buffer)
3575 return fb_refcnt(buffer);
3578 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
3580 if (!handler || handler->state != CREATE) {
3581 ErrPrint("Handler is invalid\n");
3582 return LB_STATUS_ERROR_INVALID;
3585 if (!handler->common || handler->common->state != CREATE) {
3586 ErrPrint("Handler is invalid\n");
3587 return LB_STATUS_ERROR_INVALID;
3590 if (!handler->common->id) {
3591 ErrPrint("Invalid handler\n");
3592 return LB_STATUS_ERROR_INVALID;
3595 return fb_size(handler->common->pd.fb);
3598 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
3600 if (!handler || handler->state != CREATE) {
3601 ErrPrint("Handler is invalid\n");
3602 return LB_STATUS_ERROR_INVALID;
3605 if (!handler->common || handler->common->state != CREATE) {
3606 ErrPrint("Handler is invalid\n");
3607 return LB_STATUS_ERROR_INVALID;
3610 if (!handler->common->id) {
3611 ErrPrint("Invalid handler\n");
3612 return LB_STATUS_ERROR_INVALID;
3615 return fb_size(handler->common->lb.fb);
3618 EAPI int livebox_is_user(struct livebox *handler)
3620 if (!handler || handler->state != CREATE) {
3621 ErrPrint("Handler is invalid\n");
3622 return LB_STATUS_ERROR_INVALID;
3625 if (!handler->common || handler->common->state != CREATE) {
3626 ErrPrint("Handler is invalid\n");
3627 return LB_STATUS_ERROR_INVALID;
3630 if (!handler->common->id) {
3631 ErrPrint("Invalid handler\n");
3632 return LB_STATUS_ERROR_INVALID;
3635 return handler->common->is_user;
3638 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
3640 struct packet *packet;
3643 if (!handler || handler->state != CREATE) {
3644 ErrPrint("Handler is invalid\n");
3645 return LB_STATUS_ERROR_INVALID;
3648 if (!handler->common || handler->common->state != CREATE) {
3649 ErrPrint("Handler is invalid\n");
3650 return LB_STATUS_ERROR_INVALID;
3653 if (!handler->common->id) {
3654 ErrPrint("Invalid handler\n");
3655 return LB_STATUS_ERROR_INVALID;
3658 if (handler->common->request.pinup) {
3659 ErrPrint("Previous pinup request is not finished\n");
3660 return LB_STATUS_ERROR_BUSY;
3663 if (handler->common->is_pinned_up == flag) {
3664 DbgPrint("No changes\n");
3665 return LB_STATUS_ERROR_ALREADY;
3668 packet = packet_create("pinup_changed", "ssi", handler->common->pkgname, handler->common->id, flag);
3670 ErrPrint("Failed to build a param\n");
3671 return LB_STATUS_ERROR_FAULT;
3675 cb = default_pinup_cb;
3678 ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
3679 if (ret == (int)LB_STATUS_SUCCESS) {
3680 handler->cbs.pinup.cb = cb;
3681 handler->cbs.pinup.data = data;
3682 handler->common->request.pinup = 1;
3688 EAPI int livebox_is_pinned_up(struct livebox *handler)
3690 if (!handler || handler->state != CREATE) {
3691 ErrPrint("Handler is invalid\n");
3692 return LB_STATUS_ERROR_INVALID;
3695 if (!handler->common || handler->common->state != CREATE) {
3696 ErrPrint("Handler is invalid\n");
3697 return LB_STATUS_ERROR_INVALID;
3700 if (!handler->common->id) {
3701 ErrPrint("Invalid handler\n");
3702 return LB_STATUS_ERROR_INVALID;
3705 return handler->common->is_pinned_up;
3708 EAPI int livebox_has_pinup(struct livebox *handler)
3710 if (!handler || handler->state != CREATE) {
3711 ErrPrint("Handler is invalid\n");
3712 return LB_STATUS_ERROR_INVALID;
3715 if (!handler->common || handler->common->state != CREATE) {
3716 ErrPrint("Handler is invalid\n");
3717 return LB_STATUS_ERROR_INVALID;
3720 if (!handler->common->id) {
3721 ErrPrint("Invalid handler\n");
3722 return LB_STATUS_ERROR_INVALID;
3725 return handler->common->lb.pinup_supported;
3728 EAPI int livebox_set_data(struct livebox *handler, void *data)
3731 ErrPrint("Handler is NIL\n");
3732 return LB_STATUS_ERROR_INVALID;
3735 if (handler->state != CREATE) {
3736 ErrPrint("Handler is invalid\n");
3737 return LB_STATUS_ERROR_INVALID;
3740 handler->data = data;
3741 return LB_STATUS_SUCCESS;
3744 EAPI void *livebox_get_data(struct livebox *handler)
3747 ErrPrint("Handler is NIL\n");
3751 if (handler->state != CREATE) {
3752 ErrPrint("Handler is invalid\n");
3756 return handler->data;
3759 EAPI int livebox_is_exists(const char *pkgname)
3763 lb = lb_pkgname(pkgname);
3772 EAPI const char *livebox_content(struct livebox *handler)
3774 if (!handler || handler->state != CREATE) {
3775 ErrPrint("Handler is invalid\n");
3779 if (!handler->common || handler->common->state != CREATE) {
3780 ErrPrint("Invalid handle\n");
3784 return handler->common->content;
3787 EAPI const char *livebox_category_title(struct livebox *handler)
3789 if (!handler || handler->state != CREATE) {
3790 ErrPrint("Handler is invalid\n");
3794 if (!handler->common || handler->common->state != CREATE) {
3795 ErrPrint("Invalid handle\n");
3799 return handler->common->title;
3802 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)
3804 struct packet *packet;
3805 struct cb_info *cbinfo;
3808 if (!handler || handler->state != CREATE) {
3809 ErrPrint("Handler is invalid\n");
3810 return LB_STATUS_ERROR_INVALID;
3813 if (!handler->common || handler->common->state != CREATE) {
3814 ErrPrint("Handler is invalid\n");
3815 return LB_STATUS_ERROR_INVALID;
3818 if ((handler->common->lb.type != _LB_TYPE_TEXT && handler->common->pd.type != _PD_TYPE_TEXT) || !handler->common->id) {
3819 ErrPrint("Handler is not valid\n");
3820 return LB_STATUS_ERROR_INVALID;
3831 packet = packet_create("text_signal", "ssssdddd",
3832 handler->common->pkgname, handler->common->id, emission, source, sx, sy, ex, ey);
3834 ErrPrint("Failed to build a param\n");
3835 return LB_STATUS_ERROR_FAULT;
3838 cbinfo = create_cb_info(cb, data);
3840 packet_destroy(packet);
3841 return LB_STATUS_ERROR_FAULT;
3844 ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
3846 destroy_cb_info(cbinfo);
3852 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
3854 struct packet *packet;
3858 * Validate the group info using DB
3859 * If the group info is not valid, do not send this request
3862 packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
3864 ErrPrint("Failed to create a packet\n");
3865 return LB_STATUS_ERROR_FAULT;
3868 return master_rpc_request_only(NULL, packet);
3871 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
3873 struct packet *packet;
3877 * Validate the group info using DB
3878 * If the group info is not valid, do not send this request
3879 * AND Check the subscribed or not too
3882 packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
3884 ErrPrint("Failed to create a packet\n");
3885 return LB_STATUS_ERROR_FAULT;
3888 return master_rpc_request_only(NULL, packet);
3891 EAPI int livebox_refresh(struct livebox *handler, int force)
3893 struct packet *packet;
3895 if (!handler || handler->state != CREATE) {
3896 ErrPrint("Handler is invalid\n");
3897 return LB_STATUS_ERROR_INVALID;
3900 if (!handler->common || handler->common->state != CREATE) {
3901 ErrPrint("Handler is not valid\n");
3902 return LB_STATUS_ERROR_INVALID;
3905 if (!handler->common->id) {
3906 ErrPrint("Handler is not valid\n");
3907 return LB_STATUS_ERROR_INVALID;
3910 packet = packet_create_noack("update", "ssi", handler->common->pkgname, handler->common->id, force);
3912 ErrPrint("Failed to create a packet\n");
3913 return LB_STATUS_ERROR_FAULT;
3916 return master_rpc_request_only(handler, packet);
3919 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
3921 struct packet *packet;
3923 if (!cluster || !category) {
3924 ErrPrint("Invalid argument\n");
3925 return LB_STATUS_ERROR_INVALID;
3928 packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
3930 ErrPrint("Failed to create a packet\n");
3931 return LB_STATUS_ERROR_FAULT;
3934 return master_rpc_request_only(NULL, packet);
3937 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
3942 if (!handler || handler->state != CREATE) {
3943 ErrPrint("Handler is invalid\n");
3944 return LB_STATUS_ERROR_INVALID;
3947 if (!handler->common || handler->common->state != CREATE) {
3948 ErrPrint("Handler is not valid\n");
3949 return LB_STATUS_ERROR_INVALID;
3952 if (!handler->common->id) {
3953 ErrPrint("Handler is not valid\n");
3954 return LB_STATUS_ERROR_INVALID;
3957 if (!handler->common->is_user) {
3958 /* System cluster livebox cannot be changed its visible states */
3959 if (state == (int)LB_HIDE_WITH_PAUSE) {
3960 ErrPrint("CA Livebox is not able to change the visibility\n");
3961 return LB_STATUS_ERROR_PERMISSION;
3965 DbgPrint("[%s] Change visiblity to 0x%x\n", handler->common->pkgname, state);
3967 if (handler->visible == state) {
3968 DbgPrint("%s has no changes\n", handler->common->pkgname);
3969 return LB_STATUS_ERROR_ALREADY;
3972 old_state = handler->visible;
3973 handler->visible = state;
3975 ret = lb_set_visibility(handler, state);
3977 handler->visible = old_state;
3983 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
3985 if (!handler || handler->state != CREATE) {
3986 ErrPrint("Handler is invalid\n");
3987 return LB_VISIBLE_ERROR;
3990 if (!handler->common || handler->common->state != CREATE) {
3991 ErrPrint("Handler is not valid\n");
3992 return LB_VISIBLE_ERROR;
3995 if (!handler->common->id) {
3996 ErrPrint("Handler is not valid\n");
3997 return LB_VISIBLE_ERROR;
4000 return handler->visible;
4003 int lb_set_group(struct livebox_common *common, const char *cluster, const char *category)
4009 pc = strdup(cluster);
4011 ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
4012 return LB_STATUS_ERROR_MEMORY;
4017 ps = strdup(category);
4019 ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
4021 return LB_STATUS_ERROR_MEMORY;
4025 if (common->cluster) {
4026 free(common->cluster);
4029 if (common->category) {
4030 free(common->category);
4033 common->cluster = pc;
4034 common->category = ps;
4036 return LB_STATUS_SUCCESS;
4039 void lb_set_size(struct livebox_common *common, int w, int h)
4041 common->lb.width = w;
4042 common->lb.height = h;
4045 void lb_set_update_mode(struct livebox_common *common, int active_mode)
4047 common->is_active_update = active_mode;
4050 void lb_set_pdsize(struct livebox_common *common, int w, int h)
4052 common->pd.width = w;
4053 common->pd.height = h;
4056 void lb_set_default_pdsize(struct livebox_common *common, int w, int h)
4058 common->pd.default_width = w;
4059 common->pd.default_height = h;
4062 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
4066 struct fault_info *info;
4068 s_info.fault_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4070 dlist_foreach_safe(s_info.fault_list, l, n, info) {
4071 if (!info->is_deleted && info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
4072 info->is_deleted = 1;
4075 if (info->is_deleted) {
4076 s_info.fault_list = dlist_remove(s_info.fault_list, l);
4081 s_info.fault_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4084 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
4088 struct event_info *info;
4090 if (event == (int)LB_EVENT_LB_UPDATED && handler->common->refcnt > 1) {
4091 if (handler->visible != LB_SHOW) {
4092 DbgPrint("Update requested(pending) - %s\n", handler->common->pkgname);
4093 handler->paused_updating++;
4096 handler->paused_updating = 0;
4100 s_info.event_state = INFO_STATE_CALLBACK_IN_PROCESSING;
4102 dlist_foreach_safe(s_info.event_list, l, n, info) {
4103 if (!info->is_deleted && info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
4104 DbgPrint("Event handler returns EXIT_FAILURE\n");
4105 info->is_deleted = 1;
4108 if (info->is_deleted) {
4109 s_info.event_list = dlist_remove(s_info.event_list, l);
4114 s_info.event_state &= ~INFO_STATE_CALLBACK_IN_PROCESSING;
4117 struct livebox_common *lb_find_common_handle(const char *pkgname, const char *id)
4120 struct livebox_common *common;
4122 dlist_foreach(s_info.livebox_common_list, l, common) {
4127 if (!strcmp(common->pkgname, pkgname) && !strcmp(common->id, id)) {
4135 struct livebox_common *lb_find_common_handle_by_timestamp(double timestamp)
4138 struct livebox_common *common;
4140 dlist_foreach(s_info.livebox_common_list, l, common) {
4141 if (common->timestamp == timestamp) {
4149 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp, const char *cluster, const char *category)
4151 struct livebox *handler;
4153 handler = calloc(1, sizeof(*handler));
4155 ErrPrint("Failed to create a new livebox\n");
4159 handler->common = lb_create_common_handle(handler, pkgname, cluster, category);
4160 if (!handler->common) {
4161 ErrPrint("Heap: %s\n", strerror(errno));
4166 lb_common_ref(handler->common, handler);
4167 lb_set_id(handler->common, id);
4168 handler->common->timestamp = timestamp;
4169 handler->common->state = CREATE;
4170 handler->visible = LB_SHOW;
4171 s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
4173 return lb_ref(handler);
4176 int lb_delete_all(void)
4180 struct livebox *handler;
4182 dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
4183 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
4184 lb_unref(handler, 1);
4187 return LB_STATUS_SUCCESS;
4190 int lb_set_content(struct livebox_common *common, const char *content)
4195 pc = strdup(content);
4197 ErrPrint("heap: %s [%s]\n", strerror(errno), content);
4198 return LB_STATUS_ERROR_MEMORY;
4202 free(common->content);
4203 common->content = pc;
4204 return LB_STATUS_SUCCESS;
4207 int lb_set_title(struct livebox_common *common, const char *title)
4214 ErrPrint("heap: %s [%s]\n", strerror(errno), title);
4215 return LB_STATUS_ERROR_MEMORY;
4219 free(common->title);
4221 return LB_STATUS_SUCCESS;
4224 void lb_set_size_list(struct livebox_common *common, int size_list)
4226 common->lb.size_list = size_list;
4229 void lb_set_auto_launch(struct livebox_common *common, const char *auto_launch)
4233 if (!auto_launch || !strlen(auto_launch)) {
4237 pa = strdup(auto_launch);
4239 ErrPrint("heap: %s, [%s]\n", strerror(errno), auto_launch);
4243 free(common->lb.auto_launch);
4244 common->lb.auto_launch = pa;
4247 void lb_set_priority(struct livebox_common *common, double priority)
4249 common->lb.priority = priority;
4252 void lb_set_id(struct livebox_common *common, const char *id)
4259 ErrPrint("heap: %s [%s]\n", strerror(errno), pi);
4268 void lb_set_filename(struct livebox_common *common, const char *filename)
4270 if (common->filename) {
4271 if (common->lb.type == _LB_TYPE_FILE || common->lb.type == _LB_TYPE_TEXT) {
4272 if (common->filename[0] && unlink(common->filename) < 0) {
4273 ErrPrint("unlink: %s (%s)\n", strerror(errno), common->filename);
4277 free(common->filename);
4280 common->filename = strdup(filename);
4281 if (!common->filename) {
4282 ErrPrint("Heap: %s\n", strerror(errno));
4286 void lb_set_alt_info(struct livebox_common *common, const char *icon, const char *name)
4291 if (icon && strlen(icon)) {
4292 _icon = strdup(icon);
4294 ErrPrint("Heap: %s\n", strerror(errno));
4298 if (name && strlen(name)) {
4299 _name = strdup(name);
4301 ErrPrint("Heap: %s\n", strerror(errno));
4305 free(common->alt.icon);
4306 common->alt.icon = _icon;
4308 free(common->alt.name);
4309 common->alt.name = _name;
4312 int lb_set_lb_fb(struct livebox_common *common, const char *filename)
4317 return LB_STATUS_ERROR_INVALID;
4321 if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
4322 return LB_STATUS_SUCCESS;
4325 common->lb.fb = NULL;
4327 if (!filename || filename[0] == '\0') {
4331 return LB_STATUS_SUCCESS;
4334 common->lb.fb = fb_create(filename, common->lb.width, common->lb.height);
4335 if (!common->lb.fb) {
4336 ErrPrint("Faield to create a FB\n");
4340 return LB_STATUS_ERROR_FAULT;
4347 return LB_STATUS_SUCCESS;
4350 int lb_set_pd_fb(struct livebox_common *common, const char *filename)
4354 if (!common || common->state != CREATE) {
4355 return LB_STATUS_ERROR_INVALID;
4359 if (fb && !strcmp(fb_id(fb), filename)) {
4360 /* BUFFER is not changed, just update the content */
4361 return LB_STATUS_ERROR_EXIST;
4363 common->pd.fb = NULL;
4365 if (!filename || filename[0] == '\0') {
4369 return LB_STATUS_SUCCESS;
4372 common->pd.fb = fb_create(filename, common->pd.width, common->pd.height);
4373 if (!common->pd.fb) {
4374 ErrPrint("Failed to create a FB\n");
4378 return LB_STATUS_ERROR_FAULT;
4384 return LB_STATUS_SUCCESS;
4387 struct fb_info *lb_get_lb_fb(struct livebox_common *common)
4389 return common->lb.fb;
4392 struct fb_info *lb_get_pd_fb(struct livebox_common *common)
4394 return common->pd.fb;
4397 void lb_set_user(struct livebox_common *common, int user)
4399 common->is_user = user;
4402 void lb_set_pinup(struct livebox_common *common, int pinup_supported)
4404 common->lb.pinup_supported = pinup_supported;
4407 void lb_set_text_lb(struct livebox_common *common)
4409 common->lb.type = _LB_TYPE_TEXT;
4412 void lb_set_text_pd(struct livebox_common *common)
4414 common->pd.type = _PD_TYPE_TEXT;
4417 int lb_text_lb(struct livebox_common *common)
4419 return common->lb.type == _LB_TYPE_TEXT;
4422 int lb_text_pd(struct livebox_common *common)
4424 return common->pd.type == _PD_TYPE_TEXT;
4427 void lb_set_period(struct livebox_common *common, double period)
4429 common->lb.period = period;
4432 struct livebox *lb_ref(struct livebox *handler)
4442 struct livebox *lb_unref(struct livebox *handler, int destroy_common)
4449 if (handler->refcnt > 0) {
4453 if (handler->cbs.created.cb) {
4454 handler->cbs.created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.created.data);
4455 handler->cbs.created.cb = NULL;
4456 handler->cbs.created.data = NULL;
4459 if (handler->cbs.deleted.cb) {
4460 handler->cbs.deleted.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.deleted.data);
4461 handler->cbs.deleted.cb = NULL;
4462 handler->cbs.deleted.data = NULL;
4465 if (handler->cbs.pinup.cb) {
4466 handler->cbs.pinup.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pinup.data);
4467 handler->cbs.pinup.cb = NULL;
4468 handler->cbs.pinup.data = NULL;
4471 if (handler->cbs.group_changed.cb) {
4472 handler->cbs.group_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.group_changed.data);
4473 handler->cbs.group_changed.cb = NULL;
4474 handler->cbs.group_changed.data = NULL;
4477 if (handler->cbs.period_changed.cb) {
4478 handler->cbs.period_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.period_changed.data);
4479 handler->cbs.period_changed.cb = NULL;
4480 handler->cbs.period_changed.data = NULL;
4483 if (handler->cbs.size_changed.cb) {
4484 handler->cbs.size_changed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.size_changed.data);
4485 handler->cbs.size_changed.cb = NULL;
4486 handler->cbs.size_changed.data = NULL;
4489 if (handler->cbs.pd_created.cb) {
4490 handler->cbs.pd_created.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_created.data);
4491 handler->cbs.pd_created.cb = NULL;
4492 handler->cbs.pd_created.data = NULL;
4495 if (handler->cbs.pd_destroyed.cb) {
4496 handler->cbs.pd_destroyed.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.pd_destroyed.data);
4497 handler->cbs.pd_destroyed.cb = NULL;
4498 handler->cbs.pd_destroyed.data = NULL;
4501 if (handler->cbs.update_mode.cb) {
4502 handler->cbs.update_mode.cb(handler, LB_STATUS_ERROR_FAULT, handler->cbs.update_mode.data);
4503 handler->cbs.update_mode.cb = NULL;
4504 handler->cbs.update_mode.data = NULL;
4507 if (handler->cbs.access_event.cb) {
4508 handler->cbs.access_event.cb(handler, LB_ACCESS_STATUS_ERROR, handler->cbs.access_event.data);
4509 handler->cbs.access_event.cb = NULL;
4510 handler->cbs.access_event.data = NULL;
4513 if (handler->cbs.key_event.cb) {
4514 handler->cbs.key_event.cb(handler, LB_KEY_STATUS_ERROR, handler->cbs.key_event.data);
4515 handler->cbs.key_event.cb = NULL;
4516 handler->cbs.key_event.data = NULL;
4519 dlist_remove_data(s_info.livebox_list, handler);
4521 handler->state = DESTROYED;
4522 if (lb_common_unref(handler->common, handler) == 0) {
4523 if (destroy_common) {
4526 * Lock file should be deleted after all callbacks are processed.
4528 lb_destroy_lock_file(handler->common, 0);
4529 lb_destroy_common_handle(handler->common);
4533 DbgPrint("Handler is released\n");
4537 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
4539 struct packet *packet;
4540 struct cb_info *cbinfo;
4543 if (handler->common->request.deleted) {
4544 ErrPrint("Already in-progress\n");
4546 cb(handler, LB_STATUS_SUCCESS, data);
4548 return LB_STATUS_ERROR_BUSY;
4552 cb = default_delete_cb;
4555 packet = packet_create("delete", "ssid", handler->common->pkgname, handler->common->id, type, handler->common->timestamp);
4557 ErrPrint("Failed to build a param\n");
4559 cb(handler, LB_STATUS_ERROR_FAULT, data);
4562 return LB_STATUS_ERROR_FAULT;
4565 cbinfo = create_cb_info(cb, data);
4567 packet_destroy(packet);
4568 ErrPrint("Failed to create cbinfo\n");
4570 cb(handler, LB_STATUS_ERROR_FAULT, data);
4573 return LB_STATUS_ERROR_FAULT;
4576 ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
4579 * Packet is destroyed by master_rpc_async_request.
4581 destroy_cb_info(cbinfo);
4584 cb(handler, LB_STATUS_ERROR_FAULT, data);
4587 handler->common->request.deleted = 1;
4593 EAPI int livebox_client_paused(void)
4595 struct packet *packet;
4597 packet = packet_create_noack("client_paused", "d", util_timestamp());
4599 ErrPrint("Failed to create a pause packet\n");
4600 return LB_STATUS_ERROR_FAULT;
4603 return master_rpc_request_only(NULL, packet);
4606 EAPI int livebox_client_resumed(void)
4608 struct packet *packet;
4610 packet = packet_create_noack("client_resumed", "d", util_timestamp());
4612 ErrPrint("Failed to create a resume packet\n");
4613 return LB_STATUS_ERROR_FAULT;
4616 return master_rpc_request_only(NULL, packet);
4619 EAPI int livebox_sync_lb_fb(struct livebox *handler)
4621 if (!handler || handler->state != CREATE) {
4622 ErrPrint("Invalid handle\n");
4623 return LB_STATUS_ERROR_INVALID;
4626 if (!handler->common || handler->common->state != CREATE) {
4627 ErrPrint("Invalid handle\n");
4628 return LB_STATUS_ERROR_INVALID;
4631 if (!handler->common->id) {
4632 return LB_STATUS_ERROR_INVALID;
4635 return lb_sync_lb_fb(handler->common);
4638 int lb_sync_lb_fb(struct livebox_common *common)
4642 if (fb_type(lb_get_lb_fb(common)) == BUFFER_TYPE_FILE && common->lb.lock_fd >= 0) {
4643 (void)do_fb_lock(common->lb.lock_fd);
4644 ret = fb_sync(lb_get_lb_fb(common));
4645 (void)do_fb_unlock(common->lb.lock_fd);
4647 ret = fb_sync(lb_get_lb_fb(common));
4653 int lb_sync_pd_fb(struct livebox_common *common)
4657 if (fb_type(lb_get_pd_fb(common)) == BUFFER_TYPE_FILE && common->pd.lock_fd >= 0) {
4658 (void)do_fb_lock(common->pd.lock_fd);
4659 ret = fb_sync(lb_get_pd_fb(common));
4660 (void)do_fb_unlock(common->pd.lock_fd);
4662 ret = fb_sync(lb_get_pd_fb(common));
4668 EAPI int livebox_sync_pd_fb(struct livebox *handler)
4670 if (!handler || handler->state != CREATE) {
4671 ErrPrint("Invalid handle\n");
4672 return LB_STATUS_ERROR_INVALID;
4675 if (!handler->common || handler->common->state != CREATE) {
4676 ErrPrint("Invalid handle\n");
4677 return LB_STATUS_ERROR_INVALID;
4680 if (!handler->common->id) {
4681 ErrPrint("Invalid handle\n");
4682 return LB_STATUS_ERROR_INVALID;
4685 return lb_sync_pd_fb(handler->common);
4688 EAPI const char *livebox_alt_icon(struct livebox *handler)
4690 if (!handler || handler->state != CREATE) {
4691 ErrPrint("Handler is not valid[%p]\n", handler);
4695 if (!handler->common || handler->common->state != CREATE) {
4696 ErrPrint("Handler is not valid\n");
4700 return handler->common->alt.icon;
4703 EAPI const char *livebox_alt_name(struct livebox *handler)
4705 if (!handler || handler->state != CREATE) {
4706 ErrPrint("Handler is not valid[%p]\n", handler);
4710 if (!handler->common || handler->common->state != CREATE) {
4711 ErrPrint("Handler is not valid\n");
4715 return handler->common->alt.name;
4718 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
4720 int ret = LB_STATUS_SUCCESS;
4723 if (!handler || handler->state != CREATE) {
4724 ErrPrint("Handler is not valid[%p]\n", handler);
4725 return LB_STATUS_ERROR_INVALID;
4728 if (!handler->common || handler->common->state != CREATE) {
4729 ErrPrint("Handler is not valid\n");
4730 return LB_STATUS_ERROR_INVALID;
4733 if (!handler->common->id) {
4734 ErrPrint("Handler is not valid[%p]\n", handler);
4735 return LB_STATUS_ERROR_INVALID;
4739 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4740 DbgPrint("Lock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4741 return LB_STATUS_ERROR_INVALID;
4744 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4745 return LB_STATUS_SUCCESS;
4748 fd = handler->common->pd.lock_fd;
4750 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4751 DbgPrint("Lock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4752 return LB_STATUS_ERROR_INVALID;
4755 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4756 return LB_STATUS_SUCCESS;
4759 fd = handler->common->lb.lock_fd;
4762 ret = do_fb_lock(fd);
4764 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4767 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
4769 int ret = LB_STATUS_SUCCESS;
4772 if (!handler || handler->state != CREATE) {
4773 ErrPrint("Invalid handle\n");
4774 return LB_STATUS_ERROR_INVALID;
4777 if (!handler->common || handler->common->state != CREATE) {
4778 ErrPrint("Invalid handle\n");
4779 return LB_STATUS_ERROR_INVALID;
4782 if (!handler->common->id) {
4783 ErrPrint("Handler is not valid[%p]\n", handler);
4784 return LB_STATUS_ERROR_INVALID;
4788 if (!handler->common->pd.lock || handler->common->pd.lock_fd < 0) {
4789 DbgPrint("Unlock: %s (%d)\n", handler->common->pd.lock, handler->common->pd.lock_fd);
4790 return LB_STATUS_ERROR_INVALID;
4793 if (fb_type(lb_get_pd_fb(handler->common)) == BUFFER_TYPE_FILE) {
4794 return LB_STATUS_SUCCESS;
4797 fd = handler->common->pd.lock_fd;
4799 if (!handler->common->lb.lock || handler->common->lb.lock_fd < 0) {
4800 DbgPrint("Unlock: %s (%d)\n", handler->common->lb.lock, handler->common->lb.lock_fd);
4801 return LB_STATUS_ERROR_INVALID;
4804 if (fb_type(lb_get_lb_fb(handler->common)) == BUFFER_TYPE_FILE) {
4805 return LB_STATUS_SUCCESS;
4808 fd = handler->common->lb.lock_fd;
4811 ret = do_fb_unlock(fd);
4813 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
4816 EAPI int livebox_set_option(enum livebox_option_type option, int state)
4818 int ret = LB_STATUS_SUCCESS;
4821 case LB_OPTION_MANUAL_SYNC:
4822 conf_set_manual_sync(state);
4824 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4825 conf_set_frame_drop_for_resizing(state);
4827 case LB_OPTION_SHARED_CONTENT:
4828 conf_set_shared_content(state);
4831 ret = LB_STATUS_ERROR_INVALID;
4838 EAPI int livebox_option(enum livebox_option_type option)
4843 case LB_OPTION_MANUAL_SYNC:
4844 ret = conf_manual_sync();
4846 case LB_OPTION_FRAME_DROP_FOR_RESIZE:
4847 ret = conf_frame_drop_for_resizing();
4849 case LB_OPTION_SHARED_CONTENT:
4850 ret = conf_shared_content();
4853 ret = LB_STATUS_ERROR_INVALID;
4860 EAPI int livebox_set_auto_launch_handler(int (*launch_handler)(struct livebox *handler, const char *appid, void *data), void *data)
4862 s_info.launch.handler = launch_handler;
4863 s_info.launch.data = data;
4865 return LB_STATUS_SUCCESS;