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