Replace livebox with master
[apps/native/widget/widget.git] / src / dynamicbox.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <errno.h>
19 #include <stdlib.h> /* malloc */
20 #include <string.h> /* strdup */
21 #include <libgen.h>
22 #include <unistd.h> /* access */
23 #define __USE_GNU
24 #include <dlfcn.h>
25
26 #include <dlog.h>
27 #include <dynamicbox_errno.h>
28 #include <dynamicbox_service.h>
29 #include <dynamicbox_provider.h>
30 #include <dynamicbox_provider_buffer.h>
31 #include <dynamicbox_conf.h>
32 #include <dynamicbox_buffer.h>
33 #include <Evas.h>
34
35 #include "debug.h"
36 #include "dlist.h"
37 #include "util.h"
38 #include "dynamicbox.h"
39
40 #define PUBLIC __attribute__((visibility("default")))
41
42 #define FILE_SCHEMA    "file://"
43
44 struct block {
45     unsigned int idx;
46
47     char *type;
48     char *part;
49     char *data;
50     char *option;
51     char *id;
52     char *file;
53     char *target_id;
54 };
55
56 struct dynamicbox_desc {
57     FILE *fp;
58     int for_pd;
59
60     unsigned int last_idx;
61
62     struct dlist *block_list;
63 };
64
65 struct dynamicbox_buffer_data {
66     int is_gbar;
67     int accelerated;
68
69     /* for Buffer event wrapper */
70     int (*handler)(dynamicbox_buffer_h , dynamicbox_buffer_event_data_t, void *);
71     void *cbdata;
72
73     char *content;
74     char *title;
75     char *icon;
76     char *name;
77 };
78
79 /**
80  * @brief These functions are defined in the data-provider-slave
81  */
82 static struct info {
83     const char *(*find_pkgname)(const char *filename);
84     int (*request_update_by_id)(const char *uri);
85     int (*trigger_update_monitor)(const char *id, int is_gbar);
86     int (*update_extra_info)(const char *id, const char *content, const char *title, const char *icon, const char *name);
87
88     enum load_type {
89     LOAD_TYPE_UNKNOWN = -1,
90     LOAD_TYPE_SLAVE   = 0,
91     LOAD_TYPE_APP     = 1
92     } type;
93
94     union _updated {
95     struct _slave {
96         int (*send)(const char *pkgname, const char *id, int idx, int x, int y, int w, int h, int gbar, const char *descfile);
97     } slave;
98
99     struct _app {
100         int (*send)(const char *id, int idx, int x, int y, int w, int h, int gbar);
101     } app;
102     } updated;
103 } s_info = {
104     .find_pkgname = NULL,
105     .request_update_by_id = NULL,
106     .trigger_update_monitor = NULL,
107     .update_extra_info = NULL,
108     .type = LOAD_TYPE_UNKNOWN,    /* Not initialized */
109 };
110
111 #define FUNC_PREFIX                               "dynamicbox_"
112 #define FUNC_DYNAMICBOX_SEND_UPDATED              FUNC_PREFIX "send_updated"
113 #define FUNC_DYNAMICBOX_PROVIDER_APP_UPDATED      FUNC_PREFIX "provider_app_updated"
114 #define FUNC_DYNAMICBOX_FIND_PKGNAME              FUNC_PREFIX "find_pkgname"
115 #define FUNC_DYNAMICBOX_REQUEST_UPDATE_BY_ID      FUNC_PREFIX "request_update_by_id"
116 #define FUNC_DYNAMICBOX_TRIGGER_UPDATE_MONITOR    FUNC_PREFIX "trigger_update_monitor"
117 #define FUNC_DYNAMICBOX_UPDATE_EXTRA_INFO         FUNC_PREFIX "update_extra_info"
118
119 static inline void load_update_function(void)
120 {
121     /* Must to be checked the slave function first. */
122     s_info.updated.slave.send = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_SEND_UPDATED);
123     if (s_info.updated.slave.send) {
124     s_info.type = LOAD_TYPE_SLAVE;
125     DbgPrint("Slave detected\n");
126     } else {
127     s_info.updated.app.send = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_PROVIDER_APP_UPDATED);
128     if (s_info.updated.app.send) {
129         s_info.type = LOAD_TYPE_APP;
130         DbgPrint("App detected\n");
131     }
132     }
133 }
134
135 static int send_updated(const char *pkgname, const char *id, int idx, int x, int y, int w, int h, int gbar, const char *descfile)
136 {
137     int ret = DBOX_STATUS_ERROR_INVALID_PARAMETER;
138
139     if (s_info.type == LOAD_TYPE_UNKNOWN) {
140     load_update_function();
141     }
142
143     if (s_info.type == LOAD_TYPE_APP) {
144     ret = s_info.updated.app.send(id, idx, x, y, w, h, gbar);
145     } else if (s_info.type == LOAD_TYPE_SLAVE) {
146     ret = s_info.updated.slave.send(pkgname, id, idx, x, y, w, h, gbar, descfile);
147     } else {
148     dynamicbox_damage_region_t region = {
149         .x = x,
150         .y = y,
151         .w = w,
152         .h = h,
153     };
154     ret = dynamicbox_provider_send_updated(pkgname, id, idx, &region, gbar, descfile);
155     }
156
157     return ret;
158 }
159
160 static char *id_to_uri(const char *id)
161 {
162     char *uri;
163     int uri_len;
164
165     uri_len = strlen(id) + strlen(FILE_SCHEMA) + 1;
166
167     uri = malloc(uri_len);
168     if (!uri) {
169     return NULL;
170     }
171
172     snprintf(uri, uri_len, FILE_SCHEMA "%s", id);
173     return uri;
174 }
175
176 static inline int event_handler_wrapper(dynamicbox_buffer_h buffer, dynamicbox_buffer_event_data_t event_info, void *data)
177 {
178     const char *pkgname;
179     const char *id;
180     struct dynamicbox_buffer_data *cbdata = data;
181     int ret;
182
183     pkgname = dynamicbox_provider_buffer_pkgname(buffer);
184     if (!pkgname) {
185     ErrPrint("pkgname is not valid\n");
186     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
187     }
188
189     id = dynamicbox_provider_buffer_id(buffer);
190     if (!id) {
191     ErrPrint("id is not valid[%s]\n", pkgname);
192     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
193     }
194
195     if (cbdata->handler) {
196     ret = cbdata->handler(buffer, event_info, cbdata->cbdata);
197     } else {
198     ret = DBOX_STATUS_ERROR_FAULT;
199     }
200
201     switch (event_info->type) {
202     case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT:
203     case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
204     case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
205     case DBOX_BUFFER_EVENT_ACCESS_ACTIVATE:
206     case DBOX_BUFFER_EVENT_ACCESS_ACTION_UP:
207     case DBOX_BUFFER_EVENT_ACCESS_ACTION_DOWN:
208     case DBOX_BUFFER_EVENT_ACCESS_SCROLL_UP:
209     case DBOX_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
210     case DBOX_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
211     case DBOX_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
212     case DBOX_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
213     case DBOX_BUFFER_EVENT_ACCESS_MOUSE:
214     case DBOX_BUFFER_EVENT_ACCESS_BACK:
215     case DBOX_BUFFER_EVENT_ACCESS_OVER:
216     case DBOX_BUFFER_EVENT_ACCESS_READ:
217     case DBOX_BUFFER_EVENT_ACCESS_ENABLE:
218     case DBOX_BUFFER_EVENT_ACCESS_DISABLE:
219         DbgPrint("Accessibility event: %d\n", event_info->type);
220         if (ret < 0) {
221         (void)dynamicbox_provider_send_access_status(pkgname, id, DBOX_ACCESS_STATUS_ERROR);
222         } else {
223         (void)dynamicbox_provider_send_access_status(pkgname, id, ret);
224         }
225         break;
226     case DBOX_BUFFER_EVENT_KEY_UP:
227     case DBOX_BUFFER_EVENT_KEY_DOWN:
228     case DBOX_BUFFER_EVENT_KEY_FOCUS_IN:
229     case DBOX_BUFFER_EVENT_KEY_FOCUS_OUT:
230         DbgPrint("Key event: %d\n", event_info->type);
231         if (ret < 0) {
232         (void)dynamicbox_provider_send_key_status(pkgname, id, DBOX_KEY_STATUS_ERROR);
233         } else {
234         (void)dynamicbox_provider_send_key_status(pkgname, id, ret);
235         }
236         break;
237     default:
238         break;
239     }
240
241     return ret;
242 }
243
244 static inline int default_event_handler(dynamicbox_buffer_h buffer, dynamicbox_buffer_event_data_t event_info, void *data)
245 {
246     /* NOP */
247     return 0;
248 }
249
250 PUBLIC const int DBOX_DONE = 0x00;
251 PUBLIC const int DBOX_OUTPUT_UPDATED = 0x02;
252 PUBLIC const int DBOX_USE_NET = 0x04;
253
254 PUBLIC const int DBOX_NEED_TO_SCHEDULE = 0x01;
255 PUBLIC const int DBOX_NEED_TO_CREATE = 0x01;
256 PUBLIC const int DBOX_NEED_TO_DESTROY = 0x01;
257 PUBLIC const int DBOX_FORCE_TO_SCHEDULE = 0x08;
258
259 PUBLIC const int DBOX_SYS_EVENT_FONT_CHANGED = 0x01;
260 PUBLIC const int DBOX_SYS_EVENT_LANG_CHANGED = 0x02;
261 PUBLIC const int DBOX_SYS_EVENT_TIME_CHANGED = 0x04;
262 PUBLIC const int DBOX_SYS_EVENT_REGION_CHANGED = 0x08;
263 PUBLIC const int DBOX_SYS_EVENT_TTS_CHANGED = 0x10;
264 PUBLIC const int DBOX_SYS_EVENT_PAUSED = 0x0100;
265 PUBLIC const int DBOX_SYS_EVENT_RESUMED = 0x0200;
266 PUBLIC const int DBOX_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
267 PUBLIC const int DBOX_SYS_EVENT_DELETED = 0x0800;
268
269 PUBLIC struct dynamicbox_desc *dynamicbox_desc_open(const char *filename, int for_pd)
270 {
271     struct dynamicbox_desc *handle;
272     char *new_fname;
273
274     handle = calloc(1, sizeof(*handle));
275     if (!handle) {
276     ErrPrint("Error: %s\n", strerror(errno));
277     return NULL;
278     }
279
280     if (for_pd) {
281     int len;
282     len = strlen(filename) + strlen(".desc") + 1;
283     new_fname = malloc(len);
284     if (!new_fname) {
285         ErrPrint("Error: %s\n", strerror(errno));
286         free(handle);
287         return NULL;
288     }
289     snprintf(new_fname, len, "%s.desc", filename);
290     } else {
291     new_fname = strdup(filename);
292     if (!new_fname) {
293         ErrPrint("Error: %s\n", strerror(errno));
294         free(handle);
295         return NULL;
296     }
297     }
298
299     DbgPrint("Open a file %s with merge mode %s\n",
300         new_fname,
301         access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
302
303     handle->fp = fopen(new_fname, "at");
304     free(new_fname);
305     if (!handle->fp) {
306     ErrPrint("Failed to open a file: %s\n", strerror(errno));
307     free(handle);
308     return NULL;
309     }
310
311     return handle;
312 }
313
314 PUBLIC int dynamicbox_desc_close(struct dynamicbox_desc *handle)
315 {
316     struct dlist *l;
317     struct dlist *n;
318     struct block *block;
319
320     if (!handle) {
321     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
322     }
323
324     dlist_foreach_safe(handle->block_list, l, n, block) {
325     handle->block_list = dlist_remove(handle->block_list, l);
326
327     fprintf(handle->fp, "{\n");
328     if (block->type) {
329         fprintf(handle->fp, "type=%s\n", block->type);
330     }
331
332     if (block->part) {
333         fprintf(handle->fp, "part=%s\n", block->part);
334     }
335
336     if (block->data) {
337         fprintf(handle->fp, "data=%s\n", block->data);
338     }
339
340     if (block->option) {
341         fprintf(handle->fp, "option=%s\n", block->option);
342     }
343
344     if (block->id) {
345         fprintf(handle->fp, "id=%s\n", block->id);
346     }
347
348     if (block->target_id) {
349         fprintf(handle->fp, "target=%s\n", block->target_id);
350     }
351     fprintf(handle->fp, "}\n");
352
353     free(block->type);
354     free(block->part);
355     free(block->data);
356     free(block->option);
357     free(block->id);
358     free(block->target_id);
359     free(block);
360     }
361
362     if (fclose(handle->fp) != 0) {
363     ErrPrint("fclose: %s\n", strerror(errno));
364     }
365     free(handle);
366     return DBOX_STATUS_ERROR_NONE;
367 }
368
369 PUBLIC int dynamicbox_desc_set_category(struct dynamicbox_desc *handle, const char *id, const char *category)
370 {
371     struct block *block;
372
373     if (!handle || !category) {
374     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
375     }
376
377     block = calloc(1, sizeof(*block));
378     if (!block) {
379     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
380     }
381
382     block->type = strdup(DBOX_DESC_TYPE_INFO);
383     if (!block->type) {
384     free(block);
385     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
386     }
387
388     block->part = strdup("category");
389     if (!block->part) {
390     free(block->type);
391     free(block);
392     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
393     }
394
395     block->data = strdup(category);
396     if (!block->data) {
397     free(block->type);
398     free(block->part);
399     free(block);
400     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
401     }
402
403     if (id) {
404     block->id = strdup(id);
405     if (!block->id) {
406         free(block->data);
407         free(block->type);
408         free(block->part);
409         free(block);
410         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
411     }
412     }
413
414     block->idx = handle->last_idx++;
415     handle->block_list = dlist_append(handle->block_list, block);
416     return block->idx;
417 }
418
419 PUBLIC int dynamicbox_desc_set_size(struct dynamicbox_desc *handle, const char *id, int w, int h)
420 {
421     struct block *block;
422     char buffer[BUFSIZ];
423
424     if (!handle) {
425     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
426     }
427
428     block = calloc(1, sizeof(*block));
429     if (!block) {
430     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
431     }
432
433     block->type = strdup(DBOX_DESC_TYPE_INFO);
434     if (!block->type) {
435     free(block);
436     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
437     }
438
439     block->part = strdup("size");
440     if (!block->part) {
441     free(block->type);
442     free(block);
443     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
444     }
445
446     if (id) {
447     block->id = strdup(id);
448     if (!block->id) {
449         free(block->part);
450         free(block->type);
451         free(block);
452         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
453     }
454     }
455
456     snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
457     block->data = strdup(buffer);
458     if (!block->data) {
459     free(block->part);
460     free(block->type);
461     free(block);
462     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
463     }
464
465     block->idx = handle->last_idx++;
466     handle->block_list = dlist_append(handle->block_list, block);
467     return block->idx;
468 }
469
470 PUBLIC int dynamicbox_desc_set_id(struct dynamicbox_desc *handle, int idx, const char *id)
471 {
472     struct dlist *l;
473     struct block *block;
474
475     dlist_foreach(handle->block_list, l, block) {
476     if (block->idx == idx) {
477         if (strcasecmp(block->type, DBOX_DESC_TYPE_SCRIPT)) {
478         ErrPrint("Invalid block is used\n");
479         return DBOX_STATUS_ERROR_INVALID_PARAMETER;
480         }
481
482         free(block->target_id);
483         block->target_id = NULL;
484
485         if (!id || !strlen(id)) {
486         return DBOX_STATUS_ERROR_NONE;
487         }
488
489         block->target_id = strdup(id);
490         if (!block->target_id) {
491         ErrPrint("Heap: %s\n", strerror(errno));
492         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
493         }
494
495         return DBOX_STATUS_ERROR_NONE;
496     }
497     }
498
499     return DBOX_STATUS_ERROR_NOT_EXIST;
500 }
501
502 /*!
503  * \return idx
504  */
505 PUBLIC int dynamicbox_desc_add_block(struct dynamicbox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
506 {
507     struct block *block;
508
509     if (!handle || !type) {
510     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
511     }
512
513     if (!part) {
514     part = "";
515     }
516
517     if (!data) {
518     data = "";
519     }
520
521     block = calloc(1, sizeof(*block));
522     if (!block) {
523     ErrPrint("Heap: %s\n", strerror(errno));
524     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
525     }
526
527     block->type = strdup(type);
528     if (!block->type) {
529     ErrPrint("Heap: %s\n", strerror(errno));
530     free(block);
531     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
532     }
533
534     block->part = strdup(part);
535     if (!block->part) {
536     ErrPrint("Heap: %s\n", strerror(errno));
537     free(block->type);
538     free(block);
539     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
540     }
541
542     block->data = strdup(data);
543     if (!block->data) {
544     ErrPrint("Heap: %s\n", strerror(errno));
545     free(block->type);
546     free(block->part);
547     free(block);
548     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
549     }
550
551     if (option) {
552     block->option = strdup(option);
553     if (!block->option) {
554         ErrPrint("Heap: %s\n", strerror(errno));
555         free(block->data);
556         free(block->type);
557         free(block->part);
558         free(block);
559         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
560     }
561     }
562
563     if (id) {
564     block->id = strdup(id);
565     if (!block->id) {
566         ErrPrint("Heap: %s\n", strerror(errno));
567         free(block->option);
568         free(block->data);
569         free(block->type);
570         free(block->part);
571         free(block);
572         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
573     }
574     }
575
576     block->idx = handle->last_idx++;
577     handle->block_list = dlist_append(handle->block_list, block);
578     return block->idx;
579 }
580
581 PUBLIC int dynamicbox_desc_del_block(struct dynamicbox_desc *handle, int idx)
582 {
583     struct dlist *l;
584     struct block *block;
585
586     if (!handle || idx < 0) {
587     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
588     }
589
590     dlist_foreach(handle->block_list, l, block) {
591     if (block->idx == idx) {
592         handle->block_list = dlist_remove(handle->block_list, l);
593         free(block->type);
594         free(block->part);
595         free(block->data);
596         free(block->option);
597         free(block->id);
598         free(block->target_id);
599         free(block);
600         return DBOX_STATUS_ERROR_NONE;
601     }
602     }
603
604     return DBOX_STATUS_ERROR_NOT_EXIST;
605 }
606
607 PUBLIC int dynamicbox_acquire_buffer(dynamicbox_buffer_h handle, int idx, int width, int height, int pixel_size)
608 {
609     int ret;
610
611     if (!handle || width <= 0 || height <= 0 || pixel_size <= 0 || idx > DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
612     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
613     }
614
615     if (idx >= 0) {
616     int _width = 0;
617     int _height = 0;
618     int _pixel_size = 0;
619     /* To validate the buffer */
620     if (dynamicbox_provider_buffer_get_size(handle, &_width, &_height, &_pixel_size) < 0) {
621         ErrPrint("Failed to get buffer size\n");
622     }
623
624         if (_width != width || _height != height || pixel_size != _pixel_size) {
625         DbgPrint("Extra buffer's geometry is not matched with primary one\n");
626     }
627
628     ret = dynamicbox_provider_buffer_extra_acquire(handle, idx, width, height, pixel_size);
629     } else {
630     ret = dynamicbox_provider_buffer_acquire(handle, width, height, pixel_size);
631     }
632
633     return ret;
634 }
635
636 PUBLIC dynamicbox_buffer_h dynamicbox_create_buffer(const char *filename, int is_gbar, int auto_align, int (*handler)(dynamicbox_buffer_h , dynamicbox_buffer_event_data_t, void *), void *data)
637 {
638     struct dynamicbox_buffer_data *user_data;
639     const char *pkgname;
640     dynamicbox_buffer_h handle;
641     char *uri;
642
643     if (!filename) {
644     ErrPrint("Invalid argument: %p(%dx%d)\n", filename);
645     return NULL;
646     }
647
648     user_data = calloc(1, sizeof(*user_data));
649     if (!user_data) {
650     ErrPrint("Heap: %s\n", strerror(errno));
651     return NULL;
652     }
653
654     user_data->is_gbar = is_gbar;
655     user_data->handler = handler ? handler : default_event_handler;
656     user_data->cbdata = data;
657
658     uri = id_to_uri(filename);
659     if (!uri) {
660     ErrPrint("Heap: %s\n", strerror(errno));
661     free(user_data);
662     return NULL;
663     }
664
665     if (!s_info.find_pkgname) {
666     s_info.find_pkgname = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_FIND_PKGNAME);
667     if (!s_info.find_pkgname) {
668         ErrPrint("Failed to find a \"dynamicbox_find_pkgname\"\n");
669         free(user_data);
670         free(uri);
671         return NULL;
672     }
673     }
674
675     pkgname = s_info.find_pkgname(uri);
676     if (!pkgname) {
677     ErrPrint("Invalid Request\n");
678     free(user_data);
679     free(uri);
680     return NULL;
681     }
682
683     handle = dynamicbox_provider_buffer_create((!!is_gbar) ? DBOX_TYPE_GBAR : DBOX_TYPE_DBOX, pkgname, uri, auto_align, event_handler_wrapper, user_data);
684     free(uri);
685     if (!handle) {
686     free(user_data);
687     return NULL;
688     }
689
690     (void)dynamicbox_provider_buffer_set_user_data(handle, user_data);
691     return handle;
692 }
693
694 PUBLIC int dynamicbox_request_update(const char *filename)
695 {
696     char *uri;
697     int ret;
698
699     if (!filename) {
700     ErrPrint("Invalid argument\n");
701     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
702     }
703
704     uri = id_to_uri(filename);
705     if (!uri) {
706     ErrPrint("Heap: %s\n", strerror(errno));
707     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
708     }
709
710     if (!s_info.request_update_by_id) {
711     s_info.request_update_by_id = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_REQUEST_UPDATE_BY_ID);
712     if (!s_info.request_update_by_id) {
713         ErrPrint("\"dynamicbox_request_update_by_id\" is not exists\n");
714         free(uri);
715         return DBOX_STATUS_ERROR_FAULT;
716     }
717     }
718
719     ret = s_info.request_update_by_id(uri);
720     free(uri);
721     return ret;
722 }
723
724 PUBLIC unsigned int dynamicbox_resource_id(dynamicbox_buffer_h handle, int idx)
725 {
726     int ret;
727
728     if (!handle || idx > DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
729     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
730     }
731
732     if (idx >= 0) {
733     ret = dynamicbox_provider_buffer_extra_resource_id(handle, idx);
734     } else {
735     ret = dynamicbox_provider_buffer_resource_id(handle);
736     }
737
738     return ret;
739 }
740
741 PUBLIC int dynamicbox_release_buffer(dynamicbox_buffer_h handle, int idx)
742 {
743     int ret;
744
745     if (!handle || idx > DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
746     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
747     }
748
749     if (idx >= 0) {
750     ret = dynamicbox_provider_buffer_extra_release(handle, idx);
751     } else {
752     ret = dynamicbox_provider_buffer_release(handle);
753     }
754
755     DbgPrint("Release buffer: %d (%d)\n", idx, ret);
756     return ret;
757 }
758
759 PUBLIC int dynamicbox_destroy_buffer(dynamicbox_buffer_h handle)
760 {
761     struct dynamicbox_buffer_data *user_data;
762
763     if (!handle) {
764     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
765     }
766
767     user_data = dynamicbox_provider_buffer_user_data(handle);
768     if (user_data) {
769     free(user_data->content);
770     free(user_data->title);
771     free(user_data->icon);
772     free(user_data->name);
773     free(user_data);
774     dynamicbox_provider_buffer_set_user_data(handle, NULL);
775     }
776
777     DbgPrint("Destroy buffer\n");
778     return dynamicbox_provider_buffer_destroy(handle);
779 }
780
781 PUBLIC void *dynamicbox_ref_buffer(dynamicbox_buffer_h handle)
782 {
783     struct dynamicbox_buffer_data *user_data;
784     void *data;
785     int w, h, size;
786     int ret;
787
788     if (!handle) {
789     return NULL;
790     }
791
792     user_data = dynamicbox_provider_buffer_user_data(handle);
793     if (!user_data) {
794     return NULL;
795     }
796
797     if (user_data->accelerated) {
798     DbgPrint("H/W accelerated buffer is allocated\n");
799     return NULL;
800     }
801
802     ret = dynamicbox_provider_buffer_get_size(handle, &w, &h, &size);
803
804     data = dynamicbox_provider_buffer_ref(handle);
805     if (data && !ret && w > 0 && h > 0 && size > 0) {
806     memset(data, 0, w * h * size);
807     (void)dynamicbox_provider_buffer_sync(handle);
808     }
809
810     DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
811     return data;
812 }
813
814 PUBLIC int dynamicbox_unref_buffer(void *buffer)
815 {
816     if (!buffer) {
817     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
818     }
819
820     DbgPrint("Unref buffer\n");
821     return dynamicbox_provider_buffer_unref(buffer);
822 }
823
824 PUBLIC int dynamicbox_sync_buffer(dynamicbox_buffer_h handle)
825 {
826     struct dynamicbox_buffer_data *user_data;
827     const char *pkgname;
828     const char *id;
829     int w;
830     int h;
831     int pixel_size;
832
833     if (!handle) {
834     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
835     }
836
837     user_data = dynamicbox_provider_buffer_user_data(handle);
838     if (!user_data) {
839     ErrPrint("Invalid buffer\n");
840     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
841     }
842
843     if (user_data->accelerated) {
844     DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
845     return DBOX_STATUS_ERROR_NONE;
846     }
847
848     pkgname = dynamicbox_provider_buffer_pkgname(handle);
849     if (!pkgname) {
850     ErrPrint("Invalid buffer handler\n");
851     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
852     }
853
854     id = dynamicbox_provider_buffer_id(handle);
855     if (!id) {
856     ErrPrint("Invalid buffer handler\n");
857     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
858     }
859
860     (void)dynamicbox_provider_buffer_sync(handle);
861
862     if (dynamicbox_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
863     ErrPrint("Failed to get size (%s)\n", id);
864     }
865
866     /**
867      * @todo
868      * manipulate the damaged region, so send update event only for the damaged region.
869      * to make more efficient updates
870      */
871
872     if (user_data->is_gbar == 1) {
873     if (send_updated(pkgname, id, DBOX_PRIMARY_BUFFER, 0, 0, w, h, user_data->is_gbar, NULL) < 0) {
874         ErrPrint("Failed to send GBAR updated (%s)\n", id);
875     }
876     } else {
877     if (send_updated(pkgname, id, DBOX_PRIMARY_BUFFER, 0, 0, w, h, user_data->is_gbar, NULL) < 0) {
878         ErrPrint("Failed to send updated (%s)\n", id);
879     }
880     }
881
882     return DBOX_STATUS_ERROR_NONE;
883 }
884
885 PUBLIC int dynamicbox_send_updated_by_idx(dynamicbox_buffer_h handle, int idx)
886 {
887     struct dynamicbox_buffer_data *user_data;
888     const char *pkgname;
889     const char *id;
890     int w;
891     int h;
892     int pixel_size;
893
894     user_data = dynamicbox_provider_buffer_user_data(handle);
895     if (!user_data) {
896     ErrPrint("Invalid buffer\n");
897     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
898     }
899
900     pkgname = dynamicbox_provider_buffer_pkgname(handle);
901     if (!pkgname) {
902     ErrPrint("Invalid buffer handler\n");
903     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
904     }
905
906     id = dynamicbox_provider_buffer_id(handle);
907     if (!id) {
908     ErrPrint("Invalid buffer handler\n");
909     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
910     }
911
912     if (dynamicbox_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
913     ErrPrint("Failed to get size (%s)\n", id);
914     }
915
916     if (send_updated(pkgname, id, idx, 0, 0, w, h, user_data->is_gbar, NULL) < 0) {
917     ErrPrint("Failed to send GBAR updated (%s) %d\n", id, idx);
918     }
919 }
920
921 PUBLIC int dynamicbox_support_hw_buffer(dynamicbox_buffer_h handle)
922 {
923     if (!handle) {
924     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
925     }
926
927     return dynamicbox_provider_buffer_is_support_hw(handle);
928 }
929
930 PUBLIC int dynamicbox_create_hw_buffer(dynamicbox_buffer_h handle)
931 {
932     struct dynamicbox_buffer_data *user_data;
933     int ret;
934
935     if (!handle) {
936     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
937     }
938
939     user_data = dynamicbox_provider_buffer_user_data(handle);
940     if (!user_data) {
941     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
942     }
943
944     if (user_data->accelerated) {
945     return DBOX_STATUS_ERROR_ALREADY;
946     }
947
948     ret = dynamicbox_provider_buffer_create_hw(handle);
949     user_data->accelerated = (ret == 0);
950     return ret;
951 }
952
953 PUBLIC int dynamicbox_destroy_hw_buffer(dynamicbox_buffer_h handle)
954 {
955     struct dynamicbox_buffer_data *user_data;
956
957     if (!handle) {
958     LOGD("handle is NULL\n");
959     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
960     }
961
962     user_data = dynamicbox_provider_buffer_user_data(handle);
963     if (!user_data || !user_data->accelerated) {
964     LOGD("user_data is NULL\n");
965     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
966     }
967
968     user_data->accelerated = 0;
969
970     return dynamicbox_provider_buffer_destroy_hw(handle);
971 }
972
973 PUBLIC void *dynamicbox_buffer_hw_buffer(dynamicbox_buffer_h handle)
974 {
975     struct dynamicbox_buffer_data *user_data;
976
977     if (!handle) {
978     return NULL;
979     }
980
981     user_data = dynamicbox_provider_buffer_user_data(handle);
982     if (!user_data || !user_data->accelerated) {
983     return NULL;
984     }
985
986     return dynamicbox_provider_buffer_hw_addr(handle);
987 }
988
989 PUBLIC int dynamicbox_buffer_pre_render(dynamicbox_buffer_h handle)
990 {
991     struct dynamicbox_buffer_data *user_data;
992
993     if (!handle) {
994     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
995     }
996
997     user_data = dynamicbox_provider_buffer_user_data(handle);
998     if (!user_data) {
999     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1000     }
1001
1002     if (!user_data->accelerated) {
1003     return DBOX_STATUS_ERROR_NONE;
1004     }
1005
1006     /*!
1007      * \note
1008      * Do preprocessing for accessing the H/W render buffer
1009      */
1010     return dynamicbox_provider_buffer_pre_render(handle);
1011 }
1012
1013 PUBLIC int dynamicbox_buffer_post_render(dynamicbox_buffer_h handle)
1014 {
1015     int ret;
1016     const char *pkgname;
1017     const char *id;
1018     struct dynamicbox_buffer_data *user_data;
1019     int w;
1020     int h;
1021     int pixel_size;
1022
1023     if (!handle) {
1024     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1025     }
1026
1027     user_data = dynamicbox_provider_buffer_user_data(handle);
1028     if (!user_data) {
1029     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1030     }
1031
1032     if (!user_data->accelerated) {
1033     return DBOX_STATUS_ERROR_NONE;
1034     }
1035
1036     pkgname = dynamicbox_provider_buffer_pkgname(handle);
1037     if (!pkgname) {
1038     ErrPrint("Invalid buffer handle\n");
1039     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1040     }
1041
1042     id = dynamicbox_provider_buffer_id(handle);
1043     if (!id) {
1044     ErrPrint("Invalid buffer handler\n");
1045     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1046     }
1047
1048     ret = dynamicbox_provider_buffer_post_render(handle);
1049     if (ret < 0) {
1050     ErrPrint("Failed to post render processing\n");
1051     return ret;
1052     }
1053
1054     if (dynamicbox_provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
1055     ErrPrint("Failed to get size (%s)\n", id);
1056     }
1057
1058     /**
1059      * @todo
1060      * manipulate the damaged region, so send update event only for the damaged region.
1061      * to make more efficient updates
1062      */
1063
1064     if (send_updated(pkgname, id, DBOX_PRIMARY_BUFFER, 0, 0, w, h, user_data->is_gbar, NULL) < 0) {
1065     ErrPrint("Failed to send GBAR updated (%s)\n", id);
1066     }
1067
1068     return DBOX_STATUS_ERROR_NONE;
1069 }
1070
1071 PUBLIC int dynamicbox_buffer_stride(dynamicbox_buffer_h handle)
1072 {
1073     if (!handle) {
1074     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1075     }
1076
1077     return dynamicbox_provider_buffer_stride(handle);
1078 }
1079
1080 PUBLIC int dynamicbox_content_is_updated(const char *filename, int is_gbar)
1081 {
1082     if (!s_info.trigger_update_monitor) {
1083     s_info.trigger_update_monitor = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_TRIGGER_UPDATE_MONITOR);
1084     if (!s_info.trigger_update_monitor) {
1085         ErrPrint("Trigger update monitor function is not exists\n");
1086         return DBOX_STATUS_ERROR_FAULT;
1087     }
1088     }
1089
1090     return s_info.trigger_update_monitor(filename, is_gbar);
1091 }
1092
1093 PUBLIC int dynamicbox_request_close_glance_bar(const char *pkgname, const char *id, int reason)
1094 {
1095     char *uri;
1096     int schema_len = strlen(FILE_SCHEMA);
1097     int ret;
1098
1099     if (!pkgname || !id) {
1100     ErrPrint("Invalid parameters (%s) (%s)\n", pkgname, id);
1101     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1102     }
1103
1104     if (strncmp(id, FILE_SCHEMA, schema_len)) {
1105     uri = id_to_uri(id);
1106     if (!uri) {
1107         ErrPrint("Heap: %s\n", strerror(errno));
1108         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1109     }
1110     } else {
1111     uri = strdup(id);
1112     if (!uri) {
1113         ErrPrint("Heap: %s\n", strerror(errno));
1114         return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1115     }
1116     }
1117
1118     ret = dynamicbox_provider_send_request_close_gbar(pkgname, uri, reason);
1119     free(uri);
1120     return ret;
1121 }
1122
1123 PUBLIC int dynamicbox_freeze_scroller(const char *pkgname, const char *id)
1124 {
1125     char *uri;
1126     int ret;
1127
1128     uri = id_to_uri(id);
1129     if (!uri) {
1130     ErrPrint("Heap: %s\n", strerror(errno));
1131     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1132     }
1133
1134     ret = dynamicbox_provider_send_hold_scroll(pkgname, uri, 1);
1135     free(uri);
1136     return ret;
1137 }
1138
1139 PUBLIC int dynamicbox_thaw_scroller(const char *pkgname, const char *id)
1140 {
1141     char *uri;
1142     int ret;
1143
1144     uri = id_to_uri(id);
1145     if (!uri) {
1146     ErrPrint("Heap: %s\n", strerror(errno));
1147     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1148     }
1149
1150     ret = dynamicbox_provider_send_hold_scroll(pkgname, uri, 0);
1151     free(uri);
1152     return ret;
1153 }
1154
1155 PUBLIC int dynamicbox_set_extra_info(const char *id, const char *content, const char *title, const char *icon, const char *name)
1156 {
1157     dynamicbox_buffer_h handle;
1158     const char *pkgname;
1159     char *uri;
1160
1161     uri = id_to_uri(id);
1162     if (!uri) {
1163     ErrPrint("Heap: %s\n", strerror(errno));
1164     return DBOX_STATUS_ERROR_OUT_OF_MEMORY;
1165     }
1166
1167     if (!s_info.find_pkgname) {
1168     s_info.find_pkgname = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_FIND_PKGNAME);
1169     if (!s_info.find_pkgname) {
1170         ErrPrint("Failed to find a \"dynamicbox_find_pkgname\"\n");
1171         free(uri);
1172         return DBOX_STATUS_ERROR_FAULT;
1173     }
1174     }
1175
1176     pkgname = s_info.find_pkgname(uri);
1177     if (!pkgname) {
1178     ErrPrint("Failed to find a package (%s)\n", uri);
1179     free(uri);
1180     return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1181     }
1182
1183     handle = dynamicbox_provider_buffer_find_buffer(DBOX_TYPE_DBOX, pkgname, uri);
1184     if (handle) {
1185     struct dynamicbox_buffer_data *user_data;
1186
1187     user_data = dynamicbox_provider_buffer_user_data(handle);
1188     if (!user_data) {
1189         ErrPrint("User data is not available\n");
1190         free(uri);
1191         return DBOX_STATUS_ERROR_FAULT;
1192     }
1193
1194     if (content && strlen(content)) {
1195         char *_content;
1196
1197         _content = strdup(content);
1198         if (_content) {
1199         if (user_data->content) {
1200             free(user_data->content);
1201         }
1202
1203         user_data->content = _content;
1204         } else {
1205         ErrPrint("Heap: %s\n", strerror(errno));
1206         }
1207     }
1208
1209     if (title && strlen(title)) {
1210         char *_title;
1211
1212         _title = strdup(title);
1213         if (_title) {
1214         if (user_data->title) {
1215             free(user_data->title);
1216         }
1217
1218         user_data->title = _title;
1219         } else {
1220         ErrPrint("Heap: %s\n", strerror(errno));
1221         }
1222     }
1223
1224     if (icon && strlen(icon)) {
1225         char *_icon;
1226
1227         _icon = strdup(icon);
1228         if (_icon) {
1229         if (user_data->icon) {
1230             free(user_data->icon);
1231         }
1232
1233         user_data->icon = _icon;
1234         } else {
1235         ErrPrint("Heap: %s\n", strerror(errno));
1236         }
1237     }
1238
1239     if (name && strlen(name)) {
1240         char *_name;
1241
1242         _name = strdup(name);
1243         if (_name) {
1244         if (user_data->name) {
1245             free(user_data->name);
1246         }
1247
1248         user_data->name = _name;
1249         } else {
1250         ErrPrint("Heap: %s\n", strerror(errno));
1251         }
1252     }
1253
1254     if (dynamicbox_provider_send_extra_info(pkgname, uri, -1.0f, user_data->content, user_data->title, user_data->icon, user_data->name) < 0) {
1255         ErrPrint("Failed to send extra info (%s)\n", id);
1256     }
1257
1258     free(uri);
1259     return DBOX_STATUS_ERROR_NONE;
1260     }
1261     free(uri);
1262
1263     if (!s_info.update_extra_info) {
1264     s_info.update_extra_info = dlsym(RTLD_DEFAULT, FUNC_DYNAMICBOX_UPDATE_EXTRA_INFO);
1265     if (!s_info.update_extra_info) {
1266         ErrPrint("Failed to find a \"dynamicbox_update_extra_info\"\n");
1267         return DBOX_STATUS_ERROR_INVALID_PARAMETER;
1268     }
1269     }
1270
1271     return s_info.update_extra_info(id, content, title, icon, name);
1272 }
1273
1274 /* End of a file */