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