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);
44 extern int livebox_trigger_update_monitor(const char *id, int is_pd);
62 unsigned int last_idx;
64 struct dlist *block_list;
67 struct livebox_buffer_data {
71 /* for Buffer event wrapper */
72 int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
76 PUBLIC const int DONE = 0x00;
77 PUBLIC const int OUTPUT_UPDATED = 0x02;
78 PUBLIC const int USE_NET = 0x04;
80 PUBLIC const int NEED_TO_SCHEDULE = 0x01;
81 PUBLIC const int NEED_TO_CREATE = 0x01;
82 PUBLIC const int NEED_TO_DESTROY = 0x01;
83 PUBLIC const int NEED_TO_UPDATE = 0x01;
85 PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
86 PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
87 PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
88 PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
89 PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
90 PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
91 PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
93 PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
95 struct livebox_desc *handle;
98 handle = calloc(1, sizeof(*handle));
100 ErrPrint("Error: %s\n", strerror(errno));
106 len = strlen(filename) + strlen(".desc") + 1;
107 new_fname = malloc(len);
109 ErrPrint("Error: %s\n", strerror(errno));
113 snprintf(new_fname, len, "%s.desc", filename);
115 new_fname = strdup(filename);
117 ErrPrint("Error: %s\n", strerror(errno));
123 DbgPrint("Open a file %s with merge mode %s\n",
125 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
127 handle->fp = fopen(new_fname, "at");
130 ErrPrint("Failed to open a file: %s\n", strerror(errno));
138 PUBLIC int livebox_desc_close(struct livebox_desc *handle)
145 return LB_STATUS_ERROR_INVALID;
148 dlist_foreach_safe(handle->block_list, l, n, block) {
149 handle->block_list = dlist_remove(handle->block_list, l);
151 fprintf(handle->fp, "{\n");
153 fprintf(handle->fp, "type=%s\n", block->type);
157 fprintf(handle->fp, "part=%s\n", block->part);
161 fprintf(handle->fp, "data=%s\n", block->data);
165 fprintf(handle->fp, "option=%s\n", block->option);
169 fprintf(handle->fp, "id=%s\n", block->id);
172 if (block->target_id) {
173 fprintf(handle->fp, "target=%s\n", block->target_id);
175 fprintf(handle->fp, "}\n");
182 free(block->target_id);
186 if (fclose(handle->fp) != 0) {
187 ErrPrint("fclose: %s\n", strerror(errno));
190 return LB_STATUS_SUCCESS;
193 PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
197 if (!handle || !category) {
198 return LB_STATUS_ERROR_INVALID;
201 block = calloc(1, sizeof(*block));
203 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;
252 block = calloc(1, sizeof(*block));
254 return LB_STATUS_ERROR_MEMORY;
257 block->type = strdup(LB_DESC_TYPE_INFO);
260 return LB_STATUS_ERROR_MEMORY;
263 block->part = strdup("size");
267 return LB_STATUS_ERROR_MEMORY;
271 block->id = strdup(id);
276 return LB_STATUS_ERROR_MEMORY;
280 snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
281 block->data = strdup(buffer);
286 return LB_STATUS_ERROR_MEMORY;
289 block->idx = handle->last_idx++;
290 handle->block_list = dlist_append(handle->block_list, block);
294 PUBLIC char *livebox_util_nl2br(const char *str)
310 ret = malloc(len + 1);
324 tmp = realloc(ret, len + 1);
351 PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
356 dlist_foreach(handle->block_list, l, block) {
357 if (block->idx == idx) {
358 if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
359 ErrPrint("Invalid block is used\n");
360 return LB_STATUS_ERROR_INVALID;
363 free(block->target_id);
364 block->target_id = NULL;
366 if (!id || !strlen(id)) {
367 return LB_STATUS_SUCCESS;
370 block->target_id = strdup(id);
371 if (!block->target_id) {
372 ErrPrint("Heap: %s\n", strerror(errno));
373 return LB_STATUS_ERROR_MEMORY;
376 return LB_STATUS_SUCCESS;
380 return LB_STATUS_ERROR_NOT_EXIST;
386 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)
390 if (!handle || !type) {
391 return LB_STATUS_ERROR_INVALID;
402 block = calloc(1, sizeof(*block));
404 ErrPrint("Heap: %s\n", strerror(errno));
405 return LB_STATUS_ERROR_MEMORY;
408 block->type = strdup(type);
410 ErrPrint("Heap: %s\n", strerror(errno));
412 return LB_STATUS_ERROR_MEMORY;
415 block->part = strdup(part);
417 ErrPrint("Heap: %s\n", strerror(errno));
420 return LB_STATUS_ERROR_MEMORY;
423 block->data = strdup(data);
425 ErrPrint("Heap: %s\n", strerror(errno));
429 return LB_STATUS_ERROR_MEMORY;
433 block->option = strdup(option);
434 if (!block->option) {
435 ErrPrint("Heap: %s\n", strerror(errno));
440 return LB_STATUS_ERROR_MEMORY;
445 block->id = strdup(id);
447 ErrPrint("Heap: %s\n", strerror(errno));
453 return LB_STATUS_ERROR_MEMORY;
457 block->idx = handle->last_idx++;
458 handle->block_list = dlist_append(handle->block_list, block);
462 PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
467 dlist_foreach(handle->block_list, l, block) {
468 if (block->idx == idx) {
469 handle->block_list = dlist_remove(handle->block_list, l);
475 free(block->target_id);
477 return LB_STATUS_SUCCESS;
481 return LB_STATUS_ERROR_NOT_EXIST;
486 * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
488 static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
492 struct livebox_buffer_data *cbdata = data;
495 pkgname = provider_buffer_pkgname(buffer);
497 ErrPrint("pkgname is not valid\n");
498 return LB_STATUS_ERROR_INVALID;
501 id = provider_buffer_id(buffer);
503 ErrPrint("id is not valid[%s]\n", pkgname);
504 return LB_STATUS_ERROR_INVALID;
507 ret = cbdata->handler(buffer, event, timestamp, x, y, cbdata->cbdata);
510 case BUFFER_EVENT_HIGHLIGHT:
511 case BUFFER_EVENT_HIGHLIGHT_NEXT:
512 case BUFFER_EVENT_HIGHLIGHT_PREV:
513 case BUFFER_EVENT_ACTIVATE:
514 case BUFFER_EVENT_ACTION_UP:
515 case BUFFER_EVENT_ACTION_DOWN:
516 case BUFFER_EVENT_SCROLL_UP:
517 case BUFFER_EVENT_SCROLL_MOVE:
518 case BUFFER_EVENT_SCROLL_DOWN:
519 case BUFFER_EVENT_UNHIGHLIGHT:
520 DbgPrint("Accessibility event: %d\n", event);
522 (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
524 (void)provider_send_access_status(pkgname, id, ret);
534 static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
540 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)
542 struct livebox_buffer_data *user_data;
544 struct livebox_buffer *handle;
547 struct event_cbdata *cbdata;
549 if (!filename || !width || !height) {
550 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
554 user_data = calloc(1, sizeof(*user_data));
556 ErrPrint("Heap: %s\n", strerror(errno));
560 user_data->is_pd = is_pd;
561 user_data->handler = handler ? handler : default_event_handler;
562 user_data->cbdata = data;
564 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
565 uri = malloc(uri_len);
567 ErrPrint("Heap: %s\n", strerror(errno));
572 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
573 pkgname = livebox_find_pkgname(uri);
575 ErrPrint("Invalid Request\n");
581 handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
582 DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
589 (void)provider_buffer_set_user_data(handle, user_data);
593 PUBLIC int livebox_request_update(const char *filename)
600 ErrPrint("Invalid argument\n");
601 return LB_STATUS_ERROR_INVALID;
604 uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
605 uri = malloc(uri_len);
607 ErrPrint("Heap: %s\n", strerror(errno));
608 return LB_STATUS_ERROR_MEMORY;
611 snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
612 ret = livebox_request_update_by_id(uri);
617 PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
619 return provider_buffer_pixmap_id(handle);
622 PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
624 struct livebox_buffer_data *user_data;
627 return LB_STATUS_ERROR_INVALID;
630 user_data = provider_buffer_user_data(handle);
633 provider_buffer_set_user_data(handle, NULL);
636 DbgPrint("Release buffer\n");
637 return provider_buffer_release(handle);
640 PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
642 struct livebox_buffer_data *user_data;
651 user_data = provider_buffer_user_data(handle);
656 if (user_data->accelerated) {
657 DbgPrint("H/W accelerated buffer is allocated\n");
661 ret = provider_buffer_get_size(handle, &w, &h, &size);
663 data = provider_buffer_ref(handle);
664 if (data && !ret && w > 0 && h > 0 && size > 0) {
665 memset(data, 0, w * h * size);
666 provider_buffer_sync(handle);
669 DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
673 PUBLIC int livebox_unref_buffer(void *buffer)
676 return LB_STATUS_ERROR_INVALID;
679 DbgPrint("Unref buffer\n");
680 return provider_buffer_unref(buffer);
683 PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
685 struct livebox_buffer_data *user_data;
690 return LB_STATUS_ERROR_INVALID;
693 user_data = provider_buffer_user_data(handle);
695 ErrPrint("Invalid buffer\n");
696 return LB_STATUS_ERROR_INVALID;
699 if (user_data->accelerated) {
700 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
701 return LB_STATUS_SUCCESS;
704 pkgname = provider_buffer_pkgname(handle);
706 ErrPrint("Invalid buffer handler\n");
707 return LB_STATUS_ERROR_INVALID;
710 id = provider_buffer_id(handle);
712 ErrPrint("Invalid buffer handler\n");
713 return LB_STATUS_ERROR_INVALID;
716 provider_buffer_sync(handle);
718 if (user_data->is_pd) {
719 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
720 ErrPrint("Failed to send PD updated (%s)\n", id);
727 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
728 ErrPrint("Failed to get size (%s)\n", id);
731 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
732 ErrPrint("Failed to send updated (%s)\n", id);
736 return LB_STATUS_SUCCESS;
739 PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
742 return LB_STATUS_ERROR_INVALID;
745 return provider_buffer_pixmap_is_support_hw(handle);
748 PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
750 struct livebox_buffer_data *user_data;
754 return LB_STATUS_ERROR_INVALID;
757 user_data = provider_buffer_user_data(handle);
759 return LB_STATUS_ERROR_INVALID;
762 if (user_data->accelerated) {
763 return LB_STATUS_ERROR_ALREADY;
766 ret = provider_buffer_pixmap_create_hw(handle);
767 user_data->accelerated = (ret == 0);
771 PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
773 struct livebox_buffer_data *user_data;
775 return LB_STATUS_ERROR_INVALID;
778 user_data = provider_buffer_user_data(handle);
779 if (!user_data || !user_data->accelerated) {
780 return LB_STATUS_ERROR_INVALID;
783 user_data->accelerated = 0;
785 return provider_buffer_pixmap_destroy_hw(handle);
788 PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
790 struct livebox_buffer_data *user_data;
796 user_data = provider_buffer_user_data(handle);
797 if (!user_data || !user_data->accelerated) {
801 return provider_buffer_pixmap_hw_addr(handle);
804 PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
806 struct livebox_buffer_data *user_data;
809 return LB_STATUS_ERROR_INVALID;
812 user_data = provider_buffer_user_data(handle);
814 return LB_STATUS_ERROR_INVALID;
817 if (!user_data->accelerated) {
818 return LB_STATUS_SUCCESS;
823 * Do preprocessing for accessing the H/W render buffer
825 return provider_buffer_pre_render(handle);
828 PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
833 struct livebox_buffer_data *user_data;
836 return LB_STATUS_ERROR_INVALID;
839 user_data = provider_buffer_user_data(handle);
841 return LB_STATUS_ERROR_INVALID;
844 if (!user_data->accelerated) {
845 return LB_STATUS_SUCCESS;
848 pkgname = provider_buffer_pkgname(handle);
850 ErrPrint("Invalid buffer handle\n");
851 return LB_STATUS_ERROR_INVALID;
854 id = provider_buffer_id(handle);
856 ErrPrint("Invalid buffer handler\n");
857 return LB_STATUS_ERROR_INVALID;
860 ret = provider_buffer_post_render(handle);
862 ErrPrint("Failed to post render processing\n");
866 if (user_data->is_pd == 1) {
867 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
868 ErrPrint("Failed to send PD updated (%s)\n", id);
875 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
876 ErrPrint("Failed to get size (%s)\n", id);
879 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
880 ErrPrint("Failed to send updated (%s)\n", id);
884 return LB_STATUS_SUCCESS;
887 PUBLIC int livebox_content_is_updated(const char *filename, int is_pd)
889 return livebox_trigger_update_monitor(filename, is_pd);