default_backend : remove unused variable and change variables as static
[platform/core/uifw/libpui.git] / backends / default / default_backend.c
1 /*
2  * Copyright © 2019 Samsung Electronics co., Ltd. All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25
26 #include "default_backend.h"
27 #include <limits.h>
28
29 static Eina_Hash *_animations_hash = NULL;
30 static pui_backend_ani_data *g_ani_data = NULL;
31
32 static pui_bool
33 _ani_backend_frame_cb(void *data, int serial)
34 {
35         pui_int_error e = PUI_INT_ERROR_NONE;
36         pui_ani_t *ani = (pui_ani_t *)data;
37         pui_backend_ani_data *ani_data = NULL;
38         pui_ani_control_buffer *buffer = NULL;
39
40         ani_data = pui_backend_ani_get_ani_data(ani);
41         default_ani_info *ani_info = (default_ani_info *)ani_data->ani_info;
42
43         /* TODO : make use of ani_info */
44         (void) ani_info;
45
46         buffer = pui_backend_ani_get_buffer(ani);
47
48         if (!buffer)
49         {
50                 pui_err("Failed to get buffer !\n");
51                 return 0;
52         }
53
54         /* test example */
55         for(int i = 0; i<12; i++)
56         {
57                 buffer->ptr[4*i] = 0;
58                 buffer->ptr[4*i + 1] = (ani_info->frames[ani_info->frame_idx].leds[i].color & LED_MASK_RED) >> 16;//R
59                 buffer->ptr[4*i + 2] = (ani_info->frames[ani_info->frame_idx].leds[i].color & LED_MASK_GREEN) >> 8;//G
60                 buffer->ptr[4*i + 3] = ani_info->frames[ani_info->frame_idx].leds[i].color & LED_MASK_BLUE;//B
61         }
62
63         e = pui_backend_ani_set_buffer(ani, buffer);
64
65         if (e != PUI_INT_ERROR_NONE)
66         {
67                 pui_err("Failed on setting buffer on animation !(e=%d)\n", e);
68                 return (pui_bool)0;
69         }
70
71         e = pui_backend_ani_update(ani);
72
73         if (e != PUI_INT_ERROR_NONE)
74         {
75                 pui_err("Failed on updating animation !(e=%d)\n", e);
76                 return (pui_bool)0;
77         }
78
79         pui_info("... update (serial=%d)\n", serial);
80
81         return (pui_bool)1;
82 }
83
84 default_ani_info *
85 get_ani_info_from_ani_collection(pui_id id)
86 {
87         default_ani_info *ani_info = NULL;
88
89         if (!_animations_hash)
90                 return NULL;
91
92         pui_info("... id: %s\n", id);
93
94         ani_info = eina_hash_find(_animations_hash, id);
95
96         if (!ani_info)
97         {
98                 pui_err("ani_info has NOT been found ! (id:%s)\n", id);
99                 return NULL;
100         }
101
102         pui_info("ani_info has been found ! (id:%s)\n", id);
103
104         return ani_info;
105 }
106
107 pui_error
108 _ani_start(pui_ani_t *ani, int repeat)
109 {
110         pui_bool ret = 0;
111         pui_int_error e = PUI_INT_ERROR_NONE;
112         pui_backend_ani_data *ani_data = NULL;
113
114         ani_data = pui_backend_ani_get_ani_data(ani);
115         default_ani_info *ani_info = (default_ani_info *)ani_data->ani_info;
116
117         pui_info("... info->id: %s, repeat : %d\n", ani_info->id, repeat);
118
119         pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STARTED);
120         ret = pui_backend_ani_add_frame_cb(ani, _ani_backend_frame_cb, (double)ani_info->interval / 1000);
121
122         if (!ret)
123         {
124                 pui_err("Failed to add frame callback !\n");
125                 e = PUI_INT_ERROR_INVALID_RESOURCES;
126         }
127
128         return e;
129 }
130
131 pui_error
132 _ani_stop(pui_ani_t *ani, pui_bool force)
133 {
134         pui_int_error e = PUI_INT_ERROR_NONE;
135         pui_backend_ani_data *ani_data = NULL;
136
137         ani_data = pui_backend_ani_get_ani_data(ani);
138         default_ani_info *info = (default_ani_info *)ani_data->ani_info;
139
140         //TODO
141         (void) info;
142
143         pui_info("... info->id: %s, force=%d\n", info->id, force);
144
145         pui_backend_ani_remove_frame_cb(ani);
146
147         if (force)
148                 pui_backend_ani_status_update(ani, PUI_ANI_STATUS_PAUSED);
149         else
150                 pui_backend_ani_status_update(ani, PUI_ANI_STATUS_STOPPED);
151
152         return e;
153 }
154
155 static char *
156 _read_json_file(const char *path, int *data_size)
157 {
158         FILE *fp = fopen(path, "rb");
159         int size, ret;
160         char *buffer = NULL;
161         ERROR_CHECK(fp, return NULL, "Failed to open file: %s\n", path);
162
163         ret = fseek(fp, 0, SEEK_END);
164         ERROR_CHECK(ret == 0, goto error, "Failed to seek file. ret: %d\n", ret);
165         size = (long int)ftell(fp);
166         ERROR_CHECK(0 < size && size < INT_MAX, goto error, "Invalid file: %d size\n", size);
167         ret = fseek(fp, 0, SEEK_SET);
168         ERROR_CHECK(ret == 0, goto error, "Failed to seek file. ret: %d\n", ret);
169
170         buffer = (char *)calloc(sizeof(char), size + 1);
171         ERROR_CHECK(buffer, goto error, "Failed to allocate memory for buffer\n");
172
173         if (fread(buffer, size, 1, fp) < 1) {
174                 goto error;
175         }
176
177         *data_size = size;
178         fclose(fp);
179         return buffer;
180
181 error:
182         *data_size = 0;
183         if (buffer) free(buffer);
184         fclose(fp);
185         return NULL;
186 }
187
188 static default_ani_info *
189 _read_json(const char *path)
190 {
191         char *buffer, *type;
192         json_object *root_obj, *data_obj, *frame_obj, *frame_data_obj, *led_obj, *led_data_obj;
193         default_ani_info *ani_info = NULL;
194         int frame_id = 0, frame_len = 0, led_id = 0, led_len = 0;
195         int data_size = 0, i, j;
196
197         buffer = _read_json_file(path, &data_size);
198         ERROR_CHECK(buffer && data_size > 0, goto error, "File %s has no data\n", path);
199         root_obj = json_tokener_parse(buffer);
200         ERROR_CHECK(root_obj, goto error, "Failed to tokenize json object\n");
201
202         ani_info = (default_ani_info *)calloc(1, sizeof(default_ani_info));
203         ERROR_CHECK(ani_info, goto error, "Failed to alloc for animation info\n");
204
205         data_obj = json_object_object_get(root_obj, "type");
206         //printf("type: %s\n", json_object_get_string(data_obj));
207         type = (char *)json_object_get_string(data_obj);
208         ani_info->id = strndup(type, strlen(type));
209
210         data_obj = json_object_object_get(root_obj, "interval");
211         //printf("interval: %d\n", json_object_get_int(data_obj));
212         ani_info->interval = json_object_get_int(data_obj);
213
214         data_obj = json_object_object_get(root_obj, "frame");
215         frame_len = json_object_array_length(data_obj);
216
217         ani_info->num_key_frames = frame_len;
218         ani_info->frames = (default_frame_info_t *)calloc(sizeof(default_frame_info_t), frame_len);
219         ERROR_CHECK(ani_info->frames, goto error, "Failed to alloc for default_frame_info_t\n");
220
221         for (i = 0; i < frame_len; i++) {
222                 frame_obj = json_object_array_get_idx(data_obj, i);
223
224                 frame_data_obj = json_object_object_get(frame_obj, "frame_id");
225                 //printf("\tframe id: %d\n", json_object_get_int(frame_data_obj));
226                 frame_id = json_object_get_int(frame_data_obj);
227
228                 frame_data_obj = json_object_object_get(frame_obj, "frame_duration");
229                 if (frame_data_obj)
230                         ani_info->frames[frame_id - 1].frame_duration = json_object_get_int(frame_data_obj);
231                 else
232                         ani_info->frames[frame_id - 1].frame_duration = ani_info->interval;
233
234                 frame_data_obj = json_object_object_get(frame_obj, "led");
235                 led_len = json_object_array_length(frame_data_obj);
236
237                 ani_info->frames[frame_id - 1].num_led = led_len;
238                 if (ani_info->max_leds < led_len) ani_info->max_leds = led_len;
239                 ani_info->frames[frame_id - 1].leds = (default_led_info_t *)calloc(sizeof(default_led_info_t), led_len);
240                 ERROR_CHECK(ani_info->frames[frame_id - 1].leds, goto error, "Failed to alloc for default_led_info_t\n");
241
242                 for (j = 0; j < led_len; j++) {
243                         led_obj = json_object_array_get_idx(frame_data_obj, j);
244
245                         led_data_obj = json_object_object_get(led_obj, "id");
246                         //printf("\t\tid: %2d  ", json_object_get_int(led_data_obj));
247                         led_id = json_object_get_int(led_data_obj);
248
249                         led_data_obj = json_object_object_get(led_obj, "color");
250                         //printf("color: %s\n", json_object_get_string(led_data_obj));
251                         ani_info->frames[frame_id - 1].leds[led_id - 1].color =
252                                 strtol(json_object_get_string(led_data_obj), NULL, 16);
253                 }
254         }
255
256         free(buffer);
257         return ani_info;
258
259 error:
260         if (buffer) free(buffer);
261         if (ani_info) {
262                 if (ani_info->frames) {
263                         for (i = 0; i < ani_info->num_key_frames; i++) {
264                                 if (ani_info->frames[i].leds)
265                                         free(ani_info->frames[i].leds);
266                         }
267                         free(ani_info->frames);
268                 }
269                 free(ani_info->id);
270                 free(ani_info);
271         }
272         return NULL;
273 }
274
275 int
276 _find_directory(const char *path, Eina_List **json_list)
277 {
278         DIR *dir;
279         struct dirent *cur;
280         int count = 0, ret_cnt = 0;
281
282         dir = opendir(path);
283         if (!dir)
284         {
285                 pui_err("Failed to open %s.\n", path);
286                 return count;
287         }
288
289         while ((cur = readdir(dir)) != NULL)
290         {
291                 char next_path[MAX_STR] = {0, };
292                 if (cur->d_type == DT_DIR)
293                 {
294                         if (!strncmp(cur->d_name, ".", sizeof(".")) ||
295                                 !strncmp(cur->d_name, "..", sizeof("..")))
296                                 continue;
297
298                         snprintf(next_path, MAX_STR, "%s/%s", path, cur->d_name);
299                         ret_cnt = _find_directory(next_path, json_list);
300                         count += ret_cnt;
301                 }
302                 else
303                 {
304                         if (strstr(cur->d_name, ".json"))
305                         {
306                                 snprintf(next_path, MAX_STR, "%s/%s", path, cur->d_name);
307                                 *json_list = eina_list_append(*json_list, eina_stringshare_add(next_path));
308                                 count++;
309                         }
310                 }
311         }
312         closedir(dir);
313
314         return count;
315 }
316
317 default_ani_info *
318 _create_default_ani_info(char *type)
319 {
320         default_ani_info *ani_info = NULL;
321         int frame_len = 1;
322         int led_len = 12;
323
324         ani_info = (default_ani_info *)calloc(1, sizeof(default_ani_info));
325         ERROR_CHECK(ani_info, goto error, "Failed to alloc for animation info\n");
326
327         ani_info->id = strndup(type, strlen(type));
328         ani_info->interval = 50;
329
330         ani_info->num_key_frames = frame_len;
331         ani_info->frames = (default_frame_info_t *)calloc(sizeof(default_frame_info_t), frame_len);
332         ERROR_CHECK(ani_info->frames, goto error, "Failed to alloc for default_frame_info_t\n");
333
334         ani_info->frames[0].frame_duration = 500;
335         ani_info->frames[0].num_led = led_len;
336         ani_info->max_leds = led_len;
337         ani_info->frames[0].leds = (default_led_info_t *)calloc(sizeof(default_led_info_t), led_len);
338         ERROR_CHECK(ani_info->frames[0].leds, goto error, "Failed to alloc for default_led_info_t\n");
339
340         return ani_info;
341
342 error:
343         if (ani_info) {
344                 if (ani_info->frames) {
345                         for (int i = 0; i < ani_info->num_key_frames; i++) {
346                                 if (ani_info->frames[i].leds)
347                                         free(ani_info->frames[i].leds);
348                         }
349                         free(ani_info->frames);
350                 }
351                 free(ani_info->id);
352                 free(ani_info);
353         }
354         return NULL;
355 }
356
357
358 pui_int_error
359 _create_ani_collection(void)
360 {
361         pui_int_error e = PUI_INT_ERROR_NONE;
362         default_ani_info *ani_info;
363         Eina_List *json_list = NULL;
364         Eina_List *l, *l_next;
365         Eina_Stringshare *path;
366
367         // load and store all of animation data
368
369         _find_directory(ANI_COLLECTION_DIR, &json_list);
370
371         pui_err("Start create ani collect...\n");
372
373         EINA_LIST_FOREACH_SAFE(json_list, l, l_next, path)
374         {
375                 ani_info = _read_json(path);
376                 if (ani_info) {
377                         eina_hash_add(_animations_hash, ani_info->id, ani_info);
378                         pui_info("Success to load %s animation (id: %s)\n", path, ani_info->id);
379                 }
380                 eina_stringshare_del(path);
381                 json_list = eina_list_remove_list(json_list, l);
382         }
383
384         //TODO
385         ani_info = _create_default_ani_info("default/clear_fadeout");
386         if (ani_info) {
387                 eina_hash_add(_animations_hash, ani_info->id, ani_info);
388                 pui_err("Success to load default animation (id: %s)\n", ani_info->id);
389         }
390         ani_info = _create_default_ani_info("default/clear_immediate");
391         if (ani_info) {
392                 eina_hash_add(_animations_hash, ani_info->id, ani_info);
393                 pui_err("Success to load default animation (id: %s)\n", ani_info->id);
394         }
395
396         pui_err("End create ani collect...\n");
397
398         return e;
399 }
400
401 pui_bool
402 _geometry_get(int *width, int *height)
403 {
404         if (!width || !height)
405                 return 0;
406
407         if (width)
408                 *width = DEFAULT_BACKEND_GEOM_WIDTH;
409         if (height)
410                 *height = DEFAULT_BACKEND_GEOM_HEIGHT;
411
412         return 1;
413 }
414
415 pui_int_error
416 _is_ani_supported(pui_id id)
417 {
418         pui_int_error e = PUI_INT_ERROR_NONE;
419         default_ani_info *ani_info;
420
421         //TODO
422         /* if the given id is not supported, return PUI_INT_ERROR_ID_NOT_SUPPORTED. */
423         if (!id) {
424                 e = PUI_INT_ERROR_ID_NOT_SUPPORTED;
425                 return e;
426         }
427         ani_info = eina_hash_find(_animations_hash, id);
428
429         if (!ani_info)
430                 e = PUI_INT_ERROR_ID_NOT_SUPPORTED;
431
432         return e;
433 }
434
435 static void
436 _ani_info_cleanup(default_ani_info *ani_info)
437 {
438         int i;
439
440         if (!ani_info)
441                 return;
442
443         if (ani_info->frames)
444         {
445                 for (i = 0; i < ani_info->num_key_frames; i++)
446                 {
447                         if (ani_info->frames[i].leds)
448                                 free(ani_info->frames[i].leds);
449                 }
450
451                 free(ani_info->frames);
452         }
453
454         free(ani_info->id);
455 }
456
457 pui_backend_ani_data *
458 _ani_create(pui_id id)
459 {
460         pui_backend_ani_data *ani_data = NULL;
461         pui_backend_ani_func *ani_func = NULL;
462
463         /* backend's animation specific info */
464         default_ani_info *ani_info = NULL;
465
466         //TODO : return NULL if the animation correspond to the given id dones't exist.
467         if (PUI_INT_ERROR_NONE != _is_ani_supported(id))
468         {
469                 pui_err("The animation(%s) doesn't supported !\n", id);
470                 return NULL;
471         }
472
473         /* allocation of the structure of function pointers that will be called from pui_ani_control() */
474         ani_func = pui_backend_ani_alloc_ani_func();
475
476         if (!ani_func)
477         {
478                 pui_err("Failed to allocate memory ! (pui backend ani func)\n");
479                 return NULL;
480         }
481
482         /* get animation info associate with the given id from animation collection */
483         ani_info = get_ani_info_from_ani_collection(id);
484
485         if (!ani_info)
486         {
487                 pui_err("Failed to get ani info from animation collection !\n");
488                 goto err;
489         }
490
491         /* allocate backend ani_data and return it to pui ani core */
492         ani_data = (pui_backend_ani_data *)calloc(1, sizeof(pui_backend_ani_data));
493
494         if (!ani_data)
495         {
496                 pui_err("Failed to allocate memory for pui backend ani data !\n");
497                 goto err;
498         }
499
500         /* Assign each function pointer that corresponds to the given id if needed. */
501         if (!strncmp(ani_info->id, "system/easy_setup", sizeof("system/easy_setup")))
502         {
503                 pui_default_backend_ani_easysetup_func_set(ani_func);
504         }
505         else if (!strncmp(ani_info->id, "system/processing", sizeof("system/processing")))
506         {
507                 pui_default_backend_ani_system_processing_func_set(ani_func);
508         }
509         else if (!strncmp(ani_info->id, "system/sw_update_done", sizeof("system/sw_update_done")))
510         {
511                 pui_default_backend_ani_swupdatedone_func_set(ani_func);
512         }
513         else if (!strncmp(ani_info->id, "system/mic_off", sizeof("system/mic_off")))
514         {
515                 pui_default_backend_ani_micoff_func_set(ani_func);
516         }
517         else if (!strncmp(ani_info->id, "voice/listening", sizeof("voice/listening")))
518         {
519                 pui_default_backend_ani_listening_func_set(ani_func);
520         }
521         else if (!strncmp(ani_info->id, "voice/streaming", sizeof("voice/streaming")))
522         {
523                 pui_default_backend_ani_streaming_func_set(ani_func);
524         }
525         else if (!strncmp(ani_info->id, "voice/processing", sizeof("voice/processing")))
526         {
527                 pui_default_backend_ani_processing_func_set(ani_func);
528         }
529         else if (!strncmp(ani_info->id, "voice/speaking", sizeof("voice/speaking")))
530         {
531                 pui_default_backend_ani_speaking_func_set(ani_func);
532         }
533         else if (!strncmp(ani_info->id, "voice/timeout", sizeof("voice/timeout")))
534         {
535                 pui_default_backend_ani_timeout_func_set(ani_func);
536         }
537         else if (!strncmp(ani_info->id, "notification/normal", sizeof("notification/normal")))
538         {
539                 pui_default_backend_ani_normal_func_set(ani_func);
540         }
541         else if (!strncmp(ani_info->id, "notification/emergency", sizeof("notification/emergency")))
542         {
543                 pui_default_backend_ani_emergency_func_set(ani_func);
544         }
545         else if (!strncmp(ani_info->id, "notification/network_error", sizeof("notification/network_error")))
546         {
547                 pui_default_backend_ani_networkerror_func_set(ani_func);
548         }
549         else if (!strncmp(ani_info->id, "notification/error", sizeof("notification/error")))
550         {
551                 pui_default_backend_ani_error_func_set(ani_func);
552         }
553         else if (!strncmp(ani_info->id, "notification/alarm", sizeof("notification/alarm")))
554         {
555                 pui_default_backend_ani_alarm_func_set(ani_func);
556         }
557         else if (!strncmp(ani_info->id, "bt/pairing", sizeof("bt/pairing")))
558         {
559                 pui_default_backend_ani_pairing_func_set(ani_func);
560         }
561         else if (!strncmp(ani_info->id, "bt/connected", sizeof("bt/connected")))
562         {
563                 pui_default_backend_ani_connected_func_set(ani_func);
564         }
565         else if (!strncmp(ani_info->id, "default/clear_fadeout", sizeof("default/clear_fadeout")))
566         {
567                 pui_default_backend_ani_clear_fadeout_func_set(ani_func);
568         }
569         else if (!strncmp(ani_info->id, "default/clear_immediate", sizeof("default/clear_immediate")))
570         {
571                 pui_default_backend_ani_clear_immediate_func_set(ani_func);
572         }
573         else
574         {
575                 pui_info("%s animation has no animation handler, using default handler\n", ani_info->id);
576                 /* Assign each function pointer that corresponds to the given id if needed. */
577                 ani_func->ani_start = _ani_start;
578                 ani_func->ani_stop = _ani_stop;
579         }
580
581         ani_data->ani_func = ani_func;
582         ani_data->ani_info = (pui_backend_ani_info *)ani_info;
583
584         g_ani_data = ani_data;
585
586         return ani_data;
587
588 err:
589         if (ani_func)
590         {
591                 pui_backend_ani_free_ani_func(ani_func);
592                 ani_func = NULL;
593         }
594
595         return NULL;
596 }
597
598 void
599 _ani_destroy(pui_backend_ani_data *ani_data)
600 {
601         if (!ani_data)
602                 return;
603
604         if (ani_data->ani_func)
605         {
606                 pui_backend_ani_free_ani_func(ani_data->ani_func);
607                 ani_data->ani_func = NULL;
608         }
609
610         ani_data->ani_info = NULL;
611         g_ani_data = NULL;
612 }
613
614 static void
615 _animation_data_free_cb(void *data)
616 {
617         default_ani_info *ani_info = (default_ani_info *)data;
618
619         _ani_info_cleanup(ani_info);
620 }
621
622 default_frame_info_t *
623 backend_util_alloc_frame(default_ani_info *ani_info)
624 {
625         default_frame_info_t *frame;
626
627         frame = (default_frame_info_t *)calloc(sizeof(default_frame_info_t), 1);
628         ERROR_CHECK(frame, return NULL, "Failed to allocate memory for frame\n");
629
630         frame->leds = (default_led_info_t *)calloc(sizeof(default_led_info_t), ani_info->max_leds);
631         ERROR_CHECK(frame->leds, goto error, "Failed to allocate memory for led\n");
632
633         frame->num_led = ani_info->max_leds;
634
635         return frame;
636
637 error:
638         free(frame);
639         return NULL;
640 }
641
642 void
643 backend_util_cleanup_frame(default_frame_info_t *frame)
644 {
645         ERROR_CHECK(frame, return, "Invalid frame to cleanup\n");
646
647         for (int i = 0; i < frame->num_led; i++)
648         {
649                 frame->leds[i].color = 0x0;
650         }
651         frame->frame_duration = 0;
652 }
653
654 void
655 backend_util_free_frame(default_frame_info_t *frame)
656 {
657         if (!frame) return;
658
659         if (frame->leds) free(frame->leds);
660         free(frame);
661 }
662
663 void
664 pui_default_backend_ani_get_led_rgb(default_frame_info_t *frame,
665                                                                                         int led_idx,
666                                                                                         unsigned int *r,
667                                                                                         unsigned int *g,
668                                                                                         unsigned int *b)
669 {
670         if (!frame) return;
671         if (!r || !g || !b) return;
672         if (led_idx > frame->num_led) return;
673
674         *r = (frame->leds[led_idx].color & LED_MASK_RED) >> 16;
675         *g = (frame->leds[led_idx].color & LED_MASK_GREEN) >> 8;
676         *b = (frame->leds[led_idx].color & LED_MASK_BLUE);
677 }
678
679 int
680 pui_default_backend_ani_update_frame(pui_ani_t *ani,
681                                                                                         pui_backend_ani_data *ani_data,
682                                                                                         pui_ani_control_buffer *buffer,
683                                                                                         default_frame_info_t *frame,
684                                                                                          int serial)
685 {
686         pui_int_error e = PUI_INT_ERROR_NONE;
687         default_ani_info *ani_info = (default_ani_info *)ani_data->ani_info;
688         unsigned int r = 0x0, g = 0x0, b = 0x0;
689
690         for(int i = 0; i<12; i++)
691         {
692                 pui_default_backend_ani_get_led_rgb(frame, i, &r, &g, &b);
693                 buffer->ptr[4*i] = 0;
694                 buffer->ptr[4*i + 1] = b; /* BLUE */
695                 buffer->ptr[4*i + 2] = g; /* GREEN */
696                 buffer->ptr[4*i + 3] = r; /* RED */
697         }
698         backend_util_cleanup_frame(frame);
699
700         e = pui_backend_ani_set_buffer(ani, buffer);
701
702         if (e != PUI_INT_ERROR_NONE)
703         {
704                 pui_err("Failed on setting buffer on animation !(e=%d)\n", e);
705                 return 0;
706         }
707
708         e = pui_backend_ani_update(ani);
709
710         if (e != PUI_INT_ERROR_NONE)
711         {
712                 pui_err("Failed on updating animation !(e=%d)\n", e);
713                 return 0;
714         }
715
716         pui_info("... update (serial=%d), (repeat| cur: %d, want: %d)\n",
717                 serial, ani_info->repeat_cur, ani_info->repeat);
718
719         if (ani_info->repeat >= 0 &&
720                 ani_info->repeat_cur >= ani_info->repeat)
721         {
722                 ani_data->ani_func->ani_stop(ani, EINA_FALSE);
723         }
724
725         return 1;
726 }
727
728 static pui_backend_module_data *
729 pui_default_backend_init(void)
730 {
731         pui_backend_module_data *backend_data = NULL;
732
733         backend_data = (pui_backend_module_data *)calloc(1, sizeof(pui_backend_module_data));
734
735         if (!backend_data)
736         {
737                 pui_err("Failed to allocate memory for pui backend module data !\n");
738                 return NULL;
739         }
740
741         backend_data->create_ani_collection = _create_ani_collection;
742         backend_data->geometry_get = _geometry_get;
743         backend_data->ani_create = _ani_create;
744         backend_data->ani_destroy = _ani_destroy;
745
746         /* Allocate backend specific data if needed. Now it will be empty. */
747         backend_data->data = NULL;
748         _animations_hash = eina_hash_string_superfast_new(NULL);
749
750         return backend_data;
751 }
752
753 static void
754 pui_default_backend_deinit(pui_backend_module_data *backend_data)
755 {
756         Eina_Iterator *it;
757         default_ani_info *ani_info = NULL;
758
759         if (!backend_data)
760                 return;
761
762         if (backend_data->data)
763         {
764                 //TODO : free variables of backend_data
765
766                 free(backend_data->data);
767         }
768
769         if (g_ani_data)
770         {
771                 if (g_ani_data->ani_func)
772                 {
773                         pui_backend_ani_free_ani_func(g_ani_data->ani_func);
774                         g_ani_data->ani_func = NULL;
775                 }
776
777                 g_ani_data->ani_info = NULL;
778         }
779
780         if (_animations_hash)
781         {
782                 it = eina_hash_iterator_data_new(_animations_hash);
783
784                 EINA_ITERATOR_FOREACH(it, ani_info)
785                 {
786                         _animation_data_free_cb(ani_info);
787                         free(ani_info);
788                 }
789
790                 eina_iterator_free(it);
791
792                 eina_hash_free(_animations_hash);
793                 _animations_hash = NULL;
794         }
795
796         backend_data->create_ani_collection = NULL;
797         backend_data->geometry_get = NULL;
798         backend_data->ani_create = NULL;
799         backend_data->ani_destroy = NULL;
800
801         free(backend_data);
802         backend_data = NULL;
803 }
804
805 pui_backend_module pui_backend_module_info = {
806         "Tizen Reference Speaker Backend",
807         "Samsung",
808         PUI_BACKEND_SET_ABI_VERSION(1, 0),
809         pui_default_backend_init,
810         pui_default_backend_deinit
811 };
812