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 */
25 #include <livebox-service.h>
27 #include <provider_buffer.h>
28 #include <livebox-errno.h>
35 #define PUBLIC __attribute__((visibility("default")))
37 #define FILE_SCHEMA "file://"
40 * \brief This function is defined by the data-provider-slave
42 extern const char *livebox_find_pkgname(const char *filename);
43 extern int livebox_request_update_by_id(const char *uri);
61 unsigned int last_idx;
63 struct dlist *block_list;
66 struct livebox_buffer_data {
70 /* for Buffer event wrapper */
71 int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
75 PUBLIC const int DONE = 0x00;
76 PUBLIC const int OUTPUT_UPDATED = 0x02;
77 PUBLIC const int USE_NET = 0x04;
79 PUBLIC const int NEED_TO_SCHEDULE = 0x01;
80 PUBLIC const int NEED_TO_CREATE = 0x01;
81 PUBLIC const int NEED_TO_DESTROY = 0x01;
82 PUBLIC const int NEED_TO_UPDATE = 0x01;
84 PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
85 PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
86 PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
87 PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
88 PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
89 PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
90 PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
92 PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
94 struct livebox_desc *handle;
97 handle = calloc(1, sizeof(*handle));
99 ErrPrint("Error: %s\n", strerror(errno));
105 len = strlen(filename) + strlen(".desc") + 1;
106 new_fname = malloc(len);
108 ErrPrint("Error: %s\n", strerror(errno));
112 snprintf(new_fname, len, "%s.desc", filename);
114 new_fname = strdup(filename);
116 ErrPrint("Error: %s\n", strerror(errno));
122 DbgPrint("Open a file %s with merge mode %s\n",
124 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
126 handle->fp = fopen(new_fname, "at");
129 ErrPrint("Failed to open a file: %s\n", strerror(errno));
137 PUBLIC int livebox_desc_close(struct livebox_desc *handle)
144 return LB_STATUS_ERROR_INVALID;
146 DbgPrint("Close and flush\n");
147 dlist_foreach_safe(handle->block_list, l, n, block) {
148 handle->block_list = dlist_remove(handle->block_list, l);
151 fprintf(handle->fp, "{\n");
153 fprintf(handle->fp, "type=%s\n", block->type);
154 DbgPrint("type=%s\n", block->type);
158 fprintf(handle->fp, "part=%s\n", block->part);
159 DbgPrint("part=%s\n", block->part);
163 fprintf(handle->fp, "data=%s\n", block->data);
164 DbgPrint("data=%s\n", block->data);
168 fprintf(handle->fp, "option=%s\n", block->option);
169 DbgPrint("option=%s\n", block->option);
173 fprintf(handle->fp, "id=%s\n", block->id);
174 DbgPrint("id=%s\n", block->id);
177 if (block->target_id) {
178 fprintf(handle->fp, "target=%s\n", block->target_id);
179 DbgPrint("target=%s\n", block->target_id);
182 fprintf(handle->fp, "}\n");
190 free(block->target_id);
196 return LB_STATUS_SUCCESS;
199 PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
203 if (!handle || !category)
204 return LB_STATUS_ERROR_INVALID;
206 block = calloc(1, sizeof(*block));
208 return LB_STATUS_ERROR_MEMORY;
210 block->type = strdup(LB_DESC_TYPE_INFO);
213 return LB_STATUS_ERROR_MEMORY;
216 block->part = strdup("category");
220 return LB_STATUS_ERROR_MEMORY;
223 block->data = strdup(category);
228 return LB_STATUS_ERROR_MEMORY;
232 block->id = strdup(id);
238 return LB_STATUS_ERROR_MEMORY;
242 block->idx = handle->last_idx++;
243 handle->block_list = dlist_append(handle->block_list, block);
247 PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
253 return LB_STATUS_ERROR_INVALID;
255 block = calloc(1, sizeof(*block));
257 return LB_STATUS_ERROR_MEMORY;
259 block->type = strdup(LB_DESC_TYPE_INFO);
262 return LB_STATUS_ERROR_MEMORY;
265 block->part = strdup("size");
269 return LB_STATUS_ERROR_MEMORY;
273 block->id = strdup(id);
278 return LB_STATUS_ERROR_MEMORY;
282 snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
283 block->data = strdup(buffer);
288 return LB_STATUS_ERROR_MEMORY;
291 block->idx = handle->last_idx++;
292 handle->block_list = dlist_append(handle->block_list, block);
296 PUBLIC char *livebox_util_nl2br(const char *str)
310 ret = malloc(len + 1);
323 tmp = realloc(ret, len + 1);
350 PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
355 dlist_foreach(handle->block_list, l, block) {
356 if (block->idx == idx) {
357 if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
358 ErrPrint("Invalid block is used\n");
359 return LB_STATUS_ERROR_INVALID;
362 free(block->target_id);
363 block->target_id = NULL;
365 if (!id || !strlen(id))
366 return LB_STATUS_SUCCESS;
368 block->target_id = strdup(id);
369 if (!block->target_id) {
370 ErrPrint("Heap: %s\n", strerror(errno));
371 return LB_STATUS_ERROR_MEMORY;
374 return LB_STATUS_SUCCESS;
378 return LB_STATUS_ERROR_NOT_EXIST;
384 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)
388 if (!handle || !type)
389 return LB_STATUS_ERROR_INVALID;
397 block = calloc(1, sizeof(*block));
399 ErrPrint("Heap: %s\n", strerror(errno));
400 return LB_STATUS_ERROR_MEMORY;
403 block->type = strdup(type);
405 ErrPrint("Heap: %s\n", strerror(errno));
407 return LB_STATUS_ERROR_MEMORY;
410 block->part = strdup(part);
412 ErrPrint("Heap: %s\n", strerror(errno));
415 return LB_STATUS_ERROR_MEMORY;
418 block->data = strdup(data);
420 ErrPrint("Heap: %s\n", strerror(errno));
424 return LB_STATUS_ERROR_MEMORY;
428 block->option = strdup(option);
429 if (!block->option) {
430 ErrPrint("Heap: %s\n", strerror(errno));
435 return LB_STATUS_ERROR_MEMORY;
440 block->id = strdup(id);
442 ErrPrint("Heap: %s\n", strerror(errno));
448 return LB_STATUS_ERROR_MEMORY;
452 block->idx = handle->last_idx++;
453 handle->block_list = dlist_append(handle->block_list, block);
457 PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
462 dlist_foreach(handle->block_list, l, block) {
463 if (block->idx == idx) {
464 handle->block_list = dlist_remove(handle->block_list, l);
470 free(block->target_id);
472 return LB_STATUS_SUCCESS;
476 return LB_STATUS_ERROR_NOT_EXIST;
481 * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
483 static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
487 struct livebox_buffer_data *cbdata = data;
490 pkgname = provider_buffer_pkgname(buffer);
491 id = provider_buffer_pkgname(buffer);
493 ret = cbdata->handler(buffer, event, timestamp, x, y, cbdata->cbdata);
496 case BUFFER_EVENT_HIGHLIGHT:
497 case BUFFER_EVENT_HIGHLIGHT_NEXT:
498 case BUFFER_EVENT_HIGHLIGHT_PREV:
499 case BUFFER_EVENT_ACTIVATE:
500 case BUFFER_EVENT_ACTION_UP:
501 case BUFFER_EVENT_ACTION_DOWN:
502 case BUFFER_EVENT_SCROLL_UP:
503 case BUFFER_EVENT_SCROLL_MOVE:
504 case BUFFER_EVENT_SCROLL_DOWN:
505 case BUFFER_EVENT_UNHIGHLIGHT:
507 (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
509 (void)provider_send_access_status(pkgname, id, ret);
518 static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
524 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)
526 struct livebox_buffer_data *user_data;
528 struct livebox_buffer *handle;
531 struct event_cbdata *cbdata;
533 if (!filename || !width || !height) {
534 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
538 user_data = calloc(1, sizeof(*user_data));
540 ErrPrint("Heap: %s\n", strerror(errno));
544 user_data->is_pd = is_pd;
545 user_data->handler = handler ? handler : default_event_handler;
546 user_data->cbdata = data;
548 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
549 uri = malloc(uri_len);
551 ErrPrint("Heap: %s\n", strerror(errno));
556 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
557 pkgname = livebox_find_pkgname(uri);
559 ErrPrint("Invalid Request\n");
565 handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
566 DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
573 (void)provider_buffer_set_user_data(handle, user_data);
577 PUBLIC int livebox_request_update(const char *filename)
584 ErrPrint("Invalid argument\n");
585 return LB_STATUS_ERROR_INVALID;
588 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
589 uri = malloc(uri_len);
591 ErrPrint("Heap: %s\n", strerror(errno));
592 return LB_STATUS_ERROR_MEMORY;
595 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
596 ret = livebox_request_update_by_id(uri);
601 PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
603 return provider_buffer_pixmap_id(handle);
606 PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
608 struct livebox_buffer_data *user_data;
611 return LB_STATUS_ERROR_INVALID;
613 user_data = provider_buffer_user_data(handle);
616 provider_buffer_set_user_data(handle, NULL);
619 DbgPrint("Release buffer\n");
620 return provider_buffer_release(handle);
623 PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
625 struct livebox_buffer_data *user_data;
633 user_data = provider_buffer_user_data(handle);
637 if (user_data->accelerated) {
638 DbgPrint("H/W accelerated buffer is allocated\n");
642 ret = provider_buffer_get_size(handle, &w, &h, &size);
644 data = provider_buffer_ref(handle);
645 if (data && !ret && w > 0 && h > 0 && size > 0) {
646 memset(data, 0, w * h * size);
647 provider_buffer_sync(handle);
650 DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
654 PUBLIC int livebox_unref_buffer(void *buffer)
657 return LB_STATUS_ERROR_INVALID;
659 DbgPrint("Unref buffer\n");
660 return provider_buffer_unref(buffer);
663 PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
665 struct livebox_buffer_data *user_data;
670 return LB_STATUS_ERROR_INVALID;
672 user_data = provider_buffer_user_data(handle);
674 ErrPrint("Invalid buffer\n");
675 return LB_STATUS_ERROR_INVALID;
678 if (user_data->accelerated) {
679 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
680 return LB_STATUS_SUCCESS;
683 pkgname = provider_buffer_pkgname(handle);
685 ErrPrint("Invalid buffer handler\n");
686 return LB_STATUS_ERROR_INVALID;
689 id = provider_buffer_id(handle);
691 ErrPrint("Invalid buffer handler\n");
692 return LB_STATUS_ERROR_INVALID;
695 provider_buffer_sync(handle);
697 if (user_data->is_pd) {
698 if (provider_send_desc_updated(pkgname, id, NULL) < 0)
699 ErrPrint("Failed to send PD updated (%s)\n", id);
705 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
706 ErrPrint("Failed to get size (%s)\n", id);
708 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
709 ErrPrint("Failed to send updated (%s)\n", id);
712 return LB_STATUS_SUCCESS;
715 PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
718 return LB_STATUS_ERROR_INVALID;
720 return provider_buffer_pixmap_is_support_hw(handle);
723 PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
725 struct livebox_buffer_data *user_data;
729 return LB_STATUS_ERROR_INVALID;
731 user_data = provider_buffer_user_data(handle);
733 return LB_STATUS_ERROR_INVALID;
735 if (user_data->accelerated)
738 ret = provider_buffer_pixmap_create_hw(handle);
739 user_data->accelerated = (ret == 0);
743 PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
745 struct livebox_buffer_data *user_data;
747 return LB_STATUS_ERROR_INVALID;
749 user_data = provider_buffer_user_data(handle);
750 if (!user_data || !user_data->accelerated)
751 return LB_STATUS_ERROR_INVALID;
753 user_data->accelerated = 0;
755 return provider_buffer_pixmap_destroy_hw(handle);
758 PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
760 struct livebox_buffer_data *user_data;
765 user_data = provider_buffer_user_data(handle);
766 if (!user_data || !user_data->accelerated)
769 return provider_buffer_pixmap_hw_addr(handle);
772 PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
774 struct livebox_buffer_data *user_data;
777 return LB_STATUS_ERROR_INVALID;
779 user_data = provider_buffer_user_data(handle);
781 return LB_STATUS_ERROR_INVALID;
783 if (!user_data->accelerated)
784 return LB_STATUS_SUCCESS;
788 * Do preprocessing for accessing the H/W render buffer
790 return provider_buffer_pre_render(handle);
793 PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
798 struct livebox_buffer_data *user_data;
801 return LB_STATUS_ERROR_INVALID;
803 user_data = provider_buffer_user_data(handle);
805 return LB_STATUS_ERROR_INVALID;
807 if (!user_data->accelerated)
808 return LB_STATUS_SUCCESS;
810 pkgname = provider_buffer_pkgname(handle);
812 ErrPrint("Invalid buffer handle\n");
813 return LB_STATUS_ERROR_INVALID;
816 id = provider_buffer_id(handle);
818 ErrPrint("Invalid buffer handler\n");
819 return LB_STATUS_ERROR_INVALID;
822 ret = provider_buffer_post_render(handle);
824 ErrPrint("Failed to post render processing\n");
828 if (user_data->is_pd == 1) {
829 if (provider_send_desc_updated(pkgname, id, NULL) < 0)
830 ErrPrint("Failed to send PD updated (%s)\n", id);
836 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
837 ErrPrint("Failed to get size (%s)\n", id);
839 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
840 ErrPrint("Failed to send updated (%s)\n", id);
843 return LB_STATUS_SUCCESS;