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 */
22 #include <unistd.h> /* access */
27 #include <livebox-service.h>
29 #include <provider_buffer.h>
30 #include <livebox-errno.h>
37 #define PUBLIC __attribute__((visibility("default")))
39 #define FILE_SCHEMA "file://"
42 * \brief This function is defined by the data-provider-slave
45 const char *(*find_pkgname)(const char *filename);
46 int (*request_update_by_id)(const char *uri);
47 int (*trigger_update_monitor)(const char *id, int is_pd);
50 .request_update_by_id = NULL,
51 .trigger_update_monitor = NULL,
70 unsigned int last_idx;
72 struct dlist *block_list;
75 struct livebox_buffer_data {
79 /* for Buffer event wrapper */
80 int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
84 PUBLIC const int DONE = 0x00;
85 PUBLIC const int OUTPUT_UPDATED = 0x02;
86 PUBLIC const int USE_NET = 0x04;
88 PUBLIC const int NEED_TO_SCHEDULE = 0x01;
89 PUBLIC const int NEED_TO_CREATE = 0x01;
90 PUBLIC const int NEED_TO_DESTROY = 0x01;
91 PUBLIC const int NEED_TO_UPDATE = 0x01;
93 PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
94 PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
95 PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
96 PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
97 PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
98 PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
99 PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
101 PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
103 struct livebox_desc *handle;
106 handle = calloc(1, sizeof(*handle));
108 ErrPrint("Error: %s\n", strerror(errno));
114 len = strlen(filename) + strlen(".desc") + 1;
115 new_fname = malloc(len);
117 ErrPrint("Error: %s\n", strerror(errno));
121 snprintf(new_fname, len, "%s.desc", filename);
123 new_fname = strdup(filename);
125 ErrPrint("Error: %s\n", strerror(errno));
131 DbgPrint("Open a file %s with merge mode %s\n",
133 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
135 handle->fp = fopen(new_fname, "at");
138 ErrPrint("Failed to open a file: %s\n", strerror(errno));
146 PUBLIC int livebox_desc_close(struct livebox_desc *handle)
153 return LB_STATUS_ERROR_INVALID;
156 dlist_foreach_safe(handle->block_list, l, n, block) {
157 handle->block_list = dlist_remove(handle->block_list, l);
159 fprintf(handle->fp, "{\n");
161 fprintf(handle->fp, "type=%s\n", block->type);
165 fprintf(handle->fp, "part=%s\n", block->part);
169 fprintf(handle->fp, "data=%s\n", block->data);
173 fprintf(handle->fp, "option=%s\n", block->option);
177 fprintf(handle->fp, "id=%s\n", block->id);
180 if (block->target_id) {
181 fprintf(handle->fp, "target=%s\n", block->target_id);
183 fprintf(handle->fp, "}\n");
190 free(block->target_id);
194 if (fclose(handle->fp) != 0) {
195 ErrPrint("fclose: %s\n", strerror(errno));
198 return LB_STATUS_SUCCESS;
201 PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
205 if (!handle || !category) {
206 return LB_STATUS_ERROR_INVALID;
209 block = calloc(1, sizeof(*block));
211 return LB_STATUS_ERROR_MEMORY;
214 block->type = strdup(LB_DESC_TYPE_INFO);
217 return LB_STATUS_ERROR_MEMORY;
220 block->part = strdup("category");
224 return LB_STATUS_ERROR_MEMORY;
227 block->data = strdup(category);
232 return LB_STATUS_ERROR_MEMORY;
236 block->id = strdup(id);
242 return LB_STATUS_ERROR_MEMORY;
246 block->idx = handle->last_idx++;
247 handle->block_list = dlist_append(handle->block_list, block);
251 PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
257 return LB_STATUS_ERROR_INVALID;
260 block = calloc(1, sizeof(*block));
262 return LB_STATUS_ERROR_MEMORY;
265 block->type = strdup(LB_DESC_TYPE_INFO);
268 return LB_STATUS_ERROR_MEMORY;
271 block->part = strdup("size");
275 return LB_STATUS_ERROR_MEMORY;
279 block->id = strdup(id);
284 return LB_STATUS_ERROR_MEMORY;
288 snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
289 block->data = strdup(buffer);
294 return LB_STATUS_ERROR_MEMORY;
297 block->idx = handle->last_idx++;
298 handle->block_list = dlist_append(handle->block_list, block);
302 PUBLIC char *livebox_util_nl2br(const char *str)
318 ret = malloc(len + 1);
332 tmp = realloc(ret, len + 1);
359 PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
364 dlist_foreach(handle->block_list, l, block) {
365 if (block->idx == idx) {
366 if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
367 ErrPrint("Invalid block is used\n");
368 return LB_STATUS_ERROR_INVALID;
371 free(block->target_id);
372 block->target_id = NULL;
374 if (!id || !strlen(id)) {
375 return LB_STATUS_SUCCESS;
378 block->target_id = strdup(id);
379 if (!block->target_id) {
380 ErrPrint("Heap: %s\n", strerror(errno));
381 return LB_STATUS_ERROR_MEMORY;
384 return LB_STATUS_SUCCESS;
388 return LB_STATUS_ERROR_NOT_EXIST;
394 PUBLIC int livebox_desc_add_block(struct livebox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
398 if (!handle || !type) {
399 return LB_STATUS_ERROR_INVALID;
410 block = calloc(1, sizeof(*block));
412 ErrPrint("Heap: %s\n", strerror(errno));
413 return LB_STATUS_ERROR_MEMORY;
416 block->type = strdup(type);
418 ErrPrint("Heap: %s\n", strerror(errno));
420 return LB_STATUS_ERROR_MEMORY;
423 block->part = strdup(part);
425 ErrPrint("Heap: %s\n", strerror(errno));
428 return LB_STATUS_ERROR_MEMORY;
431 block->data = strdup(data);
433 ErrPrint("Heap: %s\n", strerror(errno));
437 return LB_STATUS_ERROR_MEMORY;
441 block->option = strdup(option);
442 if (!block->option) {
443 ErrPrint("Heap: %s\n", strerror(errno));
448 return LB_STATUS_ERROR_MEMORY;
453 block->id = strdup(id);
455 ErrPrint("Heap: %s\n", strerror(errno));
461 return LB_STATUS_ERROR_MEMORY;
465 block->idx = handle->last_idx++;
466 handle->block_list = dlist_append(handle->block_list, block);
470 PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
475 dlist_foreach(handle->block_list, l, block) {
476 if (block->idx == idx) {
477 handle->block_list = dlist_remove(handle->block_list, l);
483 free(block->target_id);
485 return LB_STATUS_SUCCESS;
489 return LB_STATUS_ERROR_NOT_EXIST;
494 * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
496 static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
500 struct livebox_buffer_data *cbdata = data;
503 pkgname = provider_buffer_pkgname(buffer);
505 ErrPrint("pkgname is not valid\n");
506 return LB_STATUS_ERROR_INVALID;
509 id = provider_buffer_id(buffer);
511 ErrPrint("id is not valid[%s]\n", pkgname);
512 return LB_STATUS_ERROR_INVALID;
515 ret = cbdata->handler(buffer, event, timestamp, x, y, cbdata->cbdata);
518 case BUFFER_EVENT_HIGHLIGHT:
519 case BUFFER_EVENT_HIGHLIGHT_NEXT:
520 case BUFFER_EVENT_HIGHLIGHT_PREV:
521 case BUFFER_EVENT_ACTIVATE:
522 case BUFFER_EVENT_ACTION_UP:
523 case BUFFER_EVENT_ACTION_DOWN:
524 case BUFFER_EVENT_SCROLL_UP:
525 case BUFFER_EVENT_SCROLL_MOVE:
526 case BUFFER_EVENT_SCROLL_DOWN:
527 case BUFFER_EVENT_UNHIGHLIGHT:
528 DbgPrint("Accessibility event: %d\n", event);
530 (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
532 (void)provider_send_access_status(pkgname, id, ret);
542 static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
548 PUBLIC struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data)
550 struct livebox_buffer_data *user_data;
552 struct livebox_buffer *handle;
556 if (!filename || !width || !height) {
557 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
561 user_data = calloc(1, sizeof(*user_data));
563 ErrPrint("Heap: %s\n", strerror(errno));
567 user_data->is_pd = is_pd;
568 user_data->handler = handler ? handler : default_event_handler;
569 user_data->cbdata = data;
571 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
572 uri = malloc(uri_len);
574 ErrPrint("Heap: %s\n", strerror(errno));
579 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
580 if (!s_info.find_pkgname) {
581 s_info.find_pkgname = dlsym(RTLD_DEFAULT, "livebox_find_pkgname");
582 if (!s_info.find_pkgname) {
583 ErrPrint("Failed to find a \"livebox_find_pkgname\"\n");
590 pkgname = s_info.find_pkgname(uri);
592 ErrPrint("Invalid Request\n");
598 handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
599 DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
606 (void)provider_buffer_set_user_data(handle, user_data);
610 PUBLIC int livebox_request_update(const char *filename)
617 ErrPrint("Invalid argument\n");
618 return LB_STATUS_ERROR_INVALID;
621 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
622 uri = malloc(uri_len);
624 ErrPrint("Heap: %s\n", strerror(errno));
625 return LB_STATUS_ERROR_MEMORY;
628 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
629 if (!s_info.request_update_by_id) {
630 s_info.request_update_by_id = dlsym(RTLD_DEFAULT, "livebox_request_update_by_id");
631 if (!s_info.request_update_by_id) {
632 ErrPrint("\"livebox_request_update_by_id\" is not exists\n");
634 return LB_STATUS_ERROR_FAULT;
637 ret = s_info.request_update_by_id(uri);
642 PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
644 return provider_buffer_pixmap_id(handle);
647 PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
649 struct livebox_buffer_data *user_data;
652 return LB_STATUS_ERROR_INVALID;
655 user_data = provider_buffer_user_data(handle);
658 provider_buffer_set_user_data(handle, NULL);
661 DbgPrint("Release buffer\n");
662 return provider_buffer_release(handle);
665 PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
667 struct livebox_buffer_data *user_data;
676 user_data = provider_buffer_user_data(handle);
681 if (user_data->accelerated) {
682 DbgPrint("H/W accelerated buffer is allocated\n");
686 ret = provider_buffer_get_size(handle, &w, &h, &size);
688 data = provider_buffer_ref(handle);
689 if (data && !ret && w > 0 && h > 0 && size > 0) {
690 memset(data, 0, w * h * size);
691 provider_buffer_sync(handle);
694 DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
698 PUBLIC int livebox_unref_buffer(void *buffer)
701 return LB_STATUS_ERROR_INVALID;
704 DbgPrint("Unref buffer\n");
705 return provider_buffer_unref(buffer);
708 PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
710 struct livebox_buffer_data *user_data;
715 return LB_STATUS_ERROR_INVALID;
718 user_data = provider_buffer_user_data(handle);
720 ErrPrint("Invalid buffer\n");
721 return LB_STATUS_ERROR_INVALID;
724 if (user_data->accelerated) {
725 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
726 return LB_STATUS_SUCCESS;
729 pkgname = provider_buffer_pkgname(handle);
731 ErrPrint("Invalid buffer handler\n");
732 return LB_STATUS_ERROR_INVALID;
735 id = provider_buffer_id(handle);
737 ErrPrint("Invalid buffer handler\n");
738 return LB_STATUS_ERROR_INVALID;
741 provider_buffer_sync(handle);
743 if (user_data->is_pd) {
744 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
745 ErrPrint("Failed to send PD updated (%s)\n", id);
752 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
753 ErrPrint("Failed to get size (%s)\n", id);
756 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
757 ErrPrint("Failed to send updated (%s)\n", id);
761 return LB_STATUS_SUCCESS;
764 PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
767 return LB_STATUS_ERROR_INVALID;
770 return provider_buffer_pixmap_is_support_hw(handle);
773 PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
775 struct livebox_buffer_data *user_data;
779 return LB_STATUS_ERROR_INVALID;
782 user_data = provider_buffer_user_data(handle);
784 return LB_STATUS_ERROR_INVALID;
787 if (user_data->accelerated) {
788 return LB_STATUS_ERROR_ALREADY;
791 ret = provider_buffer_pixmap_create_hw(handle);
792 user_data->accelerated = (ret == 0);
796 PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
798 struct livebox_buffer_data *user_data;
800 return LB_STATUS_ERROR_INVALID;
803 user_data = provider_buffer_user_data(handle);
804 if (!user_data || !user_data->accelerated) {
805 return LB_STATUS_ERROR_INVALID;
808 user_data->accelerated = 0;
810 return provider_buffer_pixmap_destroy_hw(handle);
813 PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
815 struct livebox_buffer_data *user_data;
821 user_data = provider_buffer_user_data(handle);
822 if (!user_data || !user_data->accelerated) {
826 return provider_buffer_pixmap_hw_addr(handle);
829 PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
831 struct livebox_buffer_data *user_data;
834 return LB_STATUS_ERROR_INVALID;
837 user_data = provider_buffer_user_data(handle);
839 return LB_STATUS_ERROR_INVALID;
842 if (!user_data->accelerated) {
843 return LB_STATUS_SUCCESS;
848 * Do preprocessing for accessing the H/W render buffer
850 return provider_buffer_pre_render(handle);
853 PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
858 struct livebox_buffer_data *user_data;
861 return LB_STATUS_ERROR_INVALID;
864 user_data = provider_buffer_user_data(handle);
866 return LB_STATUS_ERROR_INVALID;
869 if (!user_data->accelerated) {
870 return LB_STATUS_SUCCESS;
873 pkgname = provider_buffer_pkgname(handle);
875 ErrPrint("Invalid buffer handle\n");
876 return LB_STATUS_ERROR_INVALID;
879 id = provider_buffer_id(handle);
881 ErrPrint("Invalid buffer handler\n");
882 return LB_STATUS_ERROR_INVALID;
885 ret = provider_buffer_post_render(handle);
887 ErrPrint("Failed to post render processing\n");
891 if (user_data->is_pd == 1) {
892 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
893 ErrPrint("Failed to send PD updated (%s)\n", id);
900 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
901 ErrPrint("Failed to get size (%s)\n", id);
904 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
905 ErrPrint("Failed to send updated (%s)\n", id);
909 return LB_STATUS_SUCCESS;
912 PUBLIC int livebox_content_is_updated(const char *filename, int is_pd)
914 if (!s_info.trigger_update_monitor) {
915 s_info.trigger_update_monitor = dlsym(RTLD_DEFAULT, "livebox_trigger_update_monitor");
916 if (!s_info.trigger_update_monitor) {
917 ErrPrint("Trigger update monitor function is not exists\n");
918 return LB_STATUS_ERROR_FAULT;
922 return s_info.trigger_update_monitor(filename, is_pd);