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 {
71 PUBLIC const int DONE = 0x00;
72 PUBLIC const int OUTPUT_UPDATED = 0x02;
73 PUBLIC const int USE_NET = 0x04;
75 PUBLIC const int NEED_TO_SCHEDULE = 0x01;
76 PUBLIC const int NEED_TO_CREATE = 0x01;
77 PUBLIC const int NEED_TO_DESTROY = 0x01;
78 PUBLIC const int NEED_TO_UPDATE = 0x01;
80 PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
81 PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
82 PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
83 PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
84 PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
85 PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
86 PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
88 PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
90 struct livebox_desc *handle;
93 handle = calloc(1, sizeof(*handle));
95 ErrPrint("Error: %s\n", strerror(errno));
101 len = strlen(filename) + strlen(".desc") + 1;
102 new_fname = malloc(len);
104 ErrPrint("Error: %s\n", strerror(errno));
108 snprintf(new_fname, len, "%s.desc", filename);
110 new_fname = strdup(filename);
112 ErrPrint("Error: %s\n", strerror(errno));
118 DbgPrint("Open a file %s with merge mode %s\n",
120 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
122 handle->fp = fopen(new_fname, "at");
125 ErrPrint("Failed to open a file: %s\n", strerror(errno));
133 PUBLIC int livebox_desc_close(struct livebox_desc *handle)
140 return LB_STATUS_ERROR_INVALID;
142 DbgPrint("Close and flush\n");
143 dlist_foreach_safe(handle->block_list, l, n, block) {
144 handle->block_list = dlist_remove(handle->block_list, l);
147 fprintf(handle->fp, "{\n");
149 fprintf(handle->fp, "type=%s\n", block->type);
150 DbgPrint("type=%s\n", block->type);
154 fprintf(handle->fp, "part=%s\n", block->part);
155 DbgPrint("part=%s\n", block->part);
159 fprintf(handle->fp, "data=%s\n", block->data);
160 DbgPrint("data=%s\n", block->data);
164 fprintf(handle->fp, "option=%s\n", block->option);
165 DbgPrint("option=%s\n", block->option);
169 fprintf(handle->fp, "id=%s\n", block->id);
170 DbgPrint("id=%s\n", block->id);
173 if (block->target_id) {
174 fprintf(handle->fp, "target=%s\n", block->target_id);
175 DbgPrint("target=%s\n", block->target_id);
178 fprintf(handle->fp, "}\n");
186 free(block->target_id);
192 return LB_STATUS_SUCCESS;
195 PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
199 if (!handle || !category)
200 return LB_STATUS_ERROR_INVALID;
202 block = calloc(1, sizeof(*block));
204 return LB_STATUS_ERROR_MEMORY;
206 block->type = strdup(LB_DESC_TYPE_INFO);
209 return LB_STATUS_ERROR_MEMORY;
212 block->part = strdup("category");
216 return LB_STATUS_ERROR_MEMORY;
219 block->data = strdup(category);
224 return LB_STATUS_ERROR_MEMORY;
228 block->id = strdup(id);
234 return LB_STATUS_ERROR_MEMORY;
238 block->idx = handle->last_idx++;
239 handle->block_list = dlist_append(handle->block_list, block);
243 PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
249 return LB_STATUS_ERROR_INVALID;
251 block = calloc(1, sizeof(*block));
253 return LB_STATUS_ERROR_MEMORY;
255 block->type = strdup(LB_DESC_TYPE_INFO);
258 return LB_STATUS_ERROR_MEMORY;
261 block->part = strdup("size");
265 return LB_STATUS_ERROR_MEMORY;
269 block->id = strdup(id);
274 return LB_STATUS_ERROR_MEMORY;
278 snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
279 block->data = strdup(buffer);
284 return LB_STATUS_ERROR_MEMORY;
287 block->idx = handle->last_idx++;
288 handle->block_list = dlist_append(handle->block_list, block);
292 PUBLIC char *livebox_util_nl2br(const char *str)
306 ret = malloc(len + 1);
319 tmp = realloc(ret, len + 1);
346 PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
351 dlist_foreach(handle->block_list, l, block) {
352 if (block->idx == idx) {
353 if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
354 ErrPrint("Invalid block is used\n");
355 return LB_STATUS_ERROR_INVALID;
358 free(block->target_id);
359 block->target_id = NULL;
361 if (!id || !strlen(id))
362 return LB_STATUS_SUCCESS;
364 block->target_id = strdup(id);
365 if (!block->target_id) {
366 ErrPrint("Heap: %s\n", strerror(errno));
367 return LB_STATUS_ERROR_MEMORY;
370 return LB_STATUS_SUCCESS;
374 return LB_STATUS_ERROR_NOT_EXIST;
380 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)
384 if (!handle || !type)
385 return LB_STATUS_ERROR_INVALID;
393 block = calloc(1, sizeof(*block));
395 ErrPrint("Heap: %s\n", strerror(errno));
396 return LB_STATUS_ERROR_MEMORY;
399 block->type = strdup(type);
401 ErrPrint("Heap: %s\n", strerror(errno));
403 return LB_STATUS_ERROR_MEMORY;
406 block->part = strdup(part);
408 ErrPrint("Heap: %s\n", strerror(errno));
411 return LB_STATUS_ERROR_MEMORY;
414 block->data = strdup(data);
416 ErrPrint("Heap: %s\n", strerror(errno));
420 return LB_STATUS_ERROR_MEMORY;
424 block->option = strdup(option);
425 if (!block->option) {
426 ErrPrint("Heap: %s\n", strerror(errno));
431 return LB_STATUS_ERROR_MEMORY;
436 block->id = strdup(id);
438 ErrPrint("Heap: %s\n", strerror(errno));
444 return LB_STATUS_ERROR_MEMORY;
448 block->idx = handle->last_idx++;
449 handle->block_list = dlist_append(handle->block_list, block);
453 PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
458 dlist_foreach(handle->block_list, l, block) {
459 if (block->idx == idx) {
460 handle->block_list = dlist_remove(handle->block_list, l);
466 free(block->target_id);
468 return LB_STATUS_SUCCESS;
472 return LB_STATUS_ERROR_NOT_EXIST;
475 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)
477 struct livebox_buffer_data *user_data;
479 struct livebox_buffer *handle;
483 if (!filename || !width || !height) {
484 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
488 user_data = calloc(1, sizeof(*user_data));
490 ErrPrint("Heap: %s\n", strerror(errno));
494 user_data->is_pd = is_pd;
496 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
497 uri = malloc(uri_len);
499 ErrPrint("Heap: %s\n", strerror(errno));
504 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
505 pkgname = livebox_find_pkgname(uri);
507 ErrPrint("Invalid Request\n");
513 handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), handler, data);
514 DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
517 (void)provider_buffer_set_user_data(handle, user_data);
521 PUBLIC int livebox_request_update(const char *filename)
528 ErrPrint("Invalid argument\n");
529 return LB_STATUS_ERROR_INVALID;
532 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
533 uri = malloc(uri_len);
535 ErrPrint("Heap: %s\n", strerror(errno));
536 return LB_STATUS_ERROR_MEMORY;
539 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
540 ret = livebox_request_update_by_id(uri);
545 PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
547 return provider_buffer_pixmap_id(handle);
550 PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
552 struct livebox_buffer_data *user_data;
555 return LB_STATUS_ERROR_INVALID;
557 user_data = provider_buffer_user_data(handle);
560 provider_buffer_set_user_data(handle, NULL);
563 DbgPrint("Release buffer\n");
564 return provider_buffer_release(handle);
567 PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
569 struct livebox_buffer_data *user_data;
577 user_data = provider_buffer_user_data(handle);
581 if (user_data->accelerated) {
582 DbgPrint("H/W accelerated buffer is allocated\n");
586 ret = provider_buffer_get_size(handle, &w, &h, &size);
588 data = provider_buffer_ref(handle);
589 if (data && !ret && w > 0 && h > 0 && size > 0) {
590 memset(data, 0, w * h * size);
591 provider_buffer_sync(handle);
594 DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
598 PUBLIC int livebox_unref_buffer(void *buffer)
601 return LB_STATUS_ERROR_INVALID;
603 DbgPrint("Unref buffer\n");
604 return provider_buffer_unref(buffer);
607 PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
609 struct livebox_buffer_data *user_data;
614 return LB_STATUS_ERROR_INVALID;
616 user_data = provider_buffer_user_data(handle);
618 ErrPrint("Invalid buffer\n");
619 return LB_STATUS_ERROR_INVALID;
622 if (user_data->accelerated) {
623 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
624 return LB_STATUS_SUCCESS;
627 pkgname = provider_buffer_pkgname(handle);
629 ErrPrint("Invalid buffer handler\n");
630 return LB_STATUS_ERROR_INVALID;
633 id = provider_buffer_id(handle);
635 ErrPrint("Invalid buffer handler\n");
636 return LB_STATUS_ERROR_INVALID;
639 provider_buffer_sync(handle);
641 if (user_data->is_pd) {
642 if (provider_send_desc_updated(pkgname, id, NULL) < 0)
643 ErrPrint("Failed to send PD updated (%s)\n", id);
649 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
650 ErrPrint("Failed to get size (%s)\n", id);
652 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
653 ErrPrint("Failed to send updated (%s)\n", id);
656 return LB_STATUS_SUCCESS;
659 PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
662 return LB_STATUS_ERROR_INVALID;
664 return provider_buffer_pixmap_is_support_hw(handle);
667 PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
669 struct livebox_buffer_data *user_data;
673 return LB_STATUS_ERROR_INVALID;
675 user_data = provider_buffer_user_data(handle);
677 return LB_STATUS_ERROR_INVALID;
679 if (user_data->accelerated)
682 ret = provider_buffer_pixmap_create_hw(handle);
683 user_data->accelerated = (ret == 0);
687 PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
689 struct livebox_buffer_data *user_data;
691 return LB_STATUS_ERROR_INVALID;
693 user_data = provider_buffer_user_data(handle);
694 if (!user_data || !user_data->accelerated)
695 return LB_STATUS_ERROR_INVALID;
697 user_data->accelerated = 0;
699 return provider_buffer_pixmap_destroy_hw(handle);
702 PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
704 struct livebox_buffer_data *user_data;
709 user_data = provider_buffer_user_data(handle);
710 if (!user_data || !user_data->accelerated)
713 return provider_buffer_pixmap_hw_addr(handle);
716 PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
718 struct livebox_buffer_data *user_data;
721 return LB_STATUS_ERROR_INVALID;
723 user_data = provider_buffer_user_data(handle);
725 return LB_STATUS_ERROR_INVALID;
727 if (!user_data->accelerated)
728 return LB_STATUS_SUCCESS;
732 * Do preprocessing for accessing the H/W render buffer
734 return provider_buffer_pre_render(handle);
737 PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
742 struct livebox_buffer_data *user_data;
745 return LB_STATUS_ERROR_INVALID;
747 user_data = provider_buffer_user_data(handle);
749 return LB_STATUS_ERROR_INVALID;
751 if (!user_data->accelerated)
752 return LB_STATUS_SUCCESS;
754 pkgname = provider_buffer_pkgname(handle);
756 ErrPrint("Invalid buffer handle\n");
757 return LB_STATUS_ERROR_INVALID;
760 id = provider_buffer_id(handle);
762 ErrPrint("Invalid buffer handler\n");
763 return LB_STATUS_ERROR_INVALID;
766 ret = provider_buffer_post_render(handle);
768 ErrPrint("Failed to post render processing\n");
772 if (user_data->is_pd == 1) {
773 if (provider_send_desc_updated(pkgname, id, NULL) < 0)
774 ErrPrint("Failed to send PD updated (%s)\n", id);
780 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
781 ErrPrint("Failed to get size (%s)\n", id);
783 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
784 ErrPrint("Failed to send updated (%s)\n", id);
787 return LB_STATUS_SUCCESS;