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