backend: add default clear animations
[platform/core/uifw/libpui.git] / backends / default_backend.c
index d4015ff..789e0f9 100644 (file)
@@ -24,6 +24,7 @@
  */
 
 #include "default_backend.h"
+#include <limits.h>
 
 pui_backend_ani_func *ani_func = NULL;
 Eina_Hash *_animations_hash = NULL;
@@ -80,15 +81,10 @@ _ani_backend_frame_cb(void *data, int serial)
        pui_ani_t *ani = (pui_ani_t *)data;
        pui_backend_ani_data *ani_data = NULL;
        pui_ani_control_buffer *buffer = NULL;
-       double now;
 
        ani_data = pui_backend_ani_get_ani_data(ani);
        default_ani_info *ani_info = (default_ani_info *)ani_data->ani_info;
 
-       now = ecore_time_unix_get();
-
-       pui_info("[time:%.3f] serial=%d\n", now, serial);
-
        /* TODO : make use of ani_info */
        (void) ani_info;
 
@@ -178,7 +174,7 @@ _ani_start(pui_ani_t *ani, int repeat)
 }
 
 pui_error
-_ani_stop(pui_ani_t *ani)
+_ani_stop(pui_ani_t *ani, pui_bool force)
 {
        pui_int_error e = PUI_INT_ERROR_NONE;
        pui_backend_ani_data *ani_data = NULL;
@@ -189,10 +185,14 @@ _ani_stop(pui_ani_t *ani)
        //TODO
        (void) info;
 
-       pui_info("... info->id: %s\n", info->id);
+       pui_info("... info->id: %s, force=%d\n", info->id, force);
 
        pui_backend_ani_remove_frame_cb(ani);
-       pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STOPPED);
+
+       if (force)
+               pui_backend_ani_status_update(ani, PUI_ANI_STATUS_PAUSED);
+       else
+               pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STOPPED);
 
        return e;
 }
@@ -201,26 +201,33 @@ static char *
 _read_json_file(const char *path, int *data_size)
 {
        FILE *fp = fopen(path, "rb");
-       int size;
-       char *buffer;
+       int size, ret;
+       char *buffer = NULL;
        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);
+       ret = fseek(fp, 0, SEEK_END);
+       ERROR_CHECK(ret == 0, goto error, "Failed to seek file. ret: %d\n", ret);
+       size = (long int)ftell(fp);
+       ERROR_CHECK(0 < size && size < INT_MAX, goto error, "Invalid file: %d size\n", size);
+       ret = fseek(fp, 0, SEEK_SET);
+       ERROR_CHECK(ret == 0, goto error, "Failed to seek file. ret: %d\n", ret);
 
        buffer = (char *)calloc(sizeof(char), size + 1);
+       ERROR_CHECK(buffer, goto error, "Failed to allocate memory for buffer\n");
 
        if (fread(buffer, size, 1, fp) < 1) {
-               *data_size = 0;
-               free(buffer);
-               fclose(fp);
-               return NULL;
+               goto error;
        }
 
        *data_size = size;
        fclose(fp);
        return buffer;
+
+error:
+       *data_size = 0;
+       if (buffer) free(buffer);
+       fclose(fp);
+       return NULL;
 }
 
 static default_ani_info *
@@ -233,7 +240,7 @@ _read_json(const char *path)
        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);
+       ERROR_CHECK(buffer && data_size > 0, goto error, "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");
 
@@ -263,10 +270,17 @@ _read_json(const char *path)
                //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, "frame_duration");
+               if (frame_data_obj)
+                       ani_info->frames[frame_id - 1].frame_duration = json_object_get_int(frame_data_obj);
+               else
+                       ani_info->frames[frame_id - 1].frame_duration = ani_info->interval;
+
                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;
+               if (ani_info->max_leds < led_len) ani_info->max_leds = 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");
 
@@ -288,7 +302,7 @@ _read_json(const char *path)
        return ani_info;
 
 error:
