4 #include <PUI_backend.h>
6 #include <json-c/json.h>
12 #define ANI_COLLECTION_DIR "/usr/share/pui/"
15 #define ERROR_CHECK(exp, action, fmt, ...) \
19 printf(fmt, ##__VA_ARGS__); \
24 pui_backend_ani_func *ani_func = NULL;
25 Eina_Hash *_animations_hash = NULL;
37 typedef struct _default_ani_info default_ani_info;
38 typedef struct _default_frame_info_t default_frame_info_t;
39 typedef struct _default_led_info_t default_led_info_t;
41 struct _default_ani_info
44 pui_ani_status status;
45 pui_ani_control_buffer *buffer;
48 unsigned int key_frame_idx;
49 unsigned int num_key_frames;
50 default_frame_info_t *frames;
52 pui_effect_func effect_func;
55 struct _default_frame_info_t
57 default_led_info_t *leds;
61 struct _default_led_info_t
66 pui_backend_ani_data *g_ani_data = NULL;
69 _frame_cb(void *data, int serial)
71 pui_ani_t *ani = (pui_ani_t *)data;
76 //pui_backend_ani_get_buffer();
77 //pui_backend_ani_update();
83 get_ani_info_from_ani_collection(default_ani_info *info, pui_id id)
85 pui_int_error e = PUI_INT_ERROR_NONE;
89 //ex> data->interval = 30;
95 _ani_start(pui_ani_t *ani, int repeat)
97 pui_int_error e = PUI_INT_ERROR_NONE;
98 pui_backend_ani_data *ani_data = NULL;
100 ani_data = pui_backend_ani_get_ani_data(ani);
101 default_ani_info *info = (default_ani_info *)ani_data->ani_info;
106 pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STARTED);
107 pui_backend_ani_add_frame_cb(ani, _frame_cb, 0.1);
113 _ani_stop(pui_ani_t *ani)
115 pui_int_error e = PUI_INT_ERROR_NONE;
116 pui_backend_ani_data *ani_data = NULL;
118 ani_data = pui_backend_ani_get_ani_data(ani);
119 default_ani_info *info = (default_ani_info *)ani_data->ani_info;
124 pui_backend_ani_remove_frame_cb(ani);
125 pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STOPPED);
131 _read_json_file(const char *path, int *data_size)
133 FILE *fp = fopen(path, "rb");
136 ERROR_CHECK(fp, return NULL, "Failed to open file: %s\n", path);
138 fseek(fp, 0, SEEK_END);
140 fseek(fp, 0, SEEK_SET);
142 buffer = (char *)calloc(sizeof(char), size + 1);
144 if (fread(buffer, size, 1, fp) < 1) {
156 static default_ani_info *
157 _read_json(const char *path)
160 json_object *root_obj, *data_obj, *frame_obj, *frame_data_obj, *led_obj, *led_data_obj;
161 default_ani_info *ani_info = NULL;
162 int frame_id = 0, frame_len = 0, led_id = 0, led_len = 0;
163 int data_size = 0, i, j;
165 buffer = _read_json_file(path, &data_size);
166 ERROR_CHECK(buffer && data_size > 0, return EINA_FALSE, "File %s has no data\n", path);
167 root_obj = json_tokener_parse(buffer);
168 ERROR_CHECK(root_obj, goto error, "Failed to tokenize json object\n");
170 ani_info = (default_ani_info *)calloc(1, sizeof(default_ani_info));
171 ERROR_CHECK(ani_info, goto error, "Failed to alloc for animation info\n");
173 data_obj = json_object_object_get(root_obj, "type");
174 //printf("type: %s\n", json_object_get_string(data_obj));
175 type = (char *)json_object_get_string(data_obj);
176 ani_info->id = strndup(type, strlen(type));
178 data_obj = json_object_object_get(root_obj, "interval");
179 //printf("interval: %d\n", json_object_get_int(data_obj));
180 ani_info->interval = json_object_get_int(data_obj);
182 data_obj = json_object_object_get(root_obj, "frame");
183 frame_len = json_object_array_length(data_obj);
185 ani_info->num_key_frames = frame_len;
186 ani_info->frames = (default_frame_info_t *)calloc(sizeof(default_frame_info_t), frame_len);
187 ERROR_CHECK(ani_info->frames, goto error, "Failed to alloc for default_frame_info_t\n");
189 for (i = 0; i < frame_len; i++) {
190 frame_obj = json_object_array_get_idx(data_obj, i);
192 frame_data_obj = json_object_object_get(frame_obj, "frame_id");
193 //printf("\tframe id: %d\n", json_object_get_int(frame_data_obj));
194 frame_id = json_object_get_int(frame_data_obj);
196 frame_data_obj = json_object_object_get(frame_obj, "led");
197 led_len = json_object_array_length(frame_data_obj);
199 ani_info->frames[frame_id - 1].num_led = led_len;
200 ani_info->frames[frame_id - 1].leds = (default_led_info_t *)calloc(sizeof(default_led_info_t), led_len);
201 ERROR_CHECK(ani_info->frames[frame_id - 1].leds, goto error, "Failed to alloc for default_led_info_t\n");
203 for (j = 0; j < led_len; j++) {
204 led_obj = json_object_array_get_idx(frame_data_obj, j);
206 led_data_obj = json_object_object_get(led_obj, "id");
207 //printf("\t\tid: %2d ", json_object_get_int(led_data_obj));
208 led_id = json_object_get_int(led_data_obj);
210 led_data_obj = json_object_object_get(led_obj, "color");
211 //printf("color: %s\n", json_object_get_string(led_data_obj));
212 ani_info->frames[frame_id - 1].leds[led_id - 1].color =
213 strtol(json_object_get_string(led_data_obj), NULL, 16);
223 if (ani_info->frames) {
224 for (i = 0; i < ani_info->num_key_frames; i++) {
225 if (ani_info->frames[i].leds)
226 free(ani_info->frames[i].leds);
228 free(ani_info->frames);
237 _scandir_filter(const struct dirent *dirent)
239 if (!strncmp(dirent->d_name, ".", sizeof(".")) ||
240 !strncmp(dirent->d_name, "..", sizeof("..")))
242 if (!strstr(dirent->d_name, ".json"))
250 _create_ani_collection(void)
252 pui_int_error e = PUI_INT_ERROR_NONE;
253 default_ani_info *ani_info;
254 struct dirent **files;
256 char file_path[MAX_STR] = {0, };
258 // load and store all of animation data
260 if ((count = scandir(ANI_COLLECTION_DIR, &files, _scandir_filter, alphasort)) == -1) {
261 printf("Failed to get %s directory (%s)\n", ANI_COLLECTION_DIR, strerror(errno));
262 e = PUI_INT_ERROR_INVALID_RESOURCES;
266 for (i = 0; i < count; i++) {
267 snprintf(file_path, sizeof(file_path), "%s%s", ANI_COLLECTION_DIR, files[i]->d_name);
269 ani_info = _read_json(file_path);
271 eina_hash_add(_animations_hash, ani_info->id, ani_info);
272 printf("Success to load %s animation\n", files[i]->d_name);
274 memset(file_path, 0, sizeof(file_path));
277 for (i = 0; i < count; i++) {
288 _is_ani_supported(pui_id id)
290 pui_int_error e = PUI_INT_ERROR_NONE;
291 default_ani_info *ani_info;
294 /* if the given id is not supported, return PUI_INT_ERROR_ID_NOT_SUPPORTED. */
296 e = PUI_INT_ERROR_ID_NOT_SUPPORTED;
299 ani_info = eina_hash_find(_animations_hash, id);
300 if (!ani_info) e = PUI_INT_ERROR_ID_NOT_SUPPORTED;
306 _ani_info_cleanup(default_ani_info *ani_info)
310 if (!ani_info) return;
312 eina_hash_del(_animations_hash, ani_info->id, ani_info);
313 if (ani_info->frames) {
314 for (i = 0; i < ani_info->num_key_frames; i++) {
315 if (ani_info->frames[i].leds)
316 free(ani_info->frames[i].leds);
318 free(ani_info->frames);
324 pui_backend_ani_data *
325 _ani_create(pui_id id)
327 pui_int_error e = PUI_INT_ERROR_NONE;
329 pui_backend_ani_data *ani_data = NULL;
330 pui_backend_ani_func *ani_func = NULL;
332 /* backend's animation specific info */
333 default_ani_info *ani_info = NULL;
335 //TODO : return NULL if the animation correspond to the given id dones't exist.
337 /* allocation of the structure of function pointers that will be called from pui_ani_control() */
338 ani_func = pui_backend_ani_alloc_ani_func();
342 pui_err("Failed to allocate memory ! (pui backend ani func)\n");
346 /* Assign each function pointer that corresponds to the given id if needed. */
347 ani_func->ani_start = _ani_start;
348 ani_func->ani_stop = _ani_stop;
350 ani_func->reserved1 = NULL;
351 ani_func->reserved2 = NULL;
352 ani_func->reserved3 = NULL;
353 ani_func->reserved4 = NULL;
354 ani_func->reserved5 = NULL;
355 ani_func->reserved6 = NULL;
356 ani_func->reserved7 = NULL;
357 ani_func->reserved8 = NULL;
358 ani_func->reserved9 = NULL;
359 ani_func->reserved10 = NULL;
361 /* backend's animation specific info */
362 ani_info = (default_ani_info *)calloc(1, sizeof(default_ani_info));
366 pui_err("Failed to allocate memory ! (backend's ani specific info)\n");
370 /* fill animation info associate with the given id from animation collection */
371 e = get_ani_info_from_ani_collection(ani_info, id);
373 if (PUI_INT_ERROR_NONE != e)
375 pui_err("Failed to get ani info from animation collection !\n");
379 /* allocate backend ani_data and return it to pui ani core */
380 ani_data = (pui_backend_ani_data *)calloc(1, sizeof(pui_backend_ani_data));
384 pui_err("Failed to allocate memory for pui backend ani data !\n");
388 ani_data->ani_func = ani_func;
389 ani_data->ani_info = (pui_backend_ani_info *)ani_info;
391 g_ani_data = ani_data;
398 pui_backend_ani_free_ani_func(ani_func);
404 _ani_info_cleanup(ani_info);
411 _ani_destroy(pui_backend_ani_data *ani_data)
416 pui_backend_ani_free_ani_func(ani_data->ani_func);
418 //TODO : free if anything needs to be done with ani_info
419 free(ani_data->ani_info);
421 ani_data->ani_func = NULL;
422 if (ani_data->ani_info) {
423 _ani_info_cleanup(ani_data->ani_info);
424 ani_data->ani_info = NULL;
431 _animation_data_free_cb(void *data)
433 default_ani_info *ani_info = (default_ani_info *)data;
435 _ani_info_cleanup(ani_info);
438 static pui_backend_module_data *
439 pui_default_backend_init(void)
441 pui_backend_module_data *backend_data = NULL;
443 backend_data = (pui_backend_module_data *)calloc(1, sizeof(pui_backend_module_data));
447 pui_err("Failed to allocate memory for pui backend module data !\n");
451 backend_data->create_ani_collection = _create_ani_collection;
452 backend_data->ani_create = _ani_create;
453 backend_data->ani_destroy = _ani_destroy;
455 /* Allocate backend specific data if needed. Now it will be empty. */
456 backend_data->data = NULL;
457 _animations_hash = eina_hash_string_superfast_new(_animation_data_free_cb);
463 pui_default_backend_deinit(pui_backend_module_data *backend_data)
468 if (backend_data->data)
470 //TODO : free variables of backend_data
472 free(backend_data->data);
477 if (g_ani_data->ani_func)
479 pui_backend_ani_free_ani_func(g_ani_data->ani_func);
480 g_ani_data->ani_func = NULL;
483 if (g_ani_data->ani_info)
485 _ani_info_cleanup(g_ani_data->ani_info);
486 g_ani_data->ani_info = NULL;
490 backend_data->create_ani_collection = NULL;
491 backend_data->ani_create = NULL;
492 backend_data->ani_destroy = NULL;
498 pui_backend_module pui_backend_module_info = {
499 "Tizen Reference Speaker Backend",
501 PUI_BACKEND_SET_ABI_VERSION(1, 0),
502 pui_default_backend_init,
503 pui_default_backend_deinit