Find the internal API using dlsym.
[platform/framework/web/livebox.git] / src / livebox.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 <livebox-service.h>
28 #include <provider.h>
29 #include <provider_buffer.h>
30 #include <livebox-errno.h>
31
32 #include "debug.h"
33 #include "livebox.h"
34 #include "dlist.h"
35 #include "util.h"
36
37 #define PUBLIC __attribute__((visibility("default")))
38
39 #define FILE_SCHEMA     "file://"
40
41 /*!
42  * \brief This function is defined by the data-provider-slave
43  */
44 static struct info {
45         const char *(*find_pkgname)(const char *filename);
46         int (*request_update_by_id)(const char *uri);
47         int (*trigger_update_monitor)(const char *id, int is_pd);
48 } s_info = {
49         .find_pkgname = NULL,
50         .request_update_by_id = NULL,
51         .trigger_update_monitor = NULL,
52 };
53
54 struct block {
55         unsigned int idx;
56
57         char *type;
58         char *part;
59         char *data;
60         char *option;
61         char *id;
62         char *file;
63         char *target_id;
64 };
65
66 struct livebox_desc {
67         FILE *fp;
68         int for_pd;
69
70         unsigned int last_idx;
71
72         struct dlist *block_list;
73 };
74
75 struct livebox_buffer_data {
76         int is_pd;
77         int accelerated;
78
79         /* for Buffer event wrapper */
80         int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
81         void *cbdata;
82 };
83
84 PUBLIC const int DONE = 0x00;
85 PUBLIC const int OUTPUT_UPDATED = 0x02;
86 PUBLIC const int USE_NET = 0x04;
87
88 PUBLIC const int NEED_TO_SCHEDULE = 0x01;
89 PUBLIC const int NEED_TO_CREATE = 0x01;
90 PUBLIC const int NEED_TO_DESTROY = 0x01;
91 PUBLIC const int NEED_TO_UPDATE = 0x01;
92
93 PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
94 PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
95 PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
96 PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
97 PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
98 PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
99 PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
100
101 PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
102 {
103         struct livebox_desc *handle;
104         char *new_fname;
105
106         handle = calloc(1, sizeof(*handle));
107         if (!handle) {
108                 ErrPrint("Error: %s\n", strerror(errno));
109                 return NULL;
110         }
111
112         if (for_pd) {
113                 int len;
114                 len = strlen(filename) + strlen(".desc") + 1;
115                 new_fname = malloc(len);
116                 if (!new_fname) {
117                         ErrPrint("Error: %s\n", strerror(errno));
118                         free(handle);
119                         return NULL;
120                 }
121                 snprintf(new_fname, len, "%s.desc", filename);
122         } else {
123                 new_fname = strdup(filename);
124                 if (!new_fname) {
125                         ErrPrint("Error: %s\n", strerror(errno));
126                         free(handle);
127                         return NULL;
128                 }
129         }
130
131         DbgPrint("Open a file %s with merge mode %s\n",
132                                 new_fname,
133                                 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
134
135         handle->fp = fopen(new_fname, "at");
136         free(new_fname);
137         if (!handle->fp) {
138                 ErrPrint("Failed to open a file: %s\n", strerror(errno));
139                 free(handle);
140                 return NULL;
141         }
142
143         return handle;
144 }
145
146 PUBLIC int livebox_desc_close(struct livebox_desc *handle)
147 {
148         struct dlist *l;
149         struct dlist *n;
150         struct block *block;
151
152         if (!handle) {
153                 return LB_STATUS_ERROR_INVALID;
154         }
155
156         dlist_foreach_safe(handle->block_list, l, n, block) {
157                 handle->block_list = dlist_remove(handle->block_list, l);
158
159                 fprintf(handle->fp, "{\n");
160                 if (block->type) {
161                         fprintf(handle->fp, "type=%s\n", block->type);
162                 }
163
164                 if (block->part) {
165                         fprintf(handle->fp, "part=%s\n", block->part);
166                 }
167
168                 if (block->data) {
169                         fprintf(handle->fp, "data=%s\n", block->data);
170                 }
171
172                 if (block->option) {
173                         fprintf(handle->fp, "option=%s\n", block->option);
174                 }
175
176                 if (block->id) {
177                         fprintf(handle->fp, "id=%s\n", block->id);
178                 }
179
180                 if (block->target_id) {
181                         fprintf(handle->fp, "target=%s\n", block->target_id);
182                 }
183                 fprintf(handle->fp, "}\n");
184
185                 free(block->type);
186                 free(block->part);
187                 free(block->data);
188                 free(block->option);
189                 free(block->id);
190                 free(block->target_id);
191                 free(block);
192         }
193
194         if (fclose(handle->fp) != 0) {
195                 ErrPrint("fclose: %s\n", strerror(errno));
196         }
197         free(handle);
198         return LB_STATUS_SUCCESS;
199 }
200
201 PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
202 {
203         struct block *block;
204
205         if (!handle || !category) {
206                 return LB_STATUS_ERROR_INVALID;
207         }
208
209         block = calloc(1, sizeof(*block));
210         if (!block) {
211                 return LB_STATUS_ERROR_MEMORY;
212         }
213
214         block->type = strdup(LB_DESC_TYPE_INFO);
215         if (!block->type) {
216                 free(block);
217                 return LB_STATUS_ERROR_MEMORY;
218         }
219
220         block->part = strdup("category");
221         if (!block->part) {
222                 free(block->type);
223                 free(block);
224                 return LB_STATUS_ERROR_MEMORY;
225         }
226
227         block->data = strdup(category);
228         if (!block->data) {
229                 free(block->type);
230                 free(block->part);
231                 free(block);
232                 return LB_STATUS_ERROR_MEMORY;
233         }
234
235         if (id) {
236                 block->id = strdup(id);
237                 if (!block->id) {
238                         free(block->data);
239                         free(block->type);
240                         free(block->part);
241                         free(block);
242                         return LB_STATUS_ERROR_MEMORY;
243                 }
244         }
245
246         block->idx = handle->last_idx++;
247         handle->block_list = dlist_append(handle->block_list, block);
248         return block->idx;
249 }
250
251 PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
252 {
253         struct block *block;
254         char buffer[BUFSIZ];
255
256         if (!handle) {
257                 return LB_STATUS_ERROR_INVALID;
258         }
259
260         block = calloc(1, sizeof(*block));
261         if (!block) {
262                 return LB_STATUS_ERROR_MEMORY;
263         }
264
265         block->type = strdup(LB_DESC_TYPE_INFO);
266         if (!block->type) {
267                 free(block);
268                 return LB_STATUS_ERROR_MEMORY;
269         }
270
271         block->part = strdup("size");
272         if (!block->part) {
273                 free(block->type);
274                 free(block);
275                 return LB_STATUS_ERROR_MEMORY;
276         }
277
278         if (id) {
279                 block->id = strdup(id);
280                 if (!block->id) {
281                         free(block->part);
282                         free(block->type);
283                         free(block);
284                         return LB_STATUS_ERROR_MEMORY;
285                 }
286         }
287
288         snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
289         block->data = strdup(buffer);
290         if (!block->data) {
291                 free(block->part);
292                 free(block->type);
293                 free(block);
294                 return LB_STATUS_ERROR_MEMORY;
295         }
296
297         block->idx = handle->last_idx++;
298         handle->block_list = dlist_append(handle->block_list, block);
299         return block->idx;
300 }
301
302 PUBLIC char *livebox_util_nl2br(const char *str)
303 {
304         int len;
305         register int i;
306         char *ret;
307         char *ptr;
308
309         if (!str) {
310                 return NULL;
311         }
312
313         len = strlen(str);
314         if (!len) {
315                 return NULL;
316         }
317
318         ret = malloc(len + 1);
319         if (!ret) {
320                 return NULL;
321         }
322
323         ptr = ret;
324         i = 0;
325         while (*str) {
326                 switch (*str) {
327                 case '\n':
328                         if (len - i < 5) {
329                                 char *tmp;
330                                 len += len;
331
332                                 tmp = realloc(ret, len + 1);
333                                 if (!tmp) {
334                                         free(ret);
335                                         return NULL;
336                                 }
337
338                                 ret = tmp;
339                                 ptr = tmp + i;
340                         }
341
342                         strcpy(ptr, "<br>");
343                         ptr += 4;
344                         i += 4;
345                         break;
346                 default:
347                         *ptr++ = *str;
348                         i++;
349                         break;
350                 }
351
352                 str++;
353         }
354         *ptr = '\0';
355
356         return ret;
357 }
358
359 PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
360 {
361         struct dlist *l;
362         struct block *block;
363
364         dlist_foreach(handle->block_list, l, block) {
365                 if (block->idx == idx) {
366                         if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
367                                 ErrPrint("Invalid block is used\n");
368                                 return LB_STATUS_ERROR_INVALID;
369                         }
370
371                         free(block->target_id);
372                         block->target_id = NULL;
373
374                         if (!id || !strlen(id)) {
375                                 return LB_STATUS_SUCCESS;
376                         }
377
378                         block->target_id = strdup(id);
379                         if (!block->target_id) {
380                                 ErrPrint("Heap: %s\n", strerror(errno));
381                                 return LB_STATUS_ERROR_MEMORY;
382                         }
383
384                         return LB_STATUS_SUCCESS;
385                 }
386         }
387
388         return LB_STATUS_ERROR_NOT_EXIST;
389 }
390
391 /*!
392  * \return idx
393  */
394 PUBLIC int livebox_desc_add_block(struct livebox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *option)
395 {
396         struct block *block;
397
398         if (!handle || !type) {
399                 return LB_STATUS_ERROR_INVALID;
400         }
401
402         if (!part) {
403                 part = "";
404         }
405
406         if (!data) {
407                 data = "";
408         }
409
410         block = calloc(1, sizeof(*block));
411         if (!block) {
412                 ErrPrint("Heap: %s\n", strerror(errno));
413                 return LB_STATUS_ERROR_MEMORY;
414         }
415
416         block->type = strdup(type);
417         if (!block->type) {
418                 ErrPrint("Heap: %s\n", strerror(errno));
419                 free(block);
420                 return LB_STATUS_ERROR_MEMORY;
421         }
422
423         block->part = strdup(part);
424         if (!block->part) {
425                 ErrPrint("Heap: %s\n", strerror(errno));
426                 free(block->type);
427                 free(block);
428                 return LB_STATUS_ERROR_MEMORY;
429         }
430
431         block->data = strdup(data);
432         if (!block->data) {
433                 ErrPrint("Heap: %s\n", strerror(errno));
434                 free(block->type);
435                 free(block->part);
436                 free(block);
437                 return LB_STATUS_ERROR_MEMORY;
438         }
439
440         if (option) {
441                 block->option = strdup(option);
442                 if (!block->option) {
443                         ErrPrint("Heap: %s\n", strerror(errno));
444                         free(block->data);
445                         free(block->type);
446                         free(block->part);
447                         free(block);
448                         return LB_STATUS_ERROR_MEMORY;
449                 }
450         }
451
452         if (id) {
453                 block->id = strdup(id);
454                 if (!block->id) {
455                         ErrPrint("Heap: %s\n", strerror(errno));
456                         free(block->option);
457                         free(block->data);
458                         free(block->type);
459                         free(block->part);
460                         free(block);
461                         return LB_STATUS_ERROR_MEMORY;
462                 }
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 livebox_desc_del_block(struct livebox_desc *handle, int idx)
471 {
472         struct dlist *l;
473         struct block *block;
474
475         dlist_foreach(handle->block_list, l, block) {
476                 if (block->idx == idx) {
477                         handle->block_list = dlist_remove(handle->block_list, l);
478                         free(block->type);
479                         free(block->part);
480                         free(block->data);
481                         free(block->option);
482                         free(block->id);
483                         free(block->target_id);
484                         free(block);
485                         return LB_STATUS_SUCCESS;
486                 }
487         }
488
489         return LB_STATUS_ERROR_NOT_EXIST;
490 }
491
492 /*!
493  * \note
494  * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
495  */
496 static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
497 {
498         const char *pkgname;
499         const char *id;
500         struct livebox_buffer_data *cbdata = data;
501         int ret;
502
503         pkgname = provider_buffer_pkgname(buffer);
504         if (!pkgname) {
505                 ErrPrint("pkgname is not valid\n");
506                 return LB_STATUS_ERROR_INVALID;
507         }
508
509         id = provider_buffer_id(buffer);
510         if (!id) {
511                 ErrPrint("id is not valid[%s]\n", pkgname);
512                 return LB_STATUS_ERROR_INVALID;
513         }
514
515         ret = cbdata->handler(buffer, event, timestamp, x, y, cbdata->cbdata);
516
517         switch (event) {
518         case BUFFER_EVENT_HIGHLIGHT:
519         case BUFFER_EVENT_HIGHLIGHT_NEXT:
520         case BUFFER_EVENT_HIGHLIGHT_PREV:
521         case BUFFER_EVENT_ACTIVATE:
522         case BUFFER_EVENT_ACTION_UP:
523         case BUFFER_EVENT_ACTION_DOWN:
524         case BUFFER_EVENT_SCROLL_UP:
525         case BUFFER_EVENT_SCROLL_MOVE:
526         case BUFFER_EVENT_SCROLL_DOWN:
527         case BUFFER_EVENT_UNHIGHLIGHT:
528                 DbgPrint("Accessibility event: %d\n", event);
529                 if (ret < 0) {
530                         (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
531                 } else {
532                         (void)provider_send_access_status(pkgname, id, ret);
533                 }
534                 break;
535         default:
536                 break;
537         }
538
539         return ret;
540 }
541
542 static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event event, double timestamp, double x, double y, void *data)
543 {
544         /* NOP */
545         return 0;
546 }
547
548 PUBLIC struct livebox_buffer *livebox_acquire_buffer(const char *filename, int is_pd, int width, int height, int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *), void *data)
549 {
550         struct livebox_buffer_data *user_data;
551         const char *pkgname;
552         struct livebox_buffer *handle;
553         char *uri;
554         int uri_len;
555
556         if (!filename || !width || !height) {
557                 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
558                 return NULL;
559         }
560
561         user_data = calloc(1, sizeof(*user_data));
562         if (!user_data) {
563                 ErrPrint("Heap: %s\n", strerror(errno));
564                 return NULL;
565         }
566
567         user_data->is_pd = is_pd;
568         user_data->handler = handler ? handler : default_event_handler;
569         user_data->cbdata = data;
570
571         uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
572         uri = malloc(uri_len);
573         if (!uri) {
574                 ErrPrint("Heap: %s\n", strerror(errno));
575                 free(user_data);
576                 return NULL;
577         }
578
579         snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
580         if (!s_info.find_pkgname) {
581                 s_info.find_pkgname = dlsym(RTLD_DEFAULT, "livebox_find_pkgname");
582                 if (!s_info.find_pkgname) {
583                         ErrPrint("Failed to find a \"livebox_find_pkgname\"\n");
584                         free(user_data);
585                         free(uri);
586                         return NULL;
587                 }
588         }
589
590         pkgname = s_info.find_pkgname(uri);
591         if (!pkgname) {
592                 ErrPrint("Invalid Request\n");
593                 free(user_data);
594                 free(uri);
595                 return NULL;
596         }
597
598         handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
599         DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
600         free(uri);
601         if (!handle) {
602                 free(user_data);
603                 return NULL;
604         }
605
606         (void)provider_buffer_set_user_data(handle, user_data);
607         return handle;
608 }
609
610 PUBLIC int livebox_request_update(const char *filename)
611 {
612         int uri_len;
613         char *uri;
614         int ret;
615
616         if (!filename) {
617                 ErrPrint("Invalid argument\n");
618                 return LB_STATUS_ERROR_INVALID;
619         }
620
621         uri_len = strlen(filename) + strlen(FILE_SCHEMA) + 1;
622         uri = malloc(uri_len);
623         if (!uri) {
624                 ErrPrint("Heap: %s\n", strerror(errno));
625                 return LB_STATUS_ERROR_MEMORY;
626         }
627
628         snprintf(uri, uri_len, FILE_SCHEMA "%s", filename);
629         if (!s_info.request_update_by_id) {
630                 s_info.request_update_by_id = dlsym(RTLD_DEFAULT, "livebox_request_update_by_id");
631                 if (!s_info.request_update_by_id) {
632                         ErrPrint("\"livebox_request_update_by_id\" is not exists\n");
633                         free(uri);
634                         return LB_STATUS_ERROR_FAULT;
635                 }
636         }
637         ret = s_info.request_update_by_id(uri);
638         free(uri);
639         return ret;
640 }
641
642 PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
643 {
644         return provider_buffer_pixmap_id(handle);
645 }
646
647 PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
648 {
649         struct livebox_buffer_data *user_data;
650
651         if (!handle) {
652                 return LB_STATUS_ERROR_INVALID;
653         }
654
655         user_data = provider_buffer_user_data(handle);
656         if (user_data) {
657                 free(user_data);
658                 provider_buffer_set_user_data(handle, NULL);
659         }
660
661         DbgPrint("Release buffer\n");
662         return provider_buffer_release(handle);
663 }
664
665 PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
666 {
667         struct livebox_buffer_data *user_data;
668         void *data;
669         int w, h, size;
670         int ret;
671
672         if (!handle) {
673                 return NULL;
674         }
675
676         user_data = provider_buffer_user_data(handle);
677         if (!user_data) {
678                 return NULL;
679         }
680
681         if (user_data->accelerated) {
682                 DbgPrint("H/W accelerated buffer is allocated\n");
683                 return NULL;
684         }
685
686         ret = provider_buffer_get_size(handle, &w, &h, &size);
687
688         data = provider_buffer_ref(handle);
689         if (data && !ret && w > 0 && h > 0 && size > 0) {
690                 memset(data, 0, w * h * size);
691                 provider_buffer_sync(handle);
692         }
693
694         DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
695         return data;
696 }
697
698 PUBLIC int livebox_unref_buffer(void *buffer)
699 {
700         if (!buffer) {
701                 return LB_STATUS_ERROR_INVALID;
702         }
703
704         DbgPrint("Unref buffer\n");
705         return provider_buffer_unref(buffer);
706 }
707
708 PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
709 {
710         struct livebox_buffer_data *user_data;
711         const char *pkgname;
712         const char *id;
713
714         if (!handle) {
715                 return LB_STATUS_ERROR_INVALID;
716         }
717
718         user_data = provider_buffer_user_data(handle);
719         if (!user_data) {
720                 ErrPrint("Invalid buffer\n");
721                 return LB_STATUS_ERROR_INVALID;
722         }
723
724         if (user_data->accelerated) {
725                 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
726                 return LB_STATUS_SUCCESS;
727         }
728
729         pkgname = provider_buffer_pkgname(handle);
730         if (!pkgname) {
731                 ErrPrint("Invalid buffer handler\n");
732                 return LB_STATUS_ERROR_INVALID;
733         }
734
735         id = provider_buffer_id(handle);
736         if (!id) {
737                 ErrPrint("Invalid buffer handler\n");
738                 return LB_STATUS_ERROR_INVALID;
739         }
740
741         provider_buffer_sync(handle);
742
743         if (user_data->is_pd) {
744                 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
745                         ErrPrint("Failed to send PD updated (%s)\n", id);
746                 }
747         } else {
748                 int w;
749                 int h;
750                 int pixel_size;
751
752                 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
753                         ErrPrint("Failed to get size (%s)\n", id);
754                 }
755
756                 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
757                         ErrPrint("Failed to send updated (%s)\n", id);
758                 }
759         }
760
761         return LB_STATUS_SUCCESS;
762 }
763
764 PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
765 {
766         if (!handle) {
767                 return LB_STATUS_ERROR_INVALID;
768         }
769
770         return provider_buffer_pixmap_is_support_hw(handle);
771 }
772
773 PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
774 {
775         struct livebox_buffer_data *user_data;
776         int ret;
777
778         if (!handle) {
779                 return LB_STATUS_ERROR_INVALID;
780         }
781
782         user_data = provider_buffer_user_data(handle);
783         if (!user_data) {
784                 return LB_STATUS_ERROR_INVALID;
785         }
786
787         if (user_data->accelerated) {
788                 return LB_STATUS_ERROR_ALREADY;
789         }
790
791         ret = provider_buffer_pixmap_create_hw(handle);
792         user_data->accelerated = (ret == 0);
793         return ret;
794 }
795
796 PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
797 {
798         struct livebox_buffer_data *user_data;
799         if (!handle) {
800                 return LB_STATUS_ERROR_INVALID;
801         }
802
803         user_data = provider_buffer_user_data(handle);
804         if (!user_data || !user_data->accelerated) {
805                 return LB_STATUS_ERROR_INVALID;
806         }
807
808         user_data->accelerated = 0;
809
810         return provider_buffer_pixmap_destroy_hw(handle);
811 }
812
813 PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
814 {
815         struct livebox_buffer_data *user_data;
816
817         if (!handle) {
818                 return NULL;
819         }
820
821         user_data = provider_buffer_user_data(handle);
822         if (!user_data || !user_data->accelerated) {
823                 return NULL;
824         }
825
826         return provider_buffer_pixmap_hw_addr(handle);
827 }
828
829 PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
830 {
831         struct livebox_buffer_data *user_data;
832
833         if (!handle) {
834                 return LB_STATUS_ERROR_INVALID;
835         }
836
837         user_data = provider_buffer_user_data(handle);
838         if (!user_data) {
839                 return LB_STATUS_ERROR_INVALID;
840         }
841
842         if (!user_data->accelerated) {
843                 return LB_STATUS_SUCCESS;
844         }
845
846         /*!
847          * \note
848          * Do preprocessing for accessing the H/W render buffer
849          */
850         return provider_buffer_pre_render(handle);
851 }
852
853 PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
854 {
855         int ret;
856         const char *pkgname;
857         const char *id;
858         struct livebox_buffer_data *user_data;
859
860         if (!handle) {
861                 return LB_STATUS_ERROR_INVALID;
862         }
863
864         user_data = provider_buffer_user_data(handle);
865         if (!user_data) {
866                 return LB_STATUS_ERROR_INVALID;
867         }
868
869         if (!user_data->accelerated) {
870                 return LB_STATUS_SUCCESS;
871         }
872
873         pkgname = provider_buffer_pkgname(handle);
874         if (!pkgname) {
875                 ErrPrint("Invalid buffer handle\n");
876                 return LB_STATUS_ERROR_INVALID;
877         }
878
879         id = provider_buffer_id(handle);
880         if (!id) {
881                 ErrPrint("Invalid buffer handler\n");
882                 return LB_STATUS_ERROR_INVALID;
883         }
884
885         ret = provider_buffer_post_render(handle);
886         if (ret < 0) {
887                 ErrPrint("Failed to post render processing\n");
888                 return ret;
889         }
890
891         if (user_data->is_pd == 1) {
892                 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
893                         ErrPrint("Failed to send PD updated (%s)\n", id);
894                 }
895         } else {
896                 int w;
897                 int h;
898                 int pixel_size;
899
900                 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
901                         ErrPrint("Failed to get size (%s)\n", id);
902                 }
903
904                 if (provider_send_updated(pkgname, id, w, h, -1.0f, NULL, NULL) < 0) {
905                         ErrPrint("Failed to send updated (%s)\n", id);
906                 }
907         }
908
909         return LB_STATUS_SUCCESS;
910 }
911
912 PUBLIC int livebox_content_is_updated(const char *filename, int is_pd)
913 {
914         if (!s_info.trigger_update_monitor) {
915                 s_info.trigger_update_monitor = dlsym(RTLD_DEFAULT, "livebox_trigger_update_monitor");
916                 if (!s_info.trigger_update_monitor) {
917                         ErrPrint("Trigger update monitor function is not exists\n");
918                         return LB_STATUS_ERROR_FAULT;
919                 }
920         }
921
922         return s_info.trigger_update_monitor(filename, is_pd);
923 }
924
925 /* End of a file */