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>
30 #include <com-core_packet.h>
32 #include <livebox-service.h>
33 #include <livebox-errno.h>
38 #include "livebox_internal.h"
41 #include "master_rpc.h"
45 #define EAPI __attribute__((visibility("default")))
46 #define MINIMUM_EVENT s_info.event_filter
53 struct dlist *livebox_list;
54 struct dlist *event_list;
55 struct dlist *fault_list;
57 int prevent_overwrite;
64 .prevent_overwrite = 0,
65 .event_filter = 0.01f,
74 int (*handler)(struct livebox *handler, enum livebox_event_type event, void *data);
79 int (*handler)(enum livebox_fault_type event, const char *pkgname, const char *filename, const char *func, void *data);
83 static inline void default_create_cb(struct livebox *handler, int ret, void *data)
85 DbgPrint("Default created event handler: %d\n", ret);
88 static inline void default_delete_cb(struct livebox *handler, int ret, void *data)
90 DbgPrint("Default deleted event handler: %d\n", ret);
93 static inline void default_pinup_cb(struct livebox *handler, int ret, void *data)
95 DbgPrint("Default pinup event handler: %d\n", ret);
98 static inline void default_group_changed_cb(struct livebox *handler, int ret, void *data)
100 DbgPrint("Default group changed event handler: %d\n", ret);
103 static inline void default_period_changed_cb(struct livebox *handler, int ret, void *data)
105 DbgPrint("Default period changed event handler: %d\n", ret);
108 static inline void default_pd_created_cb(struct livebox *handler, int ret, void *data)
110 DbgPrint("Default PD created event handler: %d\n", ret);
113 static inline void default_pd_destroyed_cb(struct livebox *handler, int ret, void *data)
115 DbgPrint("Default PD destroyed event handler: %d\n", ret);
118 static inline void default_lb_size_changed_cb(struct livebox *handler, int ret, void *data)
120 DbgPrint("Default LB size changed event handler: %d\n", ret);
123 static inline void default_update_mode_cb(struct livebox *handler, int ret, void *data)
125 DbgPrint("Default update mode set event handler: %d\n", ret);
128 static inline void default_access_event_cb(struct livebox *handler, int ret, void *data)
130 DbgPrint("Default access event handler: %d\n", ret);
133 static inline void default_key_event_cb(struct livebox *handler, int ret, void *data)
135 DbgPrint("Default key event handler: %d\n", ret);
138 static inline __attribute__((always_inline)) struct cb_info *create_cb_info(ret_cb_t cb, void *data)
140 struct cb_info *info;
142 info = malloc(sizeof(*info));
144 ErrPrint("Heap: %s\n", strerror(errno));
153 static inline void destroy_cb_info(struct cb_info *info)
158 static int do_fb_lock(int fd)
163 flock.l_type = F_RDLCK;
164 flock.l_whence = SEEK_SET;
167 flock.l_pid = getpid();
170 ret = fcntl(fd, F_SETLKW, &flock);
173 ErrPrint("fcntl: %s\n", strerror(errno));
175 } while (ret == EINTR);
180 static int do_fb_unlock(int fd)
185 flock.l_type = F_UNLCK;
186 flock.l_whence = SEEK_SET;
189 flock.l_pid = getpid();
192 ret = fcntl(fd, F_SETLKW, &flock);
195 ErrPrint("fcntl: %s\n", strerror(errno));
197 } while (ret == EINTR);
202 int lb_destroy_lock_file(struct livebox *info, int is_pd)
205 if (!info->pd.lock) {
209 if (close(info->pd.lock_fd) < 0) {
210 ErrPrint("close: %s\n", strerror(errno));
212 info->pd.lock_fd = -1;
214 if (unlink(info->pd.lock) < 0) {
215 ErrPrint("unlink: %s\n", strerror(errno));
219 info->pd.lock = NULL;
221 if (!info->lb.lock) {
225 if (close(info->lb.lock_fd) < 0) {
226 ErrPrint("close: %s\n", strerror(errno));
228 info->lb.lock_fd = -1;
230 if (unlink(info->lb.lock) < 0) {
231 ErrPrint("unlink: %s\n", strerror(errno));
235 info->lb.lock = NULL;
241 int lb_create_lock_file(struct livebox *info, int is_pd)
246 len = strlen(info->id);
247 file = malloc(len + 20);
249 ErrPrint("Heap: %s\n", strerror(errno));
253 snprintf(file, len + 20, "%s.%s.lck", util_uri_to_path(info->id), is_pd ? "pd" : "lb");
256 info->pd.lock_fd = open(file, O_RDONLY);
257 if (info->pd.lock_fd < 0) {
258 ErrPrint("open: %s\n", strerror(errno));
263 info->pd.lock = file;
265 info->lb.lock_fd = open(file, O_RDONLY);
266 if (info->lb.lock_fd < 0) {
267 ErrPrint("open: %s\n", strerror(errno));
272 info->lb.lock = file;
278 static void update_mode_cb(struct livebox *handler, const struct packet *result, void *data)
283 ret = LB_STATUS_ERROR_FAULT;
285 } else if (packet_get(result, "i", &ret) != 1) {
286 ErrPrint("Invalid argument\n");
287 ret = LB_STATUS_ERROR_INVALID;
292 ErrPrint("Resize request is failed: %d\n", ret);
299 handler->update_mode_cb(handler, ret, handler->update_mode_cbdata);
300 handler->update_mode_cb = NULL;
301 handler->update_mode_cbdata = NULL;
305 static void resize_cb(struct livebox *handler, const struct packet *result, void *data)
310 ret = LB_STATUS_ERROR_FAULT;
312 } else if (packet_get(result, "i", &ret) != 1) {
313 ErrPrint("Invalid argument\n");
314 ret = LB_STATUS_ERROR_INVALID;
320 * In case of resize request,
321 * The livebox handler will not have resized value right after this callback,
322 * It can only get the new size when it makes updates.
324 * So the user can only get the resized value(result) from the first update event
325 * after this request.
328 ErrPrint("Resize request is failed: %d\n", ret);
335 handler->size_changed_cb(handler, ret, handler->size_cbdata);
336 handler->size_changed_cb = NULL;
337 handler->size_cbdata = NULL;
340 static void text_signal_cb(struct livebox *handler, const struct packet *result, void *data)
344 struct cb_info *info = data;
349 destroy_cb_info(info);
352 ret = LB_STATUS_ERROR_FAULT;
353 } else if (packet_get(result, "i", &ret) != 1) {
354 ErrPrint("Invalid argument\n");
355 ret = LB_STATUS_ERROR_INVALID;
359 cb(handler, ret, cbdata);
364 static void set_group_ret_cb(struct livebox *handler, const struct packet *result, void *data)
369 ret = LB_STATUS_ERROR_FAULT;
371 } else if (packet_get(result, "i", &ret) != 1) {
372 ErrPrint("Invalid argument\n");
373 ret = LB_STATUS_ERROR_INVALID;
384 handler->group_changed_cb(handler, ret, handler->group_cbdata);
385 handler->group_changed_cb = NULL;
386 handler->group_cbdata = NULL;
389 static void period_ret_cb(struct livebox *handler, const struct packet *result, void *data)
394 ret = LB_STATUS_ERROR_FAULT;
396 } else if (packet_get(result, "i", &ret) != 1) {
397 ErrPrint("Invalid argument\n");
398 ret = LB_STATUS_ERROR_INVALID;
409 handler->period_changed_cb(handler, ret, handler->period_cbdata);
410 handler->period_changed_cb = NULL;
411 handler->period_cbdata = NULL;
414 static void del_ret_cb(struct livebox *handler, const struct packet *result, void *data)
416 struct cb_info *info = data;
423 destroy_cb_info(info);
426 ErrPrint("Connection lost?\n");
427 ret = LB_STATUS_ERROR_FAULT;
428 } else if (packet_get(result, "i", &ret) != 1) {
429 ErrPrint("Invalid argument\n");
430 ret = LB_STATUS_ERROR_INVALID;
434 handler->deleted_cb = cb;
435 handler->deleted_cbdata = cbdata;
437 cb(handler, ret, cbdata);
442 * Do not call the deleted callback from here.
443 * master will send the "deleted" event.
444 * Then invoke this callback.
446 * if (handler->deleted_cb)
447 * handler->deleted_cb(handler, ret, handler->deleted_cbdata);
451 static void new_ret_cb(struct livebox *handler, const struct packet *result, void *data)
454 struct cb_info *info = data;
460 destroy_cb_info(info);
463 ret = LB_STATUS_ERROR_FAULT;
464 } else if (packet_get(result, "i", &ret) != 1) {
465 ret = LB_STATUS_ERROR_INVALID;
469 handler->created_cb = cb;
470 handler->created_cbdata = cbdata;
474 * Don't go anymore ;)
480 * It means the current instance is not created,
481 * so user has to know about this.
482 * notice it to user using "deleted" event.
484 cb(handler, ret, cbdata);
490 static void pd_create_cb(struct livebox *handler, const struct packet *result, void *data)
495 ret = LB_STATUS_ERROR_FAULT;
497 } else if (packet_get(result, "i", &ret) != 1) {
498 ret = LB_STATUS_ERROR_INVALID;
503 ErrPrint("Failed to create a PD[%d]\n", ret);
510 handler->pd_created_cb(handler, ret, handler->pd_created_cbdata);
511 handler->pd_created_cb = NULL;
512 handler->pd_created_cbdata = NULL;
515 static void activated_cb(struct livebox *handler, const struct packet *result, void *data)
518 struct cb_info *info = data;
521 const char *pkgname = "";
525 destroy_cb_info(info);
528 ret = LB_STATUS_ERROR_FAULT;
529 } else if (packet_get(result, "is", &ret, &pkgname) != 2) {
530 ret = LB_STATUS_ERROR_INVALID;
534 cb(handler, ret, cbdata);
538 static void pd_destroy_cb(struct livebox *handler, const struct packet *result, void *data)
543 struct cb_info *info = data;
547 destroy_cb_info(info);
550 ErrPrint("Result is NIL (may connection lost)\n");
551 ret = LB_STATUS_ERROR_FAULT;
552 } else if (packet_get(result, "i", &ret) != 1) {
553 ErrPrint("Invalid parameter\n");
554 ret = LB_STATUS_ERROR_INVALID;
558 handler->pd_destroyed_cb = cb;
559 handler->pd_destroyed_cbdata = cbdata;
561 handler->is_pd_created = 0;
562 cb(handler, ret, cbdata);
566 static void delete_cluster_cb(struct livebox *handler, const struct packet *result, void *data)
568 struct cb_info *info = data;
575 destroy_cb_info(info);
578 ret = LB_STATUS_ERROR_FAULT;
579 } else if (packet_get(result, "i", &ret) != 1) {
580 ret = LB_STATUS_ERROR_INVALID;
584 cb(handler, ret, cbdata);
588 static void delete_category_cb(struct livebox *handler, const struct packet *result, void *data)
590 struct cb_info *info = data;
597 destroy_cb_info(info);
600 ret = LB_STATUS_ERROR_FAULT;
601 } else if (packet_get(result, "i", &ret) != 1) {
602 ret = LB_STATUS_ERROR_INVALID;
606 cb(handler, ret, cbdata);
610 static void lb_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
613 int ret = LB_STATUS_ERROR_INVALID;
616 struct cb_info *info = data;
620 destroy_cb_info(info);
623 pixmap = 0; /* PIXMAP 0 means error */
624 } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
628 if (ret == LB_STATUS_ERROR_BUSY) {
629 ret = livebox_acquire_lb_pixmap(handler, cb, cbdata);
630 DbgPrint("Busy, Try again: %d\n", ret);
634 cb(handler, pixmap, cbdata);
639 static void pd_pixmap_acquired_cb(struct livebox *handler, const struct packet *result, void *data)
645 struct cb_info *info = data;
649 destroy_cb_info(info);
652 pixmap = 0; /* PIXMAP 0 means error */
653 ret = LB_STATUS_ERROR_FAULT;
654 } else if (packet_get(result, "ii", &pixmap, &ret) != 2) {
656 ret = LB_STATUS_ERROR_INVALID;
659 if (ret == LB_STATUS_ERROR_BUSY) {
660 ret = livebox_acquire_pd_pixmap(handler, cb, cbdata);
661 DbgPrint("Busy, Try again: %d\n", ret);
665 DbgPrint("ret: %d, pixmap: %d\n", ret, pixmap);
666 cb(handler, pixmap, cbdata);
671 static void pinup_done_cb(struct livebox *handler, const struct packet *result, void *data)
676 ret = LB_STATUS_ERROR_FAULT;
678 } else if (packet_get(result, "i", &ret) != 1) {
689 handler->pinup_cb(handler, ret, handler->pinup_cbdata);
690 handler->pinup_cb = NULL;
691 handler->pinup_cbdata = NULL;
694 static void key_ret_cb(struct livebox *handler, const struct packet *result, void *data)
699 ret = LB_STATUS_ERROR_FAULT;
703 if (packet_get(result, "i", &ret) != 1) {
704 ret = LB_STATUS_ERROR_INVALID;
708 if (ret != LB_STATUS_SUCCESS) {
714 handler->key_event_cb(handler, ret, handler->key_event_cbdata);
715 handler->key_event_cb = NULL;
716 handler->key_event_cbdata = NULL;
720 static void access_ret_cb(struct livebox *handler, const struct packet *result, void *data)
725 ret = LB_STATUS_ERROR_FAULT;
729 if (packet_get(result, "i", &ret) != 1) {
730 ret = LB_STATUS_ERROR_INVALID;
734 if (ret != LB_STATUS_SUCCESS) {
741 handler->access_event_cb(handler, ret, handler->access_event_cbdata);
742 handler->access_event_cb = NULL;
743 handler->access_event_cbdata = NULL;
747 static int send_access_event(struct livebox *handler, const char *event, int x, int y)
749 struct packet *packet;
752 timestamp = util_timestamp();
754 packet = packet_create(event, "ssdii", handler->pkgname, handler->id, timestamp, x, y);
756 ErrPrint("Failed to build packet\n");
757 return LB_STATUS_ERROR_FAULT;
760 return master_rpc_async_request(handler, packet, 0, access_ret_cb, NULL);
763 static int send_key_event(struct livebox *handler, const char *event, unsigned int keycode)
765 struct packet *packet;
768 timestamp = util_timestamp();
769 packet = packet_create(event, "ssdi", handler->pkgname, handler->id, timestamp, keycode);
771 ErrPrint("Failed to build packet\n");
772 return LB_STATUS_ERROR_FAULT;
775 return master_rpc_async_request(handler, packet, 0, key_ret_cb, NULL);
778 static int send_mouse_event(struct livebox *handler, const char *event, int x, int y)
780 struct packet *packet;
783 timestamp = util_timestamp();
784 packet = packet_create_noack(event, "ssdii", handler->pkgname, handler->id, timestamp, x, y);
786 ErrPrint("Failed to build param\n");
787 return LB_STATUS_ERROR_FAULT;
790 return master_rpc_request_only(handler, packet);
793 static void initialize_livebox(void *disp, int use_thread)
796 char filename[BUFSIZ];
797 snprintf(filename, sizeof(filename), "/tmp/%d.box.log", getpid());
798 __file_log_fp = fopen(filename, "w+t");
799 if (!__file_log_fp) {
800 __file_log_fp = fdopen(1, "w+t");
803 livebox_service_init();
806 client_init(use_thread);
811 EAPI int livebox_init_with_options(void *disp, int prevent_overwrite, double event_filter, int use_thread)
813 if (s_info.init_count > 0) {
815 return LB_STATUS_SUCCESS;
820 * Some application doesn't want to use the environment value.
821 * So set them using arguments.
823 s_info.prevent_overwrite = prevent_overwrite;
824 MINIMUM_EVENT = event_filter;
826 initialize_livebox(disp, use_thread);
827 return LB_STATUS_SUCCESS;
830 EAPI int livebox_init(void *disp)
834 if (s_info.init_count > 0) {
836 return LB_STATUS_SUCCESS;
839 env = getenv("PROVIDER_DISABLE_PREVENT_OVERWRITE");
840 if (env && !strcasecmp(env, "true")) {
841 s_info.prevent_overwrite = 1;
844 env = getenv("PROVIDER_EVENT_FILTER");
846 sscanf(env, "%lf", &MINIMUM_EVENT);
849 initialize_livebox(disp, 0);
850 return LB_STATUS_SUCCESS;
853 EAPI int livebox_fini(void)
855 if (s_info.init_count <= 0) {
856 ErrPrint("Doesn't initialized\n");
857 return LB_STATUS_ERROR_INVALID;
861 if (s_info.init_count > 0) {
862 ErrPrint("init count : %d\n", s_info.init_count);
863 return LB_STATUS_SUCCESS;
868 livebox_service_fini();
869 return LB_STATUS_SUCCESS;
872 static inline char *lb_pkgname(const char *pkgname)
876 lb = livebox_service_pkgname(pkgname);
878 if (util_validate_livebox_package(pkgname) == 0) {
879 return strdup(pkgname);
887 * Just wrapping the livebox_add_with_size function.
889 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)
891 return livebox_add_with_size(pkgname, content, cluster, category, period, LB_SIZE_TYPE_UNKNOWN, cb, data);
894 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)
896 struct livebox *handler;
897 struct packet *packet;
901 struct cb_info *cbinfo;
903 if (!pkgname || !cluster || !category) {
904 ErrPrint("Invalid arguments: pkgname[%p], cluster[%p], category[%p]\n",
905 pkgname, cluster, category);
909 if (type != LB_SIZE_TYPE_UNKNOWN) {
910 (void)livebox_service_get_size(type, &width, &height);
913 handler = calloc(1, sizeof(*handler));
915 ErrPrint("Error: %s\n", strerror(errno));
919 handler->pkgname = lb_pkgname(pkgname);
920 if (!handler->pkgname) {
925 if (livebox_service_is_enabled(handler->pkgname) == 0) {
926 DbgPrint("Livebox [%s](%s) is disabled package\n", handler->pkgname, pkgname);
927 free(handler->pkgname);
932 if (content && strlen(content)) {
933 handler->content = strdup(content);
934 if (!handler->content) {
935 ErrPrint("Error: %s\n", strerror(errno));
936 free(handler->pkgname);
941 handler->content = livebox_service_content(handler->pkgname);
944 handler->cluster = strdup(cluster);
945 if (!handler->cluster) {
946 ErrPrint("Error: %s\n", strerror(errno));
947 free(handler->content);
948 free(handler->pkgname);
953 handler->category = strdup(category);
954 if (!handler->category) {
955 ErrPrint("Error: %s\n", strerror(errno));
956 free(handler->cluster);
957 free(handler->content);
958 free(handler->pkgname);
964 cb = default_create_cb;
967 /* Data provider will set this */
968 handler->lb.type = _LB_TYPE_FILE;
969 handler->pd.type = _PD_TYPE_SCRIPT;
970 handler->lb.period = period;
972 /* Used for handling the mouse event on a box */
973 handler->lb.mouse_event = livebox_service_mouse_event(handler->pkgname);
975 /* Cluster infomration is not determined yet */
976 handler->nr_of_sizes = 0x01;
978 handler->timestamp = util_timestamp();
979 handler->is_user = 1;
980 handler->visible = LB_SHOW;
981 handler->delete_type = LB_DELETE_PERMANENTLY;
982 handler->pd.lock = NULL;
983 handler->pd.lock_fd = -1;
984 handler->lb.lock = NULL;
985 handler->lb.lock_fd = -1;
987 s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
989 packet = packet_create("new", "dssssdii", handler->timestamp, handler->pkgname, handler->content, cluster, category, period, width, height);
991 ErrPrint("Failed to create a new packet\n");
992 free(handler->category);
993 free(handler->cluster);
994 free(handler->content);
995 free(handler->pkgname);
1000 cbinfo = create_cb_info(cb, data);
1002 ErrPrint("Failed to create a cbinfo\n");
1003 packet_destroy(packet);
1004 free(handler->category);
1005 free(handler->cluster);
1006 free(handler->content);
1007 free(handler->pkgname);
1012 ret = master_rpc_async_request(handler, packet, 0, new_ret_cb, cbinfo);
1014 ErrPrint("Failed to send a new packet\n");
1015 destroy_cb_info(cbinfo);
1016 free(handler->category);
1017 free(handler->cluster);
1018 free(handler->content);
1019 free(handler->pkgname);
1024 handler->state = CREATE;
1025 return lb_ref(handler);
1028 EAPI double livebox_period(struct livebox *handler)
1030 if (!handler || handler->state != CREATE || !handler->id) {
1031 ErrPrint("Handler is not valid\n");
1035 return handler->lb.period;
1038 EAPI int livebox_set_period(struct livebox *handler, double period, ret_cb_t cb, void *data)
1040 struct packet *packet;
1043 if (!handler || handler->state != CREATE || !handler->id) {
1044 ErrPrint("Handler is not valid\n");
1045 return LB_STATUS_ERROR_INVALID;
1048 if (handler->period_changed_cb) {
1049 ErrPrint("Previous request for changing period is not finished\n");
1050 return LB_STATUS_ERROR_BUSY;
1053 if (!handler->is_user) {
1054 ErrPrint("CA Livebox is not able to change the period\n");
1055 return LB_STATUS_ERROR_PERMISSION;
1058 if (handler->lb.period == period) {
1059 DbgPrint("No changes\n");
1060 return LB_STATUS_ERROR_ALREADY;
1063 packet = packet_create("set_period", "ssd", handler->pkgname, handler->id, period);
1065 ErrPrint("Failed to build a packet %s\n", handler->pkgname);
1066 return LB_STATUS_ERROR_FAULT;
1070 cb = default_period_changed_cb;
1073 ret = master_rpc_async_request(handler, packet, 0, period_ret_cb, NULL);
1074 if (ret == LB_STATUS_SUCCESS) {
1075 handler->period_changed_cb = cb;
1076 handler->period_cbdata = data;
1082 EAPI int livebox_del_NEW(struct livebox *handler, int type, ret_cb_t cb, void *data)
1085 ErrPrint("Handler is NIL\n");
1086 return LB_STATUS_ERROR_INVALID;
1089 if (handler->state != CREATE) {
1090 ErrPrint("Handler is already deleted\n");
1091 return LB_STATUS_ERROR_INVALID;
1094 handler->state = DELETE;
1095 handler->delete_type = type;
1100 * The id is not determined yet.
1101 * It means a user didn't receive created event yet.
1102 * Then just stop to delete procedure from here.
1103 * Because the "created" event handler will release this.
1104 * By the way, if the user adds any callback for getting return status of this,
1108 cb(handler, 0, data);
1110 return LB_STATUS_SUCCESS;
1114 cb = default_delete_cb;
1117 return lb_send_delete(handler, type, cb, data);
1120 EAPI int livebox_del(struct livebox *handler, ret_cb_t cb, void *data)
1123 ErrPrint("Handler is NIL\n");
1124 return LB_STATUS_ERROR_INVALID;
1127 if (handler->state != CREATE) {
1128 ErrPrint("Handler is already deleted\n");
1129 return LB_STATUS_ERROR_INVALID;
1132 handler->state = DELETE;
1133 handler->delete_type = LB_DELETE_PERMANENTLY;
1138 * The id is not determined yet.
1139 * It means a user didn't receive created event yet.
1140 * Then just stop to delete procedure from here.
1141 * Because the "created" event handler will release this.
1142 * By the way, if the user adds any callback for getting return status of this,
1146 cb(handler, 0, data);
1148 return LB_STATUS_SUCCESS;
1152 cb = default_delete_cb;
1155 return lb_send_delete(handler, LB_DELETE_PERMANENTLY, cb, data);
1158 EAPI int livebox_set_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *), void *data)
1160 struct fault_info *info;
1163 return LB_STATUS_ERROR_INVALID;
1166 info = malloc(sizeof(*info));
1168 ErrPrint("Heap: %s\n", strerror(errno));
1169 return LB_STATUS_ERROR_MEMORY;
1173 info->user_data = data;
1175 s_info.fault_list = dlist_append(s_info.fault_list, info);
1176 return LB_STATUS_SUCCESS;
1179 EAPI void *livebox_unset_fault_handler(int (*cb)(enum livebox_fault_type, const char *, const char *, const char *, void *))
1181 struct fault_info *info;
1184 dlist_foreach(s_info.fault_list, l, info) {
1185 if (info->handler == cb) {
1188 s_info.fault_list = dlist_remove(s_info.fault_list, l);
1189 data = info->user_data;
1199 EAPI int livebox_set_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *), void *data)
1201 struct event_info *info;
1204 ErrPrint("Invalid argument cb is nil\n");
1205 return LB_STATUS_ERROR_INVALID;
1208 info = malloc(sizeof(*info));
1210 ErrPrint("Heap: %s\n", strerror(errno));
1211 return LB_STATUS_ERROR_MEMORY;
1215 info->user_data = data;
1217 s_info.event_list = dlist_append(s_info.event_list, info);
1218 return LB_STATUS_SUCCESS;
1221 EAPI void *livebox_unset_event_handler(int (*cb)(struct livebox *, enum livebox_event_type, void *))
1223 struct event_info *info;
1226 dlist_foreach(s_info.event_list, l, info) {
1227 if (info->handler == cb) {
1230 s_info.event_list = dlist_remove(s_info.event_list, l);
1231 data = info->user_data;
1241 EAPI int livebox_set_update_mode(struct livebox *handler, int active_update, ret_cb_t cb, void *data)
1243 struct packet *packet;
1247 ErrPrint("Handler is NIL\n");
1248 return LB_STATUS_ERROR_INVALID;
1251 if (handler->state != CREATE || !handler->id) {
1252 return LB_STATUS_ERROR_INVALID;
1255 if (handler->update_mode_cb) {
1256 ErrPrint("Previous update_mode cb is not finished yet\n");
1257 return LB_STATUS_ERROR_BUSY;
1260 if (handler->is_active_update == active_update) {
1261 return LB_STATUS_ERROR_ALREADY;
1264 if (!handler->is_user) {
1265 return LB_STATUS_ERROR_PERMISSION;
1268 packet = packet_create("update_mode", "ssi", handler->pkgname, handler->id, active_update);
1270 return LB_STATUS_ERROR_FAULT;
1274 cb = default_update_mode_cb;
1277 ret = master_rpc_async_request(handler, packet, 0, update_mode_cb, NULL);
1278 if (ret == LB_STATUS_SUCCESS) {
1279 handler->update_mode_cb = cb;
1280 handler->update_mode_cbdata = data;
1286 EAPI int livebox_is_active_update(struct livebox *handler)
1289 ErrPrint("Handler is NIL\n");
1290 return LB_STATUS_ERROR_INVALID;
1293 if (handler->state != CREATE || !handler->id) {
1294 return LB_STATUS_ERROR_INVALID;
1297 return handler->is_active_update;
1300 EAPI int livebox_resize(struct livebox *handler, int type, ret_cb_t cb, void *data)
1302 struct packet *packet;
1308 ErrPrint("Handler is NIL\n");
1309 return LB_STATUS_ERROR_INVALID;
1312 if (handler->state != CREATE || !handler->id) {
1313 ErrPrint("Handler is not valid\n");
1314 return LB_STATUS_ERROR_INVALID;
1317 if (handler->size_changed_cb) {
1318 ErrPrint("Previous resize request is not finished yet\n");
1319 return LB_STATUS_ERROR_BUSY;
1322 if (!handler->is_user) {
1323 ErrPrint("CA Livebox is not able to be resized\n");
1324 return LB_STATUS_ERROR_PERMISSION;
1327 if (livebox_service_get_size(type, &w, &h) != 0) {
1328 ErrPrint("Invalid size type\n");
1329 return LB_STATUS_ERROR_INVALID;
1332 if (handler->lb.width == w && handler->lb.height == h) {
1333 DbgPrint("No changes\n");
1334 return LB_STATUS_ERROR_ALREADY;
1337 packet = packet_create("resize", "ssii", handler->pkgname, handler->id, w, h);
1339 ErrPrint("Failed to build param\n");
1340 return LB_STATUS_ERROR_FAULT;
1344 cb = default_lb_size_changed_cb;
1347 ret = master_rpc_async_request(handler, packet, 0, resize_cb, NULL);
1348 if (ret == LB_STATUS_SUCCESS) {
1349 handler->size_changed_cb = cb;
1350 handler->size_cbdata = data;
1356 EAPI int livebox_click(struct livebox *handler, double x, double y)
1358 struct packet *packet;
1362 timestamp = util_timestamp();
1365 ErrPrint("Handler is NIL\n");
1366 return LB_STATUS_ERROR_INVALID;
1369 if (handler->state != CREATE || !handler->id) {
1370 ErrPrint("Handler is not valid\n");
1371 return LB_STATUS_ERROR_INVALID;
1374 if (handler->lb.auto_launch) {
1375 DbgPrint("AUTO_LAUNCH [%s]\n", handler->lb.auto_launch);
1376 if (aul_launch_app(handler->lb.auto_launch, NULL) < 0) {
1377 ErrPrint("Failed to launch app %s\n", handler->lb.auto_launch);
1381 packet = packet_create_noack("clicked", "sssddd", handler->pkgname, handler->id, "clicked", timestamp, x, y);
1383 ErrPrint("Failed to build param\n");
1384 return LB_STATUS_ERROR_FAULT;
1387 DbgPrint("CLICKED: %lf\n", timestamp);
1388 ret = master_rpc_request_only(handler, packet);
1390 if (!handler->lb.mouse_event && (handler->lb.type == _LB_TYPE_BUFFER || handler->lb.type == _LB_TYPE_SCRIPT)) {
1391 int ret; /* Shadow variable */
1392 ret = send_mouse_event(handler, "lb_mouse_down", x * handler->lb.width, y * handler->lb.height);
1394 ErrPrint("Failed to send Down: %d\n", ret);
1397 ret = send_mouse_event(handler, "lb_mouse_move", x * handler->lb.width, y * handler->lb.height);
1399 ErrPrint("Failed to send Move: %d\n", ret);
1402 ret = send_mouse_event(handler, "lb_mouse_up", x * handler->lb.width, y * handler->lb.height);
1404 ErrPrint("Failed to send Up: %d\n", ret);
1411 EAPI int livebox_has_pd(struct livebox *handler)
1414 ErrPrint("Handler is NIL\n");
1415 return LB_STATUS_ERROR_INVALID;
1418 if (handler->state != CREATE || !handler->id) {
1419 ErrPrint("Handler is not valid\n");
1420 return LB_STATUS_ERROR_INVALID;
1423 return !!handler->pd.data.fb;
1426 EAPI int livebox_pd_is_created(struct livebox *handler)
1429 ErrPrint("Handler is NIL\n");
1430 return LB_STATUS_ERROR_INVALID;
1433 if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
1434 ErrPrint("Handler is not valid\n");
1435 return LB_STATUS_ERROR_INVALID;
1438 return handler->is_pd_created;
1441 EAPI int livebox_create_pd(struct livebox *handler, ret_cb_t cb, void *data)
1443 return livebox_create_pd_with_position(handler, -1.0, -1.0, cb, data);
1446 EAPI int livebox_create_pd_with_position(struct livebox *handler, double x, double y, ret_cb_t cb, void *data)
1448 struct packet *packet;
1452 ErrPrint("Handler is NIL\n");
1453 return LB_STATUS_ERROR_INVALID;
1456 if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
1457 ErrPrint("Handler is not valid\n");
1458 return LB_STATUS_ERROR_INVALID;
1461 if (handler->is_pd_created == 1) {
1462 DbgPrint("PD already created\n");
1463 return LB_STATUS_SUCCESS;
1466 if (handler->pd_created_cb) {
1467 ErrPrint("Previous request is not completed yet\n");
1468 return LB_STATUS_ERROR_BUSY;
1471 packet = packet_create("create_pd", "ssdd", handler->pkgname, handler->id, x, y);
1473 ErrPrint("Failed to build param\n");
1474 return LB_STATUS_ERROR_FAULT;
1478 cb = default_pd_created_cb;
1481 DbgPrint("PERF_DBOX\n");
1482 ret = master_rpc_async_request(handler, packet, 0, pd_create_cb, NULL);
1483 if (ret == LB_STATUS_SUCCESS) {
1484 handler->pd_created_cb = cb;
1485 handler->pd_created_cbdata = data;
1491 EAPI int livebox_move_pd(struct livebox *handler, double x, double y)
1493 struct packet *packet;
1496 ErrPrint("Handler is NIL\n");
1497 return LB_STATUS_ERROR_INVALID;
1500 if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
1501 ErrPrint("Handler is not valid\n");
1502 return LB_STATUS_ERROR_INVALID;
1505 if (!handler->is_pd_created) {
1506 ErrPrint("PD is not created\n");
1507 return LB_STATUS_ERROR_INVALID;
1510 packet = packet_create_noack("pd_move", "ssdd", handler->pkgname, handler->id, x, y);
1512 ErrPrint("Failed to build param\n");
1513 return LB_STATUS_ERROR_FAULT;
1516 return master_rpc_request_only(handler, packet);
1519 EAPI int livebox_activate(const char *pkgname, ret_cb_t cb, void *data)
1521 struct packet *packet;
1522 struct cb_info *cbinfo;
1526 return LB_STATUS_ERROR_INVALID;
1529 packet = packet_create("activate_package", "s", pkgname);
1531 ErrPrint("Failed to build a param\n");
1532 return LB_STATUS_ERROR_FAULT;
1535 cbinfo = create_cb_info(cb, data);
1537 ErrPrint("Unable to create cbinfo\n");
1538 packet_destroy(packet);
1539 return LB_STATUS_ERROR_FAULT;
1542 ret = master_rpc_async_request(NULL, packet, 0, activated_cb, cbinfo);
1544 destroy_cb_info(cbinfo);
1550 EAPI int livebox_destroy_pd(struct livebox *handler, ret_cb_t cb, void *data)
1552 struct packet *packet;
1553 struct cb_info *cbinfo;
1557 ErrPrint("Handler is NIL\n");
1558 return LB_STATUS_ERROR_INVALID;
1561 if (handler->state != CREATE || !handler->pd.data.fb || !handler->id) {
1562 ErrPrint("Handler is not valid\n");
1563 return LB_STATUS_ERROR_INVALID;
1566 if (!handler->is_pd_created && !handler->pd_created_cb) {
1567 ErrPrint("PD is not created\n");
1568 return LB_STATUS_ERROR_INVALID;
1571 packet = packet_create("destroy_pd", "ss", handler->pkgname, handler->id);
1573 ErrPrint("Failed to build a param\n");
1574 return LB_STATUS_ERROR_FAULT;
1578 cb = default_pd_destroyed_cb;
1581 cbinfo = create_cb_info(cb, data);
1583 packet_destroy(packet);
1584 return LB_STATUS_ERROR_FAULT;
1587 ret = master_rpc_async_request(handler, packet, 0, pd_destroy_cb, cbinfo);
1589 destroy_cb_info(cbinfo);
1595 EAPI int livebox_access_event(struct livebox *handler, enum access_event_type type, double x, double y, ret_cb_t cb, void *data)
1599 char cmd[32] = { '\0', };
1604 ErrPrint("Handler is NIL\n");
1605 return LB_STATUS_ERROR_INVALID;
1608 if (handler->state != CREATE || !handler->id) {
1609 ErrPrint("Handler is not valid\n");
1610 return LB_STATUS_ERROR_INVALID;
1613 if (handler->access_event_cb) {
1614 ErrPrint("Previous access event is not yet done\n");
1615 return LB_STATUS_ERROR_BUSY;
1618 if (type & ACCESS_EVENT_PD_MASK) {
1619 if (!handler->is_pd_created) {
1620 ErrPrint("PD is not created\n");
1621 return LB_STATUS_ERROR_INVALID;
1625 w = handler->pd.width;
1626 h = handler->pd.height;
1627 } else if (type & ACCESS_EVENT_LB_MASK) {
1630 w = handler->lb.width;
1631 h = handler->lb.height;
1633 ErrPrint("Invalid event type\n");
1634 return LB_STATUS_ERROR_INVALID;
1637 switch (type & ~ACCESS_EVENT_PD_MASK) {
1638 case ACCESS_EVENT_HIGHLIGHT:
1639 strcpy(ptr, "_access_hl");
1641 case ACCESS_EVENT_HIGHLIGHT_NEXT:
1642 strcpy(ptr, "_access_hl_next");
1644 case ACCESS_EVENT_HIGHLIGHT_PREV:
1645 strcpy(ptr, "_access_hl_prev");
1647 case ACCESS_EVENT_ACTIVATE:
1648 strcpy(ptr, "_access_activate");
1650 case ACCESS_EVENT_ACTION_DOWN:
1651 strcpy(ptr, "_access_action_down");
1653 case ACCESS_EVENT_ACTION_UP:
1654 strcpy(ptr, "_access_action_up");
1656 case ACCESS_EVENT_UNHIGHLIGHT:
1657 strcpy(ptr, "_access_unhighlight");
1659 case ACCESS_EVENT_SCROLL_DOWN:
1660 strcpy(ptr, "_access_scroll_down");
1662 case ACCESS_EVENT_SCROLL_MOVE:
1663 strcpy(ptr, "_access_scroll_move");
1665 case ACCESS_EVENT_SCROLL_UP:
1666 strcpy(ptr, "_access_scroll_up");
1669 return LB_STATUS_ERROR_INVALID;
1673 cb = default_access_event_cb;
1676 ret = send_access_event(handler, cmd, x * w, y * h);
1677 if (ret == LB_STATUS_SUCCESS) {
1678 handler->access_event_cb = cb;
1679 handler->access_event_cbdata = data;
1685 EAPI int livebox_content_event(struct livebox *handler, enum content_event_type type, double x, double y)
1687 return livebox_mouse_event(handler, type, x, y);
1690 EAPI int livebox_mouse_event(struct livebox *handler, enum content_event_type type, double x, double y)
1694 char cmd[32] = { '\0', };
1698 ErrPrint("Handler is NIL\n");
1699 return LB_STATUS_ERROR_INVALID;
1702 if (handler->state != CREATE || !handler->id) {
1703 ErrPrint("Handler is not valid\n");
1704 return LB_STATUS_ERROR_INVALID;
1707 if (!(type & CONTENT_EVENT_MOUSE_MASK)) {
1708 ErrPrint("Invalid content event is used\n");
1709 return LB_STATUS_ERROR_INVALID;
1712 if (type & CONTENT_EVENT_PD_MASK) {
1715 if (!handler->is_pd_created) {
1716 ErrPrint("PD is not created\n");
1717 return LB_STATUS_ERROR_INVALID;
1720 if (!handler->pd.data.fb) {
1721 ErrPrint("Handler is not valid\n");
1722 return LB_STATUS_ERROR_INVALID;
1725 if (type & CONTENT_EVENT_MOUSE_MOVE) {
1726 if (fabs(x - handler->pd.x) < MINIMUM_EVENT && fabs(y - handler->pd.y) < MINIMUM_EVENT) {
1727 return LB_STATUS_ERROR_BUSY;
1729 } else if (type & CONTENT_EVENT_MOUSE_SET) {
1734 w = handler->pd.width;
1735 h = handler->pd.height;
1741 } else if (type & CONTENT_EVENT_LB_MASK) {
1744 if (!handler->lb.mouse_event) {
1745 return LB_STATUS_ERROR_INVALID;
1748 if (!handler->lb.data.fb) {
1749 ErrPrint("Handler is not valid\n");
1750 return LB_STATUS_ERROR_INVALID;
1753 if (type & CONTENT_EVENT_MOUSE_MOVE) {
1754 if (fabs(x - handler->lb.x) < MINIMUM_EVENT && fabs(y - handler->lb.y) < MINIMUM_EVENT) {
1755 return LB_STATUS_ERROR_BUSY;
1757 } else if (type & CONTENT_EVENT_MOUSE_SET) {
1762 w = handler->lb.width;
1763 h = handler->lb.height;
1770 ErrPrint("Invalid event type\n");
1771 return LB_STATUS_ERROR_INVALID;
1775 * Must be short than 29 bytes.
1777 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
1778 case CONTENT_EVENT_MOUSE_ENTER | CONTENT_EVENT_MOUSE_MASK:
1779 strcpy(ptr, "_mouse_enter");
1781 case CONTENT_EVENT_MOUSE_LEAVE | CONTENT_EVENT_MOUSE_MASK:
1782 strcpy(ptr, "_mouse_leave");
1784 case CONTENT_EVENT_MOUSE_UP | CONTENT_EVENT_MOUSE_MASK:
1785 strcpy(ptr, "_mouse_up");
1787 case CONTENT_EVENT_MOUSE_DOWN | CONTENT_EVENT_MOUSE_MASK:
1788 strcpy(ptr, "_mouse_down");
1790 case CONTENT_EVENT_MOUSE_MOVE | CONTENT_EVENT_MOUSE_MASK:
1791 strcpy(ptr, "_mouse_move");
1793 case CONTENT_EVENT_MOUSE_SET | CONTENT_EVENT_MOUSE_MASK:
1794 strcpy(ptr, "_mouse_set");
1796 case CONTENT_EVENT_MOUSE_UNSET | CONTENT_EVENT_MOUSE_MASK:
1797 strcpy(ptr, "_mouse_unset");
1800 ErrPrint("Invalid event type\n");
1801 return LB_STATUS_ERROR_INVALID;
1804 return send_mouse_event(handler, cmd, x * w, y * h);
1807 EAPI int livebox_key_event(struct livebox *handler, enum content_event_type type, unsigned int keycode, ret_cb_t cb, void *data)
1809 char cmd[32] = { '\0', };
1814 ErrPrint("Handler is NIL\n");
1815 return LB_STATUS_ERROR_INVALID;
1818 if (handler->state != CREATE || !handler->id) {
1819 ErrPrint("Handler is not valid\n");
1820 return LB_STATUS_ERROR_INVALID;
1823 if (!(type & CONTENT_EVENT_KEY_MASK)) {
1824 ErrPrint("Invalid key event is used\n");
1825 return LB_STATUS_ERROR_INVALID;
1828 if (type & CONTENT_EVENT_PD_MASK) {
1829 if (!handler->is_pd_created) {
1830 ErrPrint("PD is not created\n");
1831 return LB_STATUS_ERROR_INVALID;
1834 if (!handler->pd.data.fb) {
1835 ErrPrint("Handler is not valid\n");
1836 return LB_STATUS_ERROR_INVALID;
1839 if (type & CONTENT_EVENT_KEY_DOWN) {
1842 * filtering the reproduced events if it is too fast
1844 } else if (type & CONTENT_EVENT_KEY_SET) {
1847 * What can I do for this case?
1853 } else if (type & CONTENT_EVENT_LB_MASK) {
1854 if (!handler->lb.mouse_event) {
1855 return LB_STATUS_ERROR_INVALID;
1858 if (!handler->lb.data.fb) {
1859 ErrPrint("Handler is not valid\n");
1860 return LB_STATUS_ERROR_INVALID;
1863 if (type & CONTENT_EVENT_KEY_DOWN) {
1866 * filtering the reproduced events if it is too fast
1868 } else if (type & CONTENT_EVENT_KEY_SET) {
1870 * What can I do for this case?
1877 ErrPrint("Invalid event type\n");
1878 return LB_STATUS_ERROR_INVALID;
1882 * Must be short than 29 bytes.
1884 switch ((type & ~(CONTENT_EVENT_PD_MASK | CONTENT_EVENT_LB_MASK))) {
1885 case CONTENT_EVENT_KEY_FOCUS_IN | CONTENT_EVENT_KEY_MASK:
1886 strcpy(ptr, "_key_focus_in");
1888 case CONTENT_EVENT_KEY_FOCUS_OUT | CONTENT_EVENT_KEY_MASK:
1889 strcpy(ptr, "_key_focus_out");
1891 case CONTENT_EVENT_KEY_UP | CONTENT_EVENT_KEY_MASK:
1892 strcpy(ptr, "_key_up");
1894 case CONTENT_EVENT_KEY_DOWN | CONTENT_EVENT_KEY_MASK:
1895 strcpy(ptr, "_key_down");
1897 case CONTENT_EVENT_KEY_SET | CONTENT_EVENT_KEY_MASK:
1898 strcpy(ptr, "_key_set");
1900 case CONTENT_EVENT_KEY_UNSET | CONTENT_EVENT_KEY_MASK:
1901 strcpy(ptr, "_key_unset");
1904 ErrPrint("Invalid event type\n");
1905 return LB_STATUS_ERROR_INVALID;
1909 cb = default_key_event_cb;
1912 ret = send_key_event(handler, cmd, keycode);
1913 if (ret == LB_STATUS_SUCCESS) {
1914 handler->key_event_cb = cb;
1915 handler->key_event_cbdata = data;
1921 EAPI const char *livebox_filename(struct livebox *handler)
1924 ErrPrint("Handler is NIL\n");
1928 if (handler->state != CREATE || !handler->id) {
1929 ErrPrint("Handler is not valid\n");
1933 if (handler->filename) {
1934 return handler->filename;
1938 return util_uri_to_path(handler->id);
1941 EAPI int livebox_get_pdsize(struct livebox *handler, int *w, int *h)
1947 ErrPrint("Handler is NIL\n");
1948 return LB_STATUS_ERROR_INVALID;
1951 if (handler->state != CREATE || !handler->id) {
1952 ErrPrint("Handler is not valid\n");
1953 return LB_STATUS_ERROR_INVALID;
1963 if (!handler->is_pd_created) {
1964 *w = handler->pd.default_width;
1965 *h = handler->pd.default_height;
1967 *w = handler->pd.width;
1968 *h = handler->pd.height;
1971 return LB_STATUS_SUCCESS;
1974 EAPI int livebox_size(struct livebox *handler)
1980 ErrPrint("Handler is NIL\n");
1981 return LB_STATUS_ERROR_INVALID;
1984 if (handler->state != CREATE || !handler->id) {
1985 ErrPrint("Handler is not valid\n");
1986 return LB_STATUS_ERROR_INVALID;
1989 w = handler->lb.width;
1990 h = handler->lb.height;
1992 switch (handler->lb.type) {
1993 case _LB_TYPE_BUFFER:
1994 case _LB_TYPE_SCRIPT:
1995 if (!fb_is_created(handler->lb.data.fb)) {
2004 return livebox_service_size_type(w, h);
2007 EAPI int livebox_set_group(struct livebox *handler, const char *cluster, const char *category, ret_cb_t cb, void *data)
2009 struct packet *packet;
2013 ErrPrint("Handler is NIL\n");
2014 return LB_STATUS_ERROR_INVALID;
2017 if (!cluster || !category || handler->state != CREATE || !handler->id) {
2018 ErrPrint("Invalid argument\n");
2019 return LB_STATUS_ERROR_INVALID;
2022 if (handler->group_changed_cb) {
2023 ErrPrint("Previous group changing request is not finished yet\n");
2024 return LB_STATUS_ERROR_BUSY;
2027 if (!handler->is_user) {
2028 ErrPrint("CA Livebox is not able to change the group\n");
2029 return LB_STATUS_ERROR_PERMISSION;
2032 if (!strcmp(handler->cluster, cluster) && !strcmp(handler->category, category)) {
2033 DbgPrint("No changes\n");
2034 return LB_STATUS_ERROR_ALREADY;
2037 packet = packet_create("change_group", "ssss", handler->pkgname, handler->id, cluster, category);
2039 ErrPrint("Failed to build a param\n");
2040 return LB_STATUS_ERROR_FAULT;
2044 cb = default_group_changed_cb;
2047 ret = master_rpc_async_request(handler, packet, 0, set_group_ret_cb, NULL);
2048 if (ret == LB_STATUS_SUCCESS) {
2049 handler->group_changed_cb = cb;
2050 handler->group_cbdata = data;
2056 EAPI int livebox_get_group(struct livebox *handler, const char **cluster, const char **category)
2059 ErrPrint("Handler is NIL\n");
2060 return LB_STATUS_ERROR_INVALID;
2063 if (!cluster || !category || handler->state != CREATE || !handler->id) {
2064 ErrPrint("Invalid argument\n");
2065 return LB_STATUS_ERROR_INVALID;
2068 *cluster = handler->cluster;
2069 *category = handler->category;
2070 return LB_STATUS_SUCCESS;
2073 EAPI int livebox_get_supported_sizes(struct livebox *handler, int *cnt, int *size_list)
2078 if (!handler || !size_list) {
2079 ErrPrint("Invalid argument, handler(%p), size_list(%p)\n", handler, size_list);
2080 return LB_STATUS_ERROR_INVALID;
2083 if (!cnt || handler->state != CREATE || !handler->id) {
2084 ErrPrint("Handler is not valid\n");
2085 return LB_STATUS_ERROR_INVALID;
2088 for (j = i = 0; i < NR_OF_SIZE_LIST; i++) {
2089 if (handler->lb.size_list & (0x01 << i)) {
2094 size_list[j++] = (0x01 << i);
2099 return LB_STATUS_SUCCESS;
2102 EAPI const char *livebox_pkgname(struct livebox *handler)
2105 ErrPrint("Handler is NIL\n");
2109 if (handler->state != CREATE) {
2110 ErrPrint("Handler is not valid\n");
2114 return handler->pkgname;
2117 EAPI double livebox_priority(struct livebox *handler)
2120 ErrPrint("Handler is NIL\n");
2124 if (handler->state != CREATE || !handler->id) {
2125 ErrPrint("Handler is not valid (%p)\n", handler);
2129 return handler->lb.priority;
2132 EAPI int livebox_delete_cluster(const char *cluster, ret_cb_t cb, void *data)
2134 struct packet *packet;
2135 struct cb_info *cbinfo;
2138 packet = packet_create("delete_cluster", "s", cluster);
2140 ErrPrint("Failed to build a param\n");
2141 return LB_STATUS_ERROR_FAULT;
2144 cbinfo = create_cb_info(cb, data);
2146 packet_destroy(packet);
2147 return LB_STATUS_ERROR_FAULT;
2150 ret = master_rpc_async_request(NULL, packet, 0, delete_cluster_cb, cbinfo);
2152 destroy_cb_info(cbinfo);
2158 EAPI int livebox_delete_category(const char *cluster, const char *category, ret_cb_t cb, void *data)
2160 struct packet *packet;
2161 struct cb_info *cbinfo;
2164 packet = packet_create("delete_category", "ss", cluster, category);
2166 ErrPrint("Failed to build a param\n");
2167 return LB_STATUS_ERROR_FAULT;
2170 cbinfo = create_cb_info(cb, data);
2172 packet_destroy(packet);
2173 return LB_STATUS_ERROR_FAULT;
2176 ret = master_rpc_async_request(NULL, packet, 0, delete_category_cb, cbinfo);
2178 destroy_cb_info(cbinfo);
2184 EAPI enum livebox_lb_type livebox_lb_type(struct livebox *handler)
2187 ErrPrint("Handler is NIL\n");
2188 return LB_TYPE_INVALID;
2191 if (handler->state != CREATE || !handler->id) {
2192 ErrPrint("Handler is not valid\n");
2193 return LB_TYPE_INVALID;
2196 switch (handler->lb.type) {
2198 return LB_TYPE_IMAGE;
2199 case _LB_TYPE_BUFFER:
2200 case _LB_TYPE_SCRIPT:
2203 id = fb_id(handler->lb.data.fb);
2204 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
2205 return LB_TYPE_PIXMAP;
2208 return LB_TYPE_BUFFER;
2210 return LB_TYPE_TEXT;
2215 return LB_TYPE_INVALID;
2218 EAPI enum livebox_pd_type livebox_pd_type(struct livebox *handler)
2221 ErrPrint("Handler is NIL\n");
2222 return PD_TYPE_INVALID;
2225 if (handler->state != CREATE || !handler->id) {
2226 ErrPrint("Handler is not valid\n");
2227 return PD_TYPE_INVALID;
2230 switch (handler->pd.type) {
2232 return PD_TYPE_TEXT;
2233 case _PD_TYPE_BUFFER:
2234 case _PD_TYPE_SCRIPT:
2237 id = fb_id(handler->pd.data.fb);
2238 if (id && !strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
2239 return PD_TYPE_PIXMAP;
2242 return PD_TYPE_BUFFER;
2247 return PD_TYPE_INVALID;
2250 EAPI int livebox_set_pd_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
2253 ErrPrint("Handler is NIL\n");
2254 return LB_STATUS_ERROR_INVALID;
2257 if (handler->state != CREATE) {
2258 ErrPrint("Handler is not valid\n");
2259 return LB_STATUS_ERROR_INVALID;
2262 memcpy(&handler->pd.data.ops, ops, sizeof(*ops));
2263 return LB_STATUS_SUCCESS;
2266 EAPI int livebox_set_text_handler(struct livebox *handler, struct livebox_script_operators *ops)
2269 ErrPrint("Handler is NIL\n");
2270 return LB_STATUS_ERROR_INVALID;
2273 if (handler->state != CREATE) {
2274 ErrPrint("Handler is not valid\n");
2275 return LB_STATUS_ERROR_INVALID;
2278 memcpy(&handler->lb.data.ops, ops, sizeof(*ops));
2279 return LB_STATUS_SUCCESS;
2282 EAPI int livebox_acquire_lb_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
2284 struct packet *packet;
2285 struct cb_info *cbinfo;
2290 ErrPrint("Handler is NIL\n");
2291 return LB_STATUS_ERROR_INVALID;
2294 if (handler->state != CREATE || !handler->id) {
2295 ErrPrint("Invalid handle\n");
2296 return LB_STATUS_ERROR_INVALID;
2299 if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2300 ErrPrint("Handler is not valid type\n");
2301 return LB_STATUS_ERROR_INVALID;
2304 id = fb_id(handler->lb.data.fb);
2305 if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
2306 return LB_STATUS_ERROR_INVALID;
2309 packet = packet_create("lb_acquire_pixmap", "ss", handler->pkgname, handler->id);
2311 ErrPrint("Failed to build a param\n");
2312 return LB_STATUS_ERROR_FAULT;
2315 cbinfo = create_cb_info(cb, data);
2317 packet_destroy(packet);
2318 return LB_STATUS_ERROR_FAULT;
2321 ret = master_rpc_async_request(handler, packet, 0, lb_pixmap_acquired_cb, cbinfo);
2323 destroy_cb_info(cbinfo);
2329 EAPI int livebox_release_lb_pixmap(struct livebox *handler, int pixmap)
2331 struct packet *packet;
2333 if (!handler || pixmap == 0) {
2334 ErrPrint("Handler is NIL [%d]\n", pixmap);
2335 return LB_STATUS_ERROR_INVALID;
2338 if (handler->state != CREATE || !handler->id) {
2339 ErrPrint("Invalid handle\n");
2340 return LB_STATUS_ERROR_INVALID;
2343 if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2344 ErrPrint("Handler is not valid type\n");
2345 return LB_STATUS_ERROR_INVALID;
2348 packet = packet_create_noack("lb_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
2350 ErrPrint("Failed to build a param\n");
2351 return LB_STATUS_ERROR_INVALID;
2354 return master_rpc_request_only(handler, packet);
2357 EAPI int livebox_acquire_pd_pixmap(struct livebox *handler, ret_cb_t cb, void *data)
2359 struct packet *packet;
2360 struct cb_info *cbinfo;
2365 ErrPrint("Handler is NIL\n");
2366 return LB_STATUS_ERROR_INVALID;
2369 if (handler->state != CREATE || !handler->id) {
2370 ErrPrint("Invalid handle\n");
2371 return LB_STATUS_ERROR_INVALID;
2374 if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2375 ErrPrint("Handler is not valid type\n");
2376 return LB_STATUS_ERROR_INVALID;
2379 id = fb_id(handler->pd.data.fb);
2380 if (!id || strncasecmp(id, SCHEMA_PIXMAP, strlen(SCHEMA_PIXMAP))) {
2381 return LB_STATUS_ERROR_INVALID;
2384 packet = packet_create("pd_acquire_pixmap", "ss", handler->pkgname, handler->id);
2386 ErrPrint("Failed to build a param\n");
2387 return LB_STATUS_ERROR_FAULT;
2390 cbinfo = create_cb_info(cb, data);
2392 packet_destroy(packet);
2393 return LB_STATUS_ERROR_FAULT;
2396 ret = master_rpc_async_request(handler, packet, 0, pd_pixmap_acquired_cb, cbinfo);
2398 destroy_cb_info(cbinfo);
2404 EAPI int livebox_pd_pixmap(const struct livebox *handler)
2410 ErrPrint("Handler is NIL\n");
2414 if (handler->state != CREATE || !handler->id) {
2415 ErrPrint("Invalid handler\n");
2419 if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2420 ErrPrint("Invalid handler\n");
2424 id = fb_id(handler->pd.data.fb);
2425 if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
2426 ErrPrint("PIXMAP Id is not valid\n");
2433 EAPI int livebox_lb_pixmap(const struct livebox *handler)
2439 ErrPrint("Handler is NIL\n");
2443 if (handler->state != CREATE || !handler->id) {
2444 ErrPrint("Invalid handler\n");
2448 if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2449 ErrPrint("Invalid handler\n");
2453 id = fb_id(handler->lb.data.fb);
2454 if (id && sscanf(id, SCHEMA_PIXMAP "%d", &pixmap) != 1) {
2455 ErrPrint("PIXMAP Id is not valid\n");
2462 EAPI int livebox_release_pd_pixmap(struct livebox *handler, int pixmap)
2464 struct packet *packet;
2466 if (!handler || pixmap == 0) {
2467 ErrPrint("Handler is NIL [%d]\n", pixmap);
2468 return LB_STATUS_ERROR_INVALID;
2471 if (handler->state != CREATE || !handler->id) {
2472 ErrPrint("Invalid handle\n");
2473 return LB_STATUS_ERROR_INVALID;
2476 if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2477 ErrPrint("Handler is not valid type\n");
2478 return LB_STATUS_ERROR_INVALID;
2481 packet = packet_create_noack("pd_release_pixmap", "ssi", handler->pkgname, handler->id, pixmap);
2483 ErrPrint("Failed to build a param\n");
2484 return LB_STATUS_ERROR_FAULT;
2487 return master_rpc_request_only(handler, packet);
2490 EAPI void *livebox_acquire_fb(struct livebox *handler)
2493 ErrPrint("Handler is NIL\n");
2497 if (handler->state != CREATE || !handler->id) {
2498 ErrPrint("Invalid handle\n");
2502 if (handler->lb.type != _LB_TYPE_SCRIPT && handler->lb.type != _LB_TYPE_BUFFER) {
2503 ErrPrint("Handler is not valid type\n");
2507 return fb_acquire_buffer(handler->lb.data.fb);
2510 EAPI int livebox_release_fb(void *buffer)
2512 return fb_release_buffer(buffer);
2515 EAPI int livebox_fb_refcnt(void *buffer)
2517 return fb_refcnt(buffer);
2520 EAPI void *livebox_acquire_pdfb(struct livebox *handler)
2523 ErrPrint("Handler is NIL\n");
2527 if (handler->state != CREATE || !handler->id) {
2528 ErrPrint("Invalid handler\n");
2532 if (handler->pd.type != _PD_TYPE_SCRIPT && handler->pd.type != _PD_TYPE_BUFFER) {
2533 ErrPrint("Handler is not valid type\n");
2537 return fb_acquire_buffer(handler->pd.data.fb);
2540 EAPI int livebox_release_pdfb(void *buffer)
2542 return fb_release_buffer(buffer);
2545 EAPI int livebox_pdfb_refcnt(void *buffer)
2547 return fb_refcnt(buffer);
2550 EAPI int livebox_pdfb_bufsz(struct livebox *handler)
2553 ErrPrint("Handler is NIL\n");
2554 return LB_STATUS_ERROR_INVALID;
2557 if (handler->state != CREATE || !handler->id) {
2558 ErrPrint("Handler is not valid\n");
2559 return LB_STATUS_ERROR_INVALID;
2562 return fb_size(handler->pd.data.fb);
2565 EAPI int livebox_lbfb_bufsz(struct livebox *handler)
2568 ErrPrint("Handler is NIL\n");
2569 return LB_STATUS_ERROR_INVALID;
2572 if (handler->state != CREATE || !handler->id) {
2573 ErrPrint("Handler is not valid\n");
2574 return LB_STATUS_ERROR_INVALID;
2577 return fb_size(handler->lb.data.fb);
2580 EAPI int livebox_is_user(struct livebox *handler)
2583 ErrPrint("Handler is NIL\n");
2584 return LB_STATUS_ERROR_INVALID;
2587 if (handler->state != CREATE) {
2588 ErrPrint("Handler is invalid\n");
2589 return LB_STATUS_ERROR_INVALID;
2592 return handler->is_user;
2595 EAPI int livebox_set_pinup(struct livebox *handler, int flag, ret_cb_t cb, void *data)
2597 struct packet *packet;
2601 ErrPrint("Handler is NIL\n");
2602 return LB_STATUS_ERROR_INVALID;
2605 if (handler->state != CREATE || !handler->id) {
2606 ErrPrint("Handler is not valid\n");
2607 return LB_STATUS_ERROR_INVALID;
2610 if (handler->pinup_cb) {
2611 ErrPrint("Previous pinup request is not finished\n");
2612 return LB_STATUS_ERROR_BUSY;
2615 if (handler->is_pinned_up == flag) {
2616 DbgPrint("No changes\n");
2617 return LB_STATUS_ERROR_ALREADY;
2620 packet = packet_create("pinup_changed", "ssi", handler->pkgname, handler->id, flag);
2622 ErrPrint("Failed to build a param\n");
2623 return LB_STATUS_ERROR_FAULT;
2627 cb = default_pinup_cb;
2630 ret = master_rpc_async_request(handler, packet, 0, pinup_done_cb, NULL);
2631 if (ret == LB_STATUS_SUCCESS) {
2632 handler->pinup_cb = cb;
2633 handler->pinup_cbdata = data;
2639 EAPI int livebox_is_pinned_up(struct livebox *handler)
2642 ErrPrint("Handler is NIL\n");
2643 return LB_STATUS_ERROR_INVALID;
2646 if (handler->state != CREATE || !handler->id) {
2647 return LB_STATUS_ERROR_INVALID;
2650 return handler->is_pinned_up;
2653 EAPI int livebox_has_pinup(struct livebox *handler)
2656 ErrPrint("Handler is NIL\n");
2657 return LB_STATUS_ERROR_INVALID;
2660 if (handler->state != CREATE || !handler->id) {
2661 return LB_STATUS_ERROR_INVALID;
2664 return handler->lb.pinup_supported;
2667 EAPI int livebox_set_data(struct livebox *handler, void *data)
2670 ErrPrint("Handler is NIL\n");
2671 return LB_STATUS_ERROR_INVALID;
2674 if (handler->state != CREATE) {
2675 return LB_STATUS_ERROR_INVALID;
2678 handler->data = data;
2679 return LB_STATUS_SUCCESS;
2682 EAPI void *livebox_get_data(struct livebox *handler)
2685 ErrPrint("Handler is NIL\n");
2689 if (handler->state != CREATE) {
2693 return handler->data;
2696 EAPI int livebox_is_exists(const char *pkgname)
2700 lb = lb_pkgname(pkgname);
2709 EAPI const char *livebox_content(struct livebox *handler)
2712 ErrPrint("Handler is NIL\n");
2716 if (handler->state != CREATE) {
2720 return handler->content;
2723 EAPI const char *livebox_category_title(struct livebox *handler)
2726 ErrPrint("Handler is NIL\n");
2730 if (handler->state != CREATE) {
2734 return handler->title;
2737 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)
2739 struct packet *packet;
2740 struct cb_info *cbinfo;
2744 ErrPrint("Handler is NIL\n");
2745 return LB_STATUS_ERROR_INVALID;
2748 if (handler->state != CREATE || (handler->lb.type != _LB_TYPE_TEXT && handler->pd.type != _PD_TYPE_TEXT) || !handler->id) {
2749 ErrPrint("Handler is not valid\n");
2750 return LB_STATUS_ERROR_INVALID;
2761 packet = packet_create("text_signal", "ssssdddd",
2762 handler->pkgname, handler->id, emission, source, sx, sy, ex, ey);
2764 ErrPrint("Failed to build a param\n");
2765 return LB_STATUS_ERROR_FAULT;
2768 cbinfo = create_cb_info(cb, data);
2770 packet_destroy(packet);
2771 return LB_STATUS_ERROR_FAULT;
2774 ret = master_rpc_async_request(handler, packet, 0, text_signal_cb, cbinfo);
2776 destroy_cb_info(cbinfo);
2782 EAPI int livebox_subscribe_group(const char *cluster, const char *category)
2784 struct packet *packet;
2788 * Validate the group info using DB
2789 * If the group info is not valid, do not send this request
2792 packet = packet_create_noack("subscribe", "ss", cluster ? cluster : "", category ? category : "");
2794 ErrPrint("Failed to create a packet\n");
2795 return LB_STATUS_ERROR_FAULT;
2798 return master_rpc_request_only(NULL, packet);
2801 EAPI int livebox_unsubscribe_group(const char *cluster, const char *category)
2803 struct packet *packet;
2807 * Validate the group info using DB
2808 * If the group info is not valid, do not send this request
2809 * AND Check the subscribed or not too
2812 packet = packet_create_noack("unsubscribe", "ss", cluster ? cluster : "", category ? category : "");
2814 ErrPrint("Failed to create a packet\n");
2815 return LB_STATUS_ERROR_FAULT;
2818 return master_rpc_request_only(NULL, packet);
2821 EAPI int livebox_refresh(struct livebox *handler, int force)
2823 struct packet *packet;
2826 ErrPrint("Hnalder is NIL\n");
2827 return LB_STATUS_ERROR_INVALID;
2830 if (handler->state != CREATE || !handler->id) {
2831 return LB_STATUS_ERROR_INVALID;
2834 packet = packet_create_noack("update", "ssi", handler->pkgname, handler->id, force);
2836 ErrPrint("Failed to create a packet\n");
2837 return LB_STATUS_ERROR_FAULT;
2840 return master_rpc_request_only(handler, packet);
2843 EAPI int livebox_refresh_group(const char *cluster, const char *category, int force)
2845 struct packet *packet;
2847 if (!cluster || !category) {
2848 ErrPrint("Invalid argument\n");
2849 return LB_STATUS_ERROR_INVALID;
2852 packet = packet_create_noack("refresh_group", "ssi", cluster, category, force);
2854 ErrPrint("Failed to create a packet\n");
2855 return LB_STATUS_ERROR_FAULT;
2858 return master_rpc_request_only(NULL, packet);
2861 EAPI int livebox_set_visibility(struct livebox *handler, enum livebox_visible_state state)
2863 struct packet *packet;
2867 ErrPrint("Handler is NIL\n");
2868 return LB_STATUS_ERROR_INVALID;
2871 if (handler->state != CREATE || !handler->id) {
2872 return LB_STATUS_ERROR_INVALID;
2875 if (!handler->is_user) {
2876 /* System cluster livebox cannot be changed its visible states */
2877 if (state == LB_HIDE_WITH_PAUSE) {
2878 ErrPrint("CA Livebox is not able to change the visibility\n");
2879 return LB_STATUS_ERROR_PERMISSION;
2883 if (handler->visible == state) {
2884 return LB_STATUS_ERROR_ALREADY;
2887 packet = packet_create_noack("change,visibility", "ssi", handler->pkgname, handler->id, (int)state);
2889 ErrPrint("Failed to create a packet\n");
2890 return LB_STATUS_ERROR_FAULT;
2893 ret = master_rpc_request_only(handler, packet);
2895 handler->visible = state;
2901 EAPI enum livebox_visible_state livebox_visibility(struct livebox *handler)
2904 ErrPrint("Handler is NIL\n");
2905 return LB_VISIBLE_ERROR;
2908 if (handler->state != CREATE || !handler->id) {
2909 return LB_VISIBLE_ERROR;
2912 return handler->visible;
2915 int lb_set_group(struct livebox *handler, const char *cluster, const char *category)
2921 pc = strdup(cluster);
2923 ErrPrint("Heap: %s (cluster: %s)\n", strerror(errno), cluster);
2924 return LB_STATUS_ERROR_MEMORY;
2929 ps = strdup(category);
2931 ErrPrint("Heap: %s (category: %s)\n", strerror(errno), category);
2933 return LB_STATUS_ERROR_MEMORY;
2937 if (handler->cluster) {
2938 free(handler->cluster);
2941 if (handler->category) {
2942 free(handler->category);
2945 handler->cluster = pc;
2946 handler->category = ps;
2948 return LB_STATUS_SUCCESS;
2951 void lb_set_size(struct livebox *handler, int w, int h)
2953 handler->lb.width = w;
2954 handler->lb.height = h;
2957 void lb_set_update_mode(struct livebox *handle, int active_mode)
2959 handle->is_active_update = active_mode;
2962 void lb_set_pdsize(struct livebox *handler, int w, int h)
2964 handler->pd.width = w;
2965 handler->pd.height = h;
2968 void lb_set_default_pdsize(struct livebox *handler, int w, int h)
2970 handler->pd.default_width = w;
2971 handler->pd.default_height = h;
2974 void lb_invoke_fault_handler(enum livebox_fault_type event, const char *pkgname, const char *file, const char *func)
2978 struct fault_info *info;
2980 dlist_foreach_safe(s_info.fault_list, l, n, info) {
2981 if (info->handler(event, pkgname, file, func, info->user_data) == EXIT_FAILURE) {
2982 s_info.fault_list = dlist_remove(s_info.fault_list, l);
2987 void lb_invoke_event_handler(struct livebox *handler, enum livebox_event_type event)
2991 struct event_info *info;
2993 dlist_foreach_safe(s_info.event_list, l, n, info) {
2994 if (info->handler(handler, event, info->user_data) == EXIT_FAILURE) {
2995 s_info.event_list = dlist_remove(s_info.event_list, l);
3000 struct livebox *lb_find_livebox(const char *pkgname, const char *id)
3003 struct livebox *handler;
3005 dlist_foreach(s_info.livebox_list, l, handler) {
3010 if (!strcmp(handler->pkgname, pkgname) && !strcmp(handler->id, id)) {
3018 struct livebox *lb_find_livebox_by_timestamp(double timestamp)
3021 struct livebox *handler;
3023 dlist_foreach(s_info.livebox_list, l, handler) {
3024 if (handler->timestamp == timestamp) {
3032 struct livebox *lb_new_livebox(const char *pkgname, const char *id, double timestamp)
3034 struct livebox *handler;
3036 handler = calloc(1, sizeof(*handler));
3038 ErrPrint("Failed to create a new livebox\n");
3042 handler->pkgname = strdup(pkgname);
3043 if (!handler->pkgname) {
3044 ErrPrint("%s\n", strerror(errno));
3049 handler->id = strdup(id);
3051 ErrPrint("%s\n", strerror(errno));
3052 free(handler->pkgname);
3057 handler->timestamp = timestamp;
3058 handler->lb.type = _LB_TYPE_FILE;
3059 handler->pd.type = _PD_TYPE_SCRIPT;
3060 handler->state = CREATE;
3061 handler->visible = LB_SHOW;
3062 handler->delete_type = LB_DELETE_PERMANENTLY;
3063 handler->pd.lock = NULL;
3064 handler->pd.lock_fd = -1;
3065 handler->lb.lock = NULL;
3066 handler->lb.lock_fd = -1;
3068 s_info.livebox_list = dlist_append(s_info.livebox_list, handler);
3073 int lb_delete_all(void)
3077 struct livebox *handler;
3079 dlist_foreach_safe(s_info.livebox_list, l, n, handler) {
3080 lb_invoke_event_handler(handler, LB_EVENT_DELETED);
3084 return LB_STATUS_SUCCESS;
3087 int lb_set_content(struct livebox *handler, const char *content)
3089 if (handler->content) {
3090 free(handler->content);
3091 handler->content = NULL;
3095 handler->content = strdup(content);
3096 if (!handler->content) {
3097 ErrPrint("Heap: %s (content: %s)\n", strerror(errno), content);
3098 return LB_STATUS_ERROR_MEMORY;
3102 return LB_STATUS_SUCCESS;
3105 int lb_set_title(struct livebox *handler, const char *title)
3107 if (handler->title) {
3108 free(handler->title);
3109 handler->title = NULL;
3113 handler->title = strdup(title);
3114 if (!handler->title) {
3115 ErrPrint("Heap: %s (title: %s)\n", strerror(errno), title);
3116 return LB_STATUS_ERROR_MEMORY;
3120 return LB_STATUS_SUCCESS;
3123 void lb_set_size_list(struct livebox *handler, int size_list)
3125 handler->lb.size_list = size_list;
3128 void lb_set_auto_launch(struct livebox *handler, const char *auto_launch)
3130 if (!strlen(auto_launch)) {
3134 handler->lb.auto_launch = strdup(auto_launch);
3135 if (!handler->lb.auto_launch) {
3136 ErrPrint("Heap: %s\n", strerror(errno));
3140 void lb_set_priority(struct livebox *handler, double priority)
3142 handler->lb.priority = priority;
3145 void lb_set_id(struct livebox *handler, const char *id)
3151 handler->id = strdup(id);
3153 ErrPrint("Error: %s\n", strerror(errno));
3157 void lb_set_filename(struct livebox *handler, const char *filename)
3159 if (handler->filename) {
3160 if (handler->lb.type == _LB_TYPE_FILE || handler->lb.type == _LB_TYPE_TEXT) {
3161 if (handler->filename[0] && unlink(handler->filename) < 0) {
3162 ErrPrint("unlink: %s (%s)\n", strerror(errno), handler->filename);
3166 free(handler->filename);
3169 handler->filename = strdup(filename);
3170 if (!handler->filename) {
3171 ErrPrint("Heap: %s\n", strerror(errno));
3175 void lb_set_alt_info(struct livebox *handler, const char *icon, const char *name)
3180 if (icon && strlen(icon)) {
3181 _icon = strdup(icon);
3183 ErrPrint("Heap: %s\n", strerror(errno));
3187 if (name && strlen(name)) {
3188 _name = strdup(name);
3190 ErrPrint("Heap: %s\n", strerror(errno));
3194 if (handler->icon) {
3195 free(handler->icon);
3198 handler->icon = _icon;
3200 if (handler->name) {
3201 free(handler->name);
3204 handler->name = _name;
3207 int lb_set_lb_fb(struct livebox *handler, const char *filename)
3212 return LB_STATUS_ERROR_INVALID;
3215 fb = handler->lb.data.fb;
3216 if (fb && !strcmp(fb_id(fb), filename)) { /*!< BUFFER is not changed, */
3217 return LB_STATUS_SUCCESS;
3220 handler->lb.data.fb = NULL;
3222 if (!filename || filename[0] == '\0') {
3226 return LB_STATUS_SUCCESS;
3229 handler->lb.data.fb = fb_create(filename, handler->lb.width, handler->lb.height);
3230 if (!handler->lb.data.fb) {
3231 ErrPrint("Faield to create a FB\n");
3235 return LB_STATUS_ERROR_FAULT;
3242 return LB_STATUS_SUCCESS;
3245 int lb_set_pd_fb(struct livebox *handler, const char *filename)
3250 return LB_STATUS_ERROR_INVALID;
3253 fb = handler->pd.data.fb;
3254 if (fb && !strcmp(fb_id(fb), filename)) {
3255 /* BUFFER is not changed, just update the content */
3256 return LB_STATUS_ERROR_EXIST;
3258 handler->pd.data.fb = NULL;
3260 if (!filename || filename[0] == '\0') {
3264 return LB_STATUS_SUCCESS;
3267 handler->pd.data.fb = fb_create(filename, handler->pd.width, handler->pd.height);
3268 if (!handler->pd.data.fb) {
3269 ErrPrint("Failed to create a FB\n");
3273 return LB_STATUS_ERROR_FAULT;
3279 return LB_STATUS_SUCCESS;
3282 struct fb_info *lb_get_lb_fb(struct livebox *handler)
3284 return handler->lb.data.fb;
3287 struct fb_info *lb_get_pd_fb(struct livebox *handler)
3289 return handler->pd.data.fb;
3292 void lb_set_user(struct livebox *handler, int user)
3294 handler->is_user = user;
3297 void lb_set_pinup(struct livebox *handler, int pinup_supported)
3299 handler->lb.pinup_supported = pinup_supported;
3302 void lb_set_text_lb(struct livebox *handler)
3304 handler->lb.type = _LB_TYPE_TEXT;
3307 void lb_set_text_pd(struct livebox *handler)
3309 handler->pd.type = _PD_TYPE_TEXT;
3312 int lb_text_lb(struct livebox *handler)
3314 return handler->lb.type == _LB_TYPE_TEXT;
3317 int lb_text_pd(struct livebox *handler)
3319 return handler->pd.type == _PD_TYPE_TEXT;
3322 void lb_set_period(struct livebox *handler, double period)
3324 handler->lb.period = period;
3327 struct livebox *lb_ref(struct livebox *handler)
3337 struct livebox *lb_unref(struct livebox *handler)
3344 if (handler->refcnt > 0) {
3348 if (handler->created_cb) {
3349 handler->created_cb(handler, LB_STATUS_ERROR_FAULT, handler->created_cbdata);
3350 handler->created_cb = NULL;
3351 handler->created_cbdata = NULL;
3354 if (handler->deleted_cb) {
3355 handler->deleted_cb(handler, LB_STATUS_ERROR_FAULT, handler->deleted_cbdata);
3356 handler->deleted_cb = NULL;
3357 handler->deleted_cbdata = NULL;
3360 if (handler->pinup_cb) {
3361 handler->pinup_cb(handler, LB_STATUS_ERROR_FAULT, handler->pinup_cbdata);
3362 handler->pinup_cb = NULL;
3363 handler->pinup_cbdata = NULL;
3366 if (handler->group_changed_cb) {
3367 handler->group_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->group_cbdata);
3368 handler->group_changed_cb = NULL;
3369 handler->group_cbdata = NULL;
3372 if (handler->period_changed_cb) {
3373 handler->period_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->period_cbdata);
3374 handler->period_changed_cb = NULL;
3375 handler->period_cbdata = NULL;
3378 if (handler->size_changed_cb) {
3379 handler->size_changed_cb(handler, LB_STATUS_ERROR_FAULT, handler->size_cbdata);
3380 handler->size_changed_cb = NULL;
3381 handler->size_cbdata = NULL;
3384 if (handler->pd_created_cb) {
3385 handler->pd_created_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_created_cbdata);
3386 handler->pd_created_cb = NULL;
3387 handler->pd_created_cbdata = NULL;
3390 if (handler->pd_destroyed_cb) {
3391 handler->pd_destroyed_cb(handler, LB_STATUS_ERROR_FAULT, handler->pd_destroyed_cbdata);
3392 handler->pd_destroyed_cb = NULL;
3393 handler->pd_destroyed_cbdata = NULL;
3396 if (handler->update_mode_cb) {
3397 handler->update_mode_cb(handler, LB_STATUS_ERROR_FAULT, handler->update_mode_cbdata);
3398 handler->update_mode_cb = NULL;
3399 handler->update_mode_cbdata = NULL;
3402 if (handler->access_event_cb) {
3403 handler->access_event_cb(handler, LB_ACCESS_STATUS_ERROR, handler->access_event_cbdata);
3404 handler->access_event_cb = NULL;
3405 handler->access_event_cbdata = NULL;
3408 if (handler->key_event_cb) {
3409 handler->key_event_cb(handler, LB_KEY_STATUS_ERROR, handler->key_event_cbdata);
3410 handler->key_event_cb = NULL;
3411 handler->key_event_cbdata = NULL;
3414 if (handler->filename) {
3415 (void)util_unlink(handler->filename);
3418 dlist_remove_data(s_info.livebox_list, handler);
3420 handler->state = DESTROYED;
3421 free(handler->cluster);
3422 free(handler->category);
3424 free(handler->pkgname);
3425 free(handler->filename);
3426 free(handler->lb.auto_launch);
3427 free(handler->icon);
3428 free(handler->name);
3430 if (handler->lb.data.fb) {
3431 fb_destroy(handler->lb.data.fb);
3432 handler->lb.data.fb = NULL;
3435 if (handler->pd.data.fb) {
3436 fb_destroy(handler->pd.data.fb);
3437 handler->pd.data.fb = NULL;
3444 int lb_send_delete(struct livebox *handler, int type, ret_cb_t cb, void *data)
3446 struct packet *packet;
3447 struct cb_info *cbinfo;
3450 if (!cb && !!data) {
3451 ErrPrint("Invalid argument\n");
3452 return LB_STATUS_ERROR_INVALID;
3455 if (handler->deleted_cb) {
3456 ErrPrint("Already in-progress\n");
3457 return LB_STATUS_ERROR_BUSY;
3460 packet = packet_create("delete", "ssi", handler->pkgname, handler->id, type);
3462 ErrPrint("Failed to build a param\n");
3464 cb(handler, LB_STATUS_ERROR_FAULT, data);
3467 return LB_STATUS_ERROR_FAULT;
3471 cb = default_delete_cb;
3474 cbinfo = create_cb_info(cb, data);
3476 packet_destroy(packet);
3477 return LB_STATUS_ERROR_FAULT;
3480 ret = master_rpc_async_request(handler, packet, 0, del_ret_cb, cbinfo);
3482 destroy_cb_info(cbinfo);
3488 EAPI int livebox_client_paused(void)
3490 struct packet *packet;
3492 packet = packet_create_noack("client_paused", "d", util_timestamp());
3494 ErrPrint("Failed to create a pause packet\n");
3495 return LB_STATUS_ERROR_FAULT;
3498 return master_rpc_request_only(NULL, packet);
3501 EAPI int livebox_client_resumed(void)
3503 struct packet *packet;
3505 packet = packet_create_noack("client_resumed", "d", util_timestamp());
3507 ErrPrint("Failed to create a resume packet\n");
3508 return LB_STATUS_ERROR_FAULT;
3511 return master_rpc_request_only(NULL, packet);
3514 EAPI void livebox_set_manual_sync(int flag)
3516 conf_set_manual_sync(flag);
3519 EAPI int livebox_manual_sync(void)
3521 return conf_manual_sync();
3524 EAPI void livebox_set_frame_drop_for_resizing(int flag)
3526 conf_set_frame_drop_for_resizing(flag);
3529 EAPI int livebox_frame_drop_for_resizing(void)
3531 return conf_frame_drop_for_resizing();
3534 EAPI int livebox_sync_lb_fb(struct livebox *handler)
3538 if (fb_type(lb_get_lb_fb(handler)) == BUFFER_TYPE_FILE && handler->lb.lock_fd >= 0) {
3539 (void)do_fb_lock(handler->lb.lock_fd);
3540 ret = fb_sync(lb_get_lb_fb(handler));
3541 (void)do_fb_unlock(handler->lb.lock_fd);
3543 ret = fb_sync(lb_get_lb_fb(handler));
3549 EAPI int livebox_sync_pd_fb(struct livebox *handler)
3553 if (fb_type(lb_get_pd_fb(handler)) == BUFFER_TYPE_FILE && handler->pd.lock_fd >= 0) {
3554 (void)do_fb_lock(handler->pd.lock_fd);
3555 ret = fb_sync(lb_get_pd_fb(handler));
3556 (void)do_fb_unlock(handler->pd.lock_fd);
3558 ret = fb_sync(lb_get_pd_fb(handler));
3564 EAPI const char *livebox_alt_icon(struct livebox *handler)
3566 if (!handler || handler->state != CREATE) {
3567 ErrPrint("Handler is not valid[%p]\n", handler);
3570 return handler->icon;
3573 EAPI const char *livebox_alt_name(struct livebox *handler)
3575 if (!handler || handler->state != CREATE) {
3576 ErrPrint("Handler is not valid[%p]\n", handler);
3580 return handler->name;
3583 EAPI int livebox_acquire_fb_lock(struct livebox *handler, int is_pd)
3585 int ret = LB_STATUS_SUCCESS;
3589 if (!handler->pd.lock || handler->pd.lock_fd < 0) {
3590 DbgPrint("Lock: %s (%d)\n", handler->pd.lock, handler->pd.lock_fd);
3591 return LB_STATUS_ERROR_INVALID;
3594 if (fb_type(lb_get_pd_fb(handler)) == BUFFER_TYPE_FILE) {
3595 return LB_STATUS_SUCCESS;
3598 fd = handler->pd.lock_fd;
3600 if (!handler->lb.lock || handler->lb.lock_fd < 0) {
3601 DbgPrint("Lock: %s (%d)\n", handler->lb.lock, handler->lb.lock_fd);
3602 return LB_STATUS_ERROR_INVALID;
3605 if (fb_type(lb_get_lb_fb(handler)) == BUFFER_TYPE_FILE) {
3606 return LB_STATUS_SUCCESS;
3609 fd = handler->lb.lock_fd;
3612 ret = do_fb_lock(fd);
3614 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;
3617 EAPI int livebox_release_fb_lock(struct livebox *handler, int is_pd)
3619 int ret = LB_STATUS_SUCCESS;
3623 if (!handler->pd.lock || handler->pd.lock_fd < 0) {
3624 DbgPrint("Unlock: %s (%d)\n", handler->pd.lock, handler->pd.lock_fd);
3625 return LB_STATUS_ERROR_INVALID;
3628 if (fb_type(lb_get_pd_fb(handler)) == BUFFER_TYPE_FILE) {
3629 return LB_STATUS_SUCCESS;
3632 fd = handler->pd.lock_fd;
3634 if (!handler->lb.lock || handler->lb.lock_fd < 0) {
3635 DbgPrint("Unlock: %s (%d)\n", handler->lb.lock, handler->lb.lock_fd);
3636 return LB_STATUS_ERROR_INVALID;
3639 if (fb_type(lb_get_lb_fb(handler)) == BUFFER_TYPE_FILE) {
3640 return LB_STATUS_SUCCESS;
3643 fd = handler->lb.lock_fd;
3646 ret = do_fb_unlock(fd);
3648 return ret == 0 ? LB_STATUS_SUCCESS : LB_STATUS_ERROR_FAULT;