-       free(buffer);
+       if (buffer) free(buffer);
        if (ani_info) {
                if (ani_info->frames) {
                        for (i = 0; i < ani_info->num_key_frames; i++) {
@@ -345,6 +359,46 @@ _find_directory(const char *path, Eina_List **json_list)
        return count;
 }
 
+default_ani_info *
+_create_default_ani_info(char *type)
+{
+       default_ani_info *ani_info = NULL;
+       int frame_len = 1;
+       int led_len = 12;
+
+       ani_info = (default_ani_info *)calloc(1, sizeof(default_ani_info));
+       ERROR_CHECK(ani_info, goto error, "Failed to alloc for animation info\n");
+
+       ani_info->id = strndup(type, strlen(type));
+       ani_info->interval = 50;
+
+       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");
+
+       ani_info->frames[0].frame_duration = 500;
+       ani_info->frames[0].num_led = led_len;
+       ani_info->max_leds = led_len;
+       ani_info->frames[0].leds = (default_led_info_t *)calloc(sizeof(default_led_info_t), led_len);
+       ERROR_CHECK(ani_info->frames[0].leds, goto error, "Failed to alloc for default_led_info_t\n");
+
+       return ani_info;
+
+error:
+       if (ani_info) {
+               if (ani_info->frames) {
+                       for (int 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;
+}
+
 
 pui_int_error
 _create_ani_collection(void)
@@ -359,6 +413,8 @@ _create_ani_collection(void)
 
        _find_directory(ANI_COLLECTION_DIR, &json_list);
 
+       pui_err("Start create ani collect...\n");
+
        EINA_LIST_FOREACH_SAFE(json_list, l, l_next, path)
        {
                ani_info = _read_json(path);
@@ -371,10 +427,36 @@ _create_ani_collection(void)
        }
 
        //TODO
+       ani_info = _create_default_ani_info("default/clear_fadeout");
+       if (ani_info) {
+               eina_hash_add(_animations_hash, ani_info->id, ani_info);
+               pui_err("Success to load default animation (id: %s)\n", ani_info->id);
+       }
+       ani_info = _create_default_ani_info("default/clear_immediate");
+       if (ani_info) {
+               eina_hash_add(_animations_hash, ani_info->id, ani_info);
+               pui_err("Success to load default animation (id: %s)\n", ani_info->id);
+       }
+
+       pui_err("End create ani collect...\n");
 
        return e;
 }
 
+pui_bool
+_geometry_get(int *width, int *height)
+{
+       if (!width || !height)
+               return 0;
+
+       if (width)
+               *width = DEFAULT_BACKEND_GEOM_WIDTH;
+       if (height)
+               *height = DEFAULT_BACKEND_GEOM_HEIGHT;
+
+       return 1;
+}
+
 pui_int_error
 _is_ani_supported(pui_id id)
 {
@@ -525,6 +607,14 @@ _ani_create(pui_id id)
        {
                pui_default_backend_ani_connected_func_set(ani_func);
        }
+       else if (!strncmp(ani_info->id, "default/clear_fadeout", sizeof("default/clear_fadeout")))
+       {
+               pui_default_backend_ani_clear_fadeout_func_set(ani_func);
+       }
+       else if (!strncmp(ani_info->id, "default/clear_immediate", sizeof("default/clear_immediate")))
+       {
+               pui_default_backend_ani_clear_immediate_func_set(ani_func);
+       }
        else
        {
                pui_info("%s animation has no animation handler, using default handler\n", ani_info->id);
@@ -574,6 +664,48 @@ _animation_data_free_cb(void *data)
        _ani_info_cleanup(ani_info);
 }
 
+default_frame_info_t *
+backend_util_alloc_frame(default_ani_info *ani_info)
+{
+       default_frame_info_t *frame;
+
+       frame = (default_frame_info_t *)calloc(sizeof(default_frame_info_t), 1);
+       ERROR_CHECK(frame, return NULL, "Failed to allocate memory for frame\n");
+
+       frame->leds = (default_led_info_t *)calloc(sizeof(default_led_info_t), ani_info->max_leds);
+       ERROR_CHECK(frame->leds, goto error, "Failed to allocate memory for led\n");
+
+       frame->num_led = ani_info->max_leds;
+
+       return frame;
+
+error:
+       free(frame);
+       return NULL;
+}
+
+void
+backend_util_cleanup_frame(default_frame_info_t *frame)
+{
+       ERROR_CHECK(frame, return, "Invalid frame to cleanup\n");
+
+       for (int i = 0; i < frame->num_led; i++)
+       {
+               frame->leds[i].color = 0x0;
+       }
+       frame->frame_duration = 0;
+}
+
+void
+backend_util_free_frame(default_frame_info_t *frame)
+{
+       if (!frame) return;
+
+       if (frame->leds) free(frame->leds);
+       free(frame);
+}
+
+
 static pui_backend_module_data *
 pui_default_backend_init(void)
 {
@@ -588,6 +720,7 @@ pui_default_backend_init(void)
        }
 
        backend_data->create_ani_collection = _create_ani_collection;
+       backend_data->geometry_get = _geometry_get;
        backend_data->ani_create = _ani_create;
        backend_data->ani_destroy = _ani_destroy;
 
@@ -642,6 +775,7 @@ pui_default_backend_deinit(pui_backend_module_data *backend_data)
        }
 
        backend_data->create_ani_collection = NULL;
+       backend_data->geometry_get = NULL;
        backend_data->ani_create = NULL;
        backend_data->ani_destroy = NULL;