From d6ed58acc3fb0a4459e9645d21f2057d8bc5417e Mon Sep 17 00:00:00 2001 From: jeon Date: Wed, 14 Aug 2019 18:53:03 +0900 Subject: [PATCH] backend: add default_backend initial codes Change-Id: Ie01ec8bb3f9b61ffd791497307cb15b56ebdd100 --- backends/Makefile.am | 4 +- backends/default_backend.c | 232 +++++++++++++++++++++++++++++++++++++++++++-- configure.ac | 7 +- packaging/libpui.spec | 1 + src/PUI_common.h | 1 + 5 files changed, 233 insertions(+), 12 deletions(-) diff --git a/backends/Makefile.am b/backends/Makefile.am index 00db99b..7ca90e7 100644 --- a/backends/Makefile.am +++ b/backends/Makefile.am @@ -8,8 +8,8 @@ AM_CFLAGS = \ libpui_default_backend_includedir=$(includedir) libpui_default_backend_include_HEADERS = -libpui_default_backend_la_CFLAGS = $(AM_CFLAGS) $(LIBPUI_BACKEND_CFLAGS) -libpui_default_backend_la_LIBADD = $(LIBPUI_BACKEND_LIBS) +libpui_default_backend_la_CFLAGS = $(AM_CFLAGS) $(DEFAULT_BACKEND_CFLAGS) +libpui_default_backend_la_LIBADD = $(DEFAULT_BACKEND_LIBS) libpui_default_backend_la_SOURCES = \ default_backend.c diff --git a/backends/default_backend.c b/backends/default_backend.c index ab13717..d626c69 100644 --- a/backends/default_backend.c +++ b/backends/default_backend.c @@ -3,6 +3,26 @@ #include #include +#include +#include +#include +#include + +#define ANI_COLLECTION_DIR "/run/pui/" +#define MAX_STR 1024 + +#define ERROR_CHECK(exp, action, fmt, ...) \ + do { \ + if (!(exp)) \ + { \ + printf(fmt, ##__VA_ARGS__); \ + action; \ + } \ + } while (0) + +pui_backend_ani_func *ani_func = NULL; +Eina_Hash *_animations_hash = NULL; + typedef enum { None, @@ -14,6 +34,9 @@ typedef enum } pui_effect_func; typedef struct _default_ani_info default_ani_info; +typedef struct _default_frame_info_t default_frame_info_t; +typedef struct _default_led_info_t default_led_info_t; + struct _default_ani_info { pui_id id; @@ -23,10 +46,22 @@ struct _default_ani_info unsigned int key_frame_idx; unsigned int num_key_frames; - double interval; + default_frame_info_t *frames; + int interval; pui_effect_func effect_func; }; +struct _default_frame_info_t +{ + default_led_info_t *leds; + int num_led; +}; + +struct _default_led_info_t +{ + unsigned int color; +}; + pui_backend_ani_data *g_ani_data = NULL; static pui_bool @@ -91,10 +126,157 @@ _ani_stop(pui_ani_t *ani) return e; } +static char * +_read_json_file(const char *path, int *data_size) +{ + FILE *fp = fopen(path, "rb"); + int size; + char *buffer; + ERROR_CHECK(fp, return NULL, "Failed to open file: %s\n", path); + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + fseek(fp, 0, SEEK_SET); + + buffer = (char *)calloc(sizeof(char), size + 1); + + if (fread(buffer, size, 1, fp) < 1) { + *data_size = 0; + free(buffer); + fclose(fp); + return NULL; + } + + *data_size = size; + fclose(fp); + return buffer; +} + +static default_ani_info * +_read_json(const char *path) +{ + char *buffer, *type; + json_object *root_obj, *data_obj, *frame_obj, *frame_data_obj, *led_obj, *led_data_obj; + default_ani_info *ani_info = NULL; + int frame_id = 0, frame_len = 0, led_id = 0, led_len = 0; + int data_size = 0, i, j; + + buffer = _read_json_file(path, &data_size); + ERROR_CHECK(buffer && data_size > 0, return EINA_FALSE, "File %s has no data\n", path); + root_obj = json_tokener_parse(buffer); + ERROR_CHECK(root_obj, goto error, "Failed to tokenize json object\n"); + + ani_info = (default_ani_info *)calloc(1, sizeof(default_ani_info)); + ERROR_CHECK(ani_info, goto error, "Failed to alloc for animation info\n"); + + data_obj = json_object_object_get(root_obj, "type"); + //printf("type: %s\n", json_object_get_string(data_obj)); + type = (char *)json_object_get_string(data_obj); + ani_info->id = strndup(type, strlen(type)); + + data_obj = json_object_object_get(root_obj, "interval"); + //printf("interval: %d\n", json_object_get_int(data_obj)); + ani_info->interval = json_object_get_int(data_obj); + + data_obj = json_object_object_get(root_obj, "frame"); + frame_len = json_object_array_length(data_obj); + + ani_info->num_key_frames = frame_len; + ani_info->frames = (default_frame_info_t *)calloc(sizeof(default_frame_info_t), frame_len); + ERROR_CHECK(ani_info->frames, goto error, "Failed to alloc for default_frame_info_t\n"); + + for (i = 0; i < frame_len; i++) { + frame_obj = json_object_array_get_idx(data_obj, i); + + frame_data_obj = json_object_object_get(frame_obj, "frame_id"); + //printf("\tframe id: %d\n", json_object_get_int(frame_data_obj)); + frame_id = json_object_get_int(frame_data_obj); + + frame_data_obj = json_object_object_get(frame_obj, "led"); + led_len = json_object_array_length(frame_data_obj); + + ani_info->frames[frame_id - 1].num_led = led_len; + ani_info->frames[frame_id - 1].leds = (default_led_info_t *)calloc(sizeof(default_led_info_t), led_len); + ERROR_CHECK(ani_info->frames[frame_id - 1].leds, goto error, "Failed to alloc for default_led_info_t\n"); + + for (j = 0; j < led_len; j++) { + led_obj = json_object_array_get_idx(frame_data_obj, j); + + led_data_obj = json_object_object_get(led_obj, "id"); + //printf("\t\tid: %2d ", json_object_get_int(led_data_obj)); + led_id = json_object_get_int(led_data_obj); + + led_data_obj = json_object_object_get(led_obj, "color"); + //printf("color: %s\n", json_object_get_string(led_data_obj)); + ani_info->frames[frame_id - 1].leds[led_id - 1].color = + strtol(json_object_get_string(led_data_obj), NULL, 16); + } + } + + free(buffer); + return ani_info; + +error: + free(buffer); + if (ani_info) { + if (ani_info->frames) { + for (i = 0; i < ani_info->num_key_frames; i++) { + if (ani_info->frames[i].leds) + free(ani_info->frames[i].leds); + } + free(ani_info->frames); + } + free(ani_info->id); + free(ani_info); + } + return NULL; +} + +static int +_scandir_filter(const struct dirent *dirent) +{ + if (!strncmp(dirent->d_name, ".", sizeof(".")) || + !strncmp(dirent->d_name, "..", sizeof(".."))) + return 0; + if (!strstr(dirent->d_name, ".json")) + return 0; + + return 1; +} + + pui_int_error _create_ani_collection(void) { pui_int_error e = PUI_INT_ERROR_NONE; + default_ani_info *ani_info; + struct dirent **files; + int count, i; + char file_path[MAX_STR] = {0, }; + + // load and store all of animation data + + if ((count = scandir(ANI_COLLECTION_DIR, &files, _scandir_filter, alphasort)) == -1) { + printf("Failed to get %s directory (%s)\n", ANI_COLLECTION_DIR, strerror(errno)); + e = PUI_INT_ERROR_INVALID_RESOURCES; + return e; + } + + for (i = 0; i < count; i++) { + snprintf(file_path, sizeof(file_path), "%s%s", ANI_COLLECTION_DIR, files[i]->d_name); + + ani_info = _read_json(file_path); + if (ani_info) { + eina_hash_add(_animations_hash, ani_info->id, ani_info); + printf("Success to load %s animation\n", files[i]->d_name); + } + memset(file_path, 0, sizeof(file_path)); + } + + for (i = 0; i < count; i++) { + free(files[i]); + } + free(files); //TODO @@ -105,13 +287,39 @@ pui_int_error _is_ani_supported(pui_id id) { pui_int_error e = PUI_INT_ERROR_NONE; + default_ani_info *ani_info; //TODO /* if the given id is not supported, return PUI_INT_ERROR_ID_NOT_SUPPORTED. */ + if (!id) { + e = PUI_INT_ERROR_ID_NOT_SUPPORTED; + return e; + } + ani_info = eina_hash_find(_animations_hash, id); + if (!ani_info) e = PUI_INT_ERROR_ID_NOT_SUPPORTED; return e; } +static void +_ani_info_cleanup(default_ani_info *ani_info) +{ + int i; + + if (!ani_info) return; + + eina_hash_del(_animations_hash, ani_info->id, ani_info); + if (ani_info->frames) { + for (i = 0; i < ani_info->num_key_frames; i++) { + if (ani_info->frames[i].leds) + free(ani_info->frames[i].leds); + } + free(ani_info->frames); + } + free(ani_info->id); + free(ani_info); +} + pui_backend_ani_data * _ani_create(pui_id id) { @@ -192,9 +400,7 @@ err: if (ani_info) { - //TODO : free if anything needs to be done with ani_info - - free(ani_info); + _ani_info_cleanup(ani_info); } return NULL; @@ -212,11 +418,23 @@ _ani_destroy(pui_backend_ani_data *ani_data) free(ani_data->ani_info); ani_data->ani_func = NULL; - ani_data->ani_info = NULL; + if (ani_data->ani_info) { + _ani_info_cleanup(ani_data->ani_info); + ani_data->ani_info = NULL; + } g_ani_data = NULL; } +static void +_animation_data_free_cb(void *data) +{ + int i; + default_ani_info *ani_info = (default_ani_info *)data; + + _ani_info_cleanup(ani_info); +} + static pui_backend_module_data * pui_default_backend_init(void) { @@ -236,6 +454,7 @@ pui_default_backend_init(void) /* Allocate backend specific data if needed. Now it will be empty. */ backend_data->data = NULL; + _animations_hash = eina_hash_string_superfast_new(_animation_data_free_cb); return backend_data; } @@ -263,8 +482,7 @@ pui_default_backend_deinit(pui_backend_module_data *backend_data) if (g_ani_data->ani_info) { - //TODO : free if anything needs to be done with ani_info - free(g_ani_data->ani_info); + _ani_info_cleanup(g_ani_data->ani_info); g_ani_data->ani_info = NULL; } } diff --git a/configure.ac b/configure.ac index 764b8f0..5a36a35 100644 --- a/configure.ac +++ b/configure.ac @@ -50,10 +50,11 @@ AC_SUBST(LIBPUI_CFLAGS) AC_SUBST(LIBPUI_LIBS) # libpui default backend -DEFAULT_BACKEND_REQUIRES="" -DEFAULT_BACKEND_CFLAGS="$LIBPUI_DIR " +DEFAULT_BACKEND_REQUIRES="eina json-c" +PKG_CHECK_MODULES(DEFAULT_BACKEND, $[DEFAULT_BACKEND_REQUIRES]) +DEFAULT_BACKEND_CFLAGS="$DEFAULT_BACKEND_CFLAGS $LIBPUI_DIR " #DEFAULT_BACKEND_CFLAGS="$DEFAULT_BACKEND_CFLAGS $LIBPUI_CFLAGS " -DEFAULT_BACKEND_LIBS="$LIBPUI_LIB " +DEFAULT_BACKEND_LIBS="$DEFAULT_BACKEND_LIBS $LIBPUI_LIB " AC_SUBST(DEFAULT_BACKEND_CFLAGS) AC_SUBST(DEFAULT_BACKEND_LIBS) diff --git a/packaging/libpui.spec b/packaging/libpui.spec index 9052ecc..bf640a7 100644 --- a/packaging/libpui.spec +++ b/packaging/libpui.spec @@ -16,6 +16,7 @@ BuildRequires: xz BuildRequires: pkgconfig(wayland-tbm-client) BuildRequires: pkgconfig(ecore-wl2) #BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(json-c) %{!?TZ_SYS_LIB: %global TZ_SYS_LIB /usr/lib} %{!?TZ_SYS_RO_SHARE: %global TZ_SYS_RO_SHARE /usr/share} diff --git a/src/PUI_common.h b/src/PUI_common.h index a8c02fd..62e15a5 100644 --- a/src/PUI_common.h +++ b/src/PUI_common.h @@ -35,6 +35,7 @@ typedef enum { PUI_INT_ERROR_INVALID_BACKEND_MGR, PUI_INT_ERROR_NO_ANI_AVAILABLE, PUI_INT_ERROR_BACKEND_FUNC_ERROR, + PUI_INT_ERROR_INVALID_RESOURCES, } pui_int_error; typedef unsigned int pui_bool; -- 2.7.4