/*
* Copyright 2013 Samsung Electronics Co., Ltd
*
- * Licensed under the Flora License, Version 1.0 (the "License");
+ * Licensed under the Flora License, Version 1.1 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.tizenopensource.org/license
+ * http://floralicense.org/license/
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
#include <stdlib.h> /* malloc */
#include <string.h> /* strdup */
#include <libgen.h>
+#include <unistd.h> /* access */
+#define __USE_GNU
+#include <dlfcn.h>
#include <dlog.h>
#include <livebox-service.h>
#include "dlist.h"
#include "util.h"
-#define EAPI __attribute__((visibility("default")))
+#define PUBLIC __attribute__((visibility("default")))
#define FILE_SCHEMA "file://"
/*!
* \brief This function is defined by the data-provider-slave
*/
-extern const char *livebox_find_pkgname(const char *filename);
-extern int livebox_request_update_by_id(const char *uri);
+static struct info {
+ const char *(*find_pkgname)(const char *filename);
+ int (*request_update_by_id)(const char *uri);
+ int (*trigger_update_monitor)(const char *id, int is_pd);
+} s_info = {
+ .find_pkgname = NULL,
+ .request_update_by_id = NULL,
+ .trigger_update_monitor = NULL,
+};
struct block {
unsigned int idx;
struct livebox_buffer_data {
int is_pd;
int accelerated;
+
+ /* for Buffer event wrapper */
+ int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
+ void *cbdata;
};
-EAPI const int DONE = 0x00;
-EAPI const int OUTPUT_UPDATED = 0x02;
-EAPI const int USE_NET = 0x04;
+PUBLIC const int DONE = 0x00;
+PUBLIC const int OUTPUT_UPDATED = 0x02;
+PUBLIC const int USE_NET = 0x04;
-EAPI const int NEED_TO_SCHEDULE = 0x01;
-EAPI const int NEED_TO_CREATE = 0x01;
-EAPI const int NEED_TO_DESTROY = 0x01;
-EAPI const int NEED_TO_UPDATE = 0x01;
+PUBLIC const int NEED_TO_SCHEDULE = 0x01;
+PUBLIC const int NEED_TO_CREATE = 0x01;
+PUBLIC const int NEED_TO_DESTROY = 0x01;
+PUBLIC const int NEED_TO_UPDATE = 0x01;
-EAPI const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
-EAPI const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
-EAPI const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
-EAPI const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
-EAPI const int LB_SYS_EVENT_PAUSED = 0x0100;
-EAPI const int LB_SYS_EVENT_RESUMED = 0x0200;
+PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
+PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
+PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
+PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
+PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
+PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
+PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
-EAPI struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
+PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
{
struct livebox_desc *handle;
char *new_fname;
}
}
- DbgPrint("Open a new file: %s\n", new_fname);
- handle->fp = fopen(new_fname, "w+t");
+ DbgPrint("Open a file %s with merge mode %s\n",
+ new_fname,
+ access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
+
+ handle->fp = fopen(new_fname, "at");
free(new_fname);
if (!handle->fp) {
ErrPrint("Failed to open a file: %s\n", strerror(errno));
return handle;
}
-EAPI int livebox_desc_close(struct livebox_desc *handle)
+PUBLIC int livebox_desc_close(struct livebox_desc *handle)
{
struct dlist *l;
struct dlist *n;
struct block *block;
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
- DbgPrint("Close and flush\n");
dlist_foreach_safe(handle->block_list, l, n, block) {
handle->block_list = dlist_remove(handle->block_list, l);
- DbgPrint("{\n");
fprintf(handle->fp, "{\n");
if (block->type) {
fprintf(handle->fp, "type=%s\n", block->type);
- DbgPrint("type=%s\n", block->type);
}
if (block->part) {
fprintf(handle->fp, "part=%s\n", block->part);
- DbgPrint("part=%s\n", block->part);
}
if (block->data) {
fprintf(handle->fp, "data=%s\n", block->data);
- DbgPrint("data=%s\n", block->data);
}
if (block->option) {
fprintf(handle->fp, "option=%s\n", block->option);
- DbgPrint("option=%s\n", block->option);
}
if (block->id) {
fprintf(handle->fp, "id=%s\n", block->id);
- DbgPrint("id=%s\n", block->id);
}
if (block->target_id) {
fprintf(handle->fp, "target=%s\n", block->target_id);
- DbgPrint("target=%s\n", block->target_id);
}
-
fprintf(handle->fp, "}\n");
- DbgPrint("}\n");
free(block->type);
free(block->part);
free(block);
}
- fclose(handle->fp);
+ if (fclose(handle->fp) != 0) {
+ ErrPrint("fclose: %s\n", strerror(errno));
+ }
free(handle);
return LB_STATUS_SUCCESS;
}
-EAPI int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
+PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
{
struct block *block;
- if (!handle || !category)
+ if (!handle || !category) {
return LB_STATUS_ERROR_INVALID;
+ }
block = calloc(1, sizeof(*block));
- if (!block)
+ if (!block) {
return LB_STATUS_ERROR_MEMORY;
+ }
block->type = strdup(LB_DESC_TYPE_INFO);
if (!block->type) {
return block->idx;
}
-EAPI int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
+PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
{
struct block *block;
char buffer[BUFSIZ];
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
block = calloc(1, sizeof(*block));
- if (!block)
+ if (!block) {
return LB_STATUS_ERROR_MEMORY;
+ }
block->type = strdup(LB_DESC_TYPE_INFO);
if (!block->type) {
return block->idx;
}
-EAPI char *livebox_util_nl2br(const char *str)
+PUBLIC char *livebox_util_nl2br(const char *str)
{
int len;
register int i;
char *ret;
char *ptr;
- if (!str)
+ if (!str) {
return NULL;
+ }
len = strlen(str);
- if (!len)
+ if (!len) {
return NULL;
+ }
ret = malloc(len + 1);
- if (!ret)
+ if (!ret) {
return NULL;
+ }
ptr = ret;
i = 0;
return ret;
}
-EAPI int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
+PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
{
struct dlist *l;
struct block *block;
free(block->target_id);
block->target_id = NULL;
- if (!id || !strlen(id))
+ if (!id || !strlen(id)) {
return LB_STATUS_SUCCESS;
+ }
block->target_id = strdup(id);
if (!block->target_id) {
/*!
* \return idx
*/
-EAPI int livebox_desc_add_block(struct livebox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
+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)
{
struct block *block;
- if (!handle || !type)
+ if (!handle || !type) {
return LB_STATUS_ERROR_INVALID;
+ }
- if (!part)
+ if (!part) {
part = "";
+ }
- if (!data)
+ if (!data) {
data = "";
+ }
block = calloc(1, sizeof(*block));
if (!block) {
return block->idx;
}
-EAPI int livebox_desc_del_block(struct livebox_desc *handle, int idx)
+PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
{
struct dlist *l;
struct block *block;
return LB_STATUS_ERROR_NOT_EXIST;
}
-EAPI 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)
+/*!
+ * \note
+ * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
+ */
+static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
+{
+ const char *pkgname;
+ const char *id;
+ struct livebox_buffer_data *cbdata = data;
+ int ret;
+
+ pkgname = provider_buffer_pkgname(buffer);
+ if (!pkgname) {
+ ErrPrint("pkgname is not valid\n");
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ id = provider_buffer_id(buffer);
+ if (!id) {
+ ErrPrint("id is not valid[%s]\n", pkgname);
+ return LB_STATUS_ERROR_INVALID;
+ }
+
+ ret = cbdata->handler(buffer, event, timestamp, x, y, cbdata->cbdata);
+
+ switch (event) {
+ case BUFFER_EVENT_HIGHLIGHT:
+ case BUFFER_EVENT_HIGHLIGHT_NEXT:
+ case BUFFER_EVENT_HIGHLIGHT_PREV:
+ case BUFFER_EVENT_ACTIVATE:
+ case BUFFER_EVENT_ACTION_UP:
+ case BUFFER_EVENT_ACTION_DOWN:
+ case BUFFER_EVENT_SCROLL_UP:
+ case BUFFER_EVENT_SCROLL_MOVE:
+ case BUFFER_EVENT_SCROLL_DOWN:
+ case BUFFER_EVENT_UNHIGHLIGHT:
+ DbgPrint("Accessibility event: %d\n", event);
+ if (ret < 0) {
+ (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
+ } else {
+ (void)provider_send_access_status(pkgname, id, ret);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
+{
+ /* NOP */
+ return 0;
+}
+
+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)
{
struct livebox_buffer_data *user_data;
const char *pkgname;
}
user_data->is_pd = is_pd;
+ user_data->handler = handler ? handler : default_event_handler;
+ user_data->cbdata = data;
uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
uri = malloc(uri_len);
}
snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
- pkgname = livebox_find_pkgname(uri);
+ if (!s_info.find_pkgname) {
+ s_info.find_pkgname = dlsym(RTLD_DEFAULT, "livebox_find_pkgname");
+ if (!s_info.find_pkgname) {
+ ErrPrint("Failed to find a \"livebox_find_pkgname\"\n");
+ free(user_data);
+ free(uri);
+ return NULL;
+ }
+ }
+
+ pkgname = s_info.find_pkgname(uri);
if (!pkgname) {
ErrPrint("Invalid Request\n");
free(user_data);
return NULL;
}
- handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), handler, data);
+ handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
free(uri);
+ if (!handle) {
+ free(user_data);
+ return NULL;
+ }
(void)provider_buffer_set_user_data(handle, user_data);
return handle;
}
-EAPI int livebox_request_update(const char *filename)
+PUBLIC int livebox_request_update(const char *filename)
{
int uri_len;
char *uri;
}
snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
- ret = livebox_request_update_by_id(uri);
+ if (!s_info.request_update_by_id) {
+ s_info.request_update_by_id = dlsym(RTLD_DEFAULT, "livebox_request_update_by_id");
+ if (!s_info.request_update_by_id) {
+ ErrPrint("\"livebox_request_update_by_id\" is not exists\n");
+ free(uri);
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+ ret = s_info.request_update_by_id(uri);
free(uri);
return ret;
}
-EAPI unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
+PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
{
return provider_buffer_pixmap_id(handle);
}
-EAPI int livebox_release_buffer(struct livebox_buffer *handle)
+PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
{
struct livebox_buffer_data *user_data;
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
user_data = provider_buffer_user_data(handle);
if (user_data) {
return provider_buffer_release(handle);
}
-EAPI void *livebox_ref_buffer(struct livebox_buffer *handle)
+PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
{
struct livebox_buffer_data *user_data;
void *data;
int w, h, size;
int ret;
- if (!handle)
+ if (!handle) {
return NULL;
+ }
user_data = provider_buffer_user_data(handle);
- if (!user_data)
+ if (!user_data) {
return NULL;
+ }
if (user_data->accelerated) {
DbgPrint("H/W accelerated buffer is allocated\n");
return data;
}
-EAPI int livebox_unref_buffer(void *buffer)
+PUBLIC int livebox_unref_buffer(void *buffer)
{
- if (!buffer)
+ if (!buffer) {
return LB_STATUS_ERROR_INVALID;
+ }
DbgPrint("Unref buffer\n");
return provider_buffer_unref(buffer);
}
-EAPI int livebox_sync_buffer(struct livebox_buffer *handle)
+PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
{
struct livebox_buffer_data *user_data;
const char *pkgname;
const char *id;
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
user_data = provider_buffer_user_data(handle);
if (!user_data) {
provider_buffer_sync(handle);
if (user_data->is_pd) {
- if (provider_send_desc_updated(pkgname, id, NULL) < 0)
+ if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
ErrPrint("Failed to send PD updated (%s)\n", id);
+ }
} else {
int w;
int h;
int pixel_size;
- if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
+ if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
ErrPrint("Failed to get size (%s)\n", id);
+ }
- if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
+ if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
ErrPrint("Failed to send updated (%s)\n", id);
+ }
}
return LB_STATUS_SUCCESS;
}
-EAPI int livebox_support_hw_buffer(struct livebox_buffer *handle)
+PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
{
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
return provider_buffer_pixmap_is_support_hw(handle);
}
-EAPI int livebox_create_hw_buffer(struct livebox_buffer *handle)
+PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
{
struct livebox_buffer_data *user_data;
int ret;
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
user_data = provider_buffer_user_data(handle);
- if (!user_data)
+ if (!user_data) {
return LB_STATUS_ERROR_INVALID;
+ }
- if (user_data->accelerated)
- return -EALREADY;
+ if (user_data->accelerated) {
+ return LB_STATUS_ERROR_ALREADY;
+ }
ret = provider_buffer_pixmap_create_hw(handle);
user_data->accelerated = (ret == 0);
return ret;
}
-EAPI int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
+PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
{
struct livebox_buffer_data *user_data;
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
user_data = provider_buffer_user_data(handle);
- if (!user_data || !user_data->accelerated)
+ if (!user_data || !user_data->accelerated) {
return LB_STATUS_ERROR_INVALID;
+ }
user_data->accelerated = 0;
return provider_buffer_pixmap_destroy_hw(handle);
}
-EAPI void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
+PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
{
struct livebox_buffer_data *user_data;
- if (!handle)
+ if (!handle) {
return NULL;
+ }
user_data = provider_buffer_user_data(handle);
- if (!user_data || !user_data->accelerated)
+ if (!user_data || !user_data->accelerated) {
return NULL;
+ }
return provider_buffer_pixmap_hw_addr(handle);
}
-EAPI int livebox_buffer_pre_render(struct livebox_buffer *handle)
+PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
{
struct livebox_buffer_data *user_data;
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
user_data = provider_buffer_user_data(handle);
- if (!user_data)
+ if (!user_data) {
return LB_STATUS_ERROR_INVALID;
+ }
- if (!user_data->accelerated)
+ if (!user_data->accelerated) {
return LB_STATUS_SUCCESS;
+ }
/*!
* \note
return provider_buffer_pre_render(handle);
}
-EAPI int livebox_buffer_post_render(struct livebox_buffer *handle)
+PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
{
int ret;
const char *pkgname;
const char *id;
struct livebox_buffer_data *user_data;
- if (!handle)
+ if (!handle) {
return LB_STATUS_ERROR_INVALID;
+ }
user_data = provider_buffer_user_data(handle);
- if (!user_data)
+ if (!user_data) {
return LB_STATUS_ERROR_INVALID;
+ }
- if (!user_data->accelerated)
+ if (!user_data->accelerated) {
return LB_STATUS_SUCCESS;
+ }
pkgname = provider_buffer_pkgname(handle);
if (!pkgname) {
}
if (user_data->is_pd == 1) {
- if (provider_send_desc_updated(pkgname, id, NULL) < 0)
+ if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
ErrPrint("Failed to send PD updated (%s)\n", id);
+ }
} else {
int w;
int h;
int pixel_size;
- if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0)
+ if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
ErrPrint("Failed to get size (%s)\n", id);
+ }
- if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0)
+ if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
ErrPrint("Failed to send updated (%s)\n", id);
+ }
}
return LB_STATUS_SUCCESS;
}
+PUBLIC int livebox_content_is_updated(const char *filename, int is_pd)
+{
+ if (!s_info.trigger_update_monitor) {
+ s_info.trigger_update_monitor = dlsym(RTLD_DEFAULT, "livebox_trigger_update_monitor");
+ if (!s_info.trigger_update_monitor) {
+ ErrPrint("Trigger update monitor function is not exists\n");
+ return LB_STATUS_ERROR_FAULT;
+ }
+ }
+
+ return s_info.trigger_update_monitor(filename, is_pd);
+}
+
/* End of a file */