Initialize Tizen 2.3
[apps/native/widget/widget.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 /* Must has to sync'd with data-provider-slave */
42 struct conf {
43         int width;
44         int height;
45
46         int base_width;
47         int base_height;
48         double minimum_period;
49
50         struct {
51                 char *script;
52                 char *abi;
53                 char *pd_group;
54                 double period;
55         } default_conf;
56
57         struct {
58                 char *name;
59                 char *secured;
60                 char *abi;
61         } launch_key;
62
63         double default_packet_time;
64
65         char *empty_content;
66         char *empty_title;
67
68         char *default_content;
69         char *default_title;
70
71         unsigned long minimum_space;
72
73         char *replace_tag;
74
75         double slave_ttl;
76         double slave_activate_time;
77         double slave_relaunch_time;
78         int slave_relaunch_count;
79
80         int max_log_line;
81         int max_log_file;
82
83         unsigned long sqlite_flush_max;
84
85         struct {
86                 char *conf;
87                 char *image;
88                 char *script;
89                 char *root;
90                 char *script_port;
91                 char *slave_log;
92                 char *reader;
93                 char *always;
94                 char *db;
95                 char *module;
96                 char *input;
97         } path;
98
99         int max_size_type;
100
101         int slave_max_load;
102
103         double ping_time;
104
105         int use_sw_backend;
106         char *provider_method;
107         int debug_mode;
108         int overwrite_content;
109         int com_core_thread;
110         int use_xmonitor;
111         int premultiplied;
112 };
113
114 /*!
115  * \brief This function is defined by the data-provider-slave
116  */
117 static struct info {
118         const char *(*find_pkgname)(const char *filename);
119         int (*request_update_by_id)(const char *uri);
120         int (*trigger_update_monitor)(const char *id, int is_pd);
121         int (*update_extra_info)(const char *id, const char *content, const char *title, const char *icon, const char *name);
122         struct conf *conf;
123 } s_info = {
124         .find_pkgname = NULL,
125         .request_update_by_id = NULL,
126         .trigger_update_monitor = NULL,
127         .update_extra_info = NULL,
128         .conf = NULL,
129 };
130
131 struct block {
132         unsigned int idx;
133
134         char *type;
135         char *part;
136         char *data;
137         char *option;
138         char *id;
139         char *file;
140         char *target_id;
141 };
142
143 struct livebox_desc {
144         FILE *fp;
145         int for_pd;
146
147         unsigned int last_idx;
148
149         struct dlist *block_list;
150 };
151
152 struct livebox_buffer_data {
153         int is_pd;
154         int accelerated;
155
156         /* for Buffer event wrapper */
157         int (*handler_NEW)(struct livebox_buffer *, struct buffer_event_data *, void *);
158         int (*handler)(struct livebox_buffer *, enum buffer_event, double, double, double, void *);
159         void *cbdata;
160
161         char *content;
162         char *title;
163         char *icon;
164         char *name;
165 };
166
167 PUBLIC const int DONE = 0x00;
168 PUBLIC const int OUTPUT_UPDATED = 0x02;
169 PUBLIC const int USE_NET = 0x04;
170
171 PUBLIC const int NEED_TO_SCHEDULE = 0x01;
172 PUBLIC const int NEED_TO_CREATE = 0x01;
173 PUBLIC const int NEED_TO_DESTROY = 0x01;
174 PUBLIC const int NEED_TO_UPDATE = 0x01;
175 PUBLIC const int FORCE_TO_SCHEDULE = 0x08;
176
177 PUBLIC const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
178 PUBLIC const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
179 PUBLIC const int LB_SYS_EVENT_TIME_CHANGED = 0x04;
180 PUBLIC const int LB_SYS_EVENT_REGION_CHANGED = 0x08;
181 PUBLIC const int LB_SYS_EVENT_PAUSED = 0x0100;
182 PUBLIC const int LB_SYS_EVENT_RESUMED = 0x0200;
183 PUBLIC const int LB_SYS_EVENT_MMC_STATUS_CHANGED = 0x0400;
184
185 static char *id_to_uri(const char *id)
186 {
187         char *uri;
188         int uri_len;
189
190         uri_len = strlen(id) + strlen(FILE_SCHEMA) + 1;
191
192         uri = malloc(uri_len);
193         if (!uri) {
194                 return NULL;
195         }
196
197         snprintf(uri, uri_len, FILE_SCHEMA "%s", id);
198         return uri;
199 }
200
201 PUBLIC struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
202 {
203         struct livebox_desc *handle;
204         char *new_fname;
205
206         handle = calloc(1, sizeof(*handle));
207         if (!handle) {
208                 ErrPrint("Error: %s\n", strerror(errno));
209                 return NULL;
210         }
211
212         if (for_pd) {
213                 int len;
214                 len = strlen(filename) + strlen(".desc") + 1;
215                 new_fname = malloc(len);
216                 if (!new_fname) {
217                         ErrPrint("Error: %s\n", strerror(errno));
218                         free(handle);
219                         return NULL;
220                 }
221                 snprintf(new_fname, len, "%s.desc", filename);
222         } else {
223                 new_fname = strdup(filename);
224                 if (!new_fname) {
225                         ErrPrint("Error: %s\n", strerror(errno));
226                         free(handle);
227                         return NULL;
228                 }
229         }
230
231         DbgPrint("Open a file %s with merge mode %s\n",
232                                 new_fname,
233                                 access(new_fname, F_OK) == 0 ? "enabled" : "disabled");
234
235         handle->fp = fopen(new_fname, "at");
236         free(new_fname);
237         if (!handle->fp) {
238                 ErrPrint("Failed to open a file: %s\n", strerror(errno));
239                 free(handle);
240                 return NULL;
241         }
242
243         return handle;
244 }
245
246 PUBLIC int livebox_desc_close(struct livebox_desc *handle)
247 {
248         struct dlist *l;
249         struct dlist *n;
250         struct block *block;
251
252         if (!handle) {
253                 return LB_STATUS_ERROR_INVALID;
254         }
255
256         dlist_foreach_safe(handle->block_list, l, n, block) {
257                 handle->block_list = dlist_remove(handle->block_list, l);
258
259                 fprintf(handle->fp, "{\n");
260                 if (block->type) {
261                         fprintf(handle->fp, "type=%s\n", block->type);
262                 }
263
264                 if (block->part) {
265                         fprintf(handle->fp, "part=%s\n", block->part);
266                 }
267
268                 if (block->data) {
269                         fprintf(handle->fp, "data=%s\n", block->data);
270                 }
271
272                 if (block->option) {
273                         fprintf(handle->fp, "option=%s\n", block->option);
274                 }
275
276                 if (block->id) {
277                         fprintf(handle->fp, "id=%s\n", block->id);
278                 }
279
280                 if (block->target_id) {
281                         fprintf(handle->fp, "target=%s\n", block->target_id);
282                 }
283                 fprintf(handle->fp, "}\n");
284
285                 free(block->type);
286                 free(block->part);
287                 free(block->data);
288                 free(block->option);
289                 free(block->id);
290                 free(block->target_id);
291                 free(block);
292         }
293
294         if (fclose(handle->fp) != 0) {
295                 ErrPrint("fclose: %s\n", strerror(errno));
296         }
297         free(handle);
298         return LB_STATUS_SUCCESS;
299 }
300
301 PUBLIC int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
302 {
303         struct block *block;
304
305         if (!handle || !category) {
306                 return LB_STATUS_ERROR_INVALID;
307         }
308
309         block = calloc(1, sizeof(*block));
310         if (!block) {
311                 return LB_STATUS_ERROR_MEMORY;
312         }
313
314         block->type = strdup(LB_DESC_TYPE_INFO);
315         if (!block->type) {
316                 free(block);
317                 return LB_STATUS_ERROR_MEMORY;
318         }
319
320         block->part = strdup("category");
321         if (!block->part) {
322                 free(block->type);
323                 free(block);
324                 return LB_STATUS_ERROR_MEMORY;
325         }
326
327         block->data = strdup(category);
328         if (!block->data) {
329                 free(block->type);
330                 free(block->part);
331                 free(block);
332                 return LB_STATUS_ERROR_MEMORY;
333         }
334
335         if (id) {
336                 block->id = strdup(id);
337                 if (!block->id) {
338                         free(block->data);
339                         free(block->type);
340                         free(block->part);
341                         free(block);
342                         return LB_STATUS_ERROR_MEMORY;
343                 }
344         }
345
346         block->idx = handle->last_idx++;
347         handle->block_list = dlist_append(handle->block_list, block);
348         return block->idx;
349 }
350
351 PUBLIC int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
352 {
353         struct block *block;
354         char buffer[BUFSIZ];
355
356         if (!handle) {
357                 return LB_STATUS_ERROR_INVALID;
358         }
359
360         block = calloc(1, sizeof(*block));
361         if (!block) {
362                 return LB_STATUS_ERROR_MEMORY;
363         }
364
365         block->type = strdup(LB_DESC_TYPE_INFO);
366         if (!block->type) {
367                 free(block);
368                 return LB_STATUS_ERROR_MEMORY;
369         }
370
371         block->part = strdup("size");
372         if (!block->part) {
373                 free(block->type);
374                 free(block);
375                 return LB_STATUS_ERROR_MEMORY;
376         }
377
378         if (id) {
379                 block->id = strdup(id);
380                 if (!block->id) {
381                         free(block->part);
382                         free(block->type);
383                         free(block);
384                         return LB_STATUS_ERROR_MEMORY;
385                 }
386         }
387
388         snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
389         block->data = strdup(buffer);
390         if (!block->data) {
391                 free(block->part);
392                 free(block->type);
393                 free(block);
394                 return LB_STATUS_ERROR_MEMORY;
395         }
396
397         block->idx = handle->last_idx++;
398         handle->block_list = dlist_append(handle->block_list, block);
399         return block->idx;
400 }
401
402 PUBLIC char *livebox_util_nl2br(const char *str)
403 {
404         int len;
405         register int i;
406         char *ret;
407         char *ptr;
408
409         if (!str) {
410                 return NULL;
411         }
412
413         len = strlen(str);
414         if (!len) {
415                 return NULL;
416         }
417
418         ret = malloc(len + 1);
419         if (!ret) {
420                 return NULL;
421         }
422
423         ptr = ret;
424         i = 0;
425         while (*str) {
426                 switch (*str) {
427                 case '\n':
428                         if (len - i < 5) {
429                                 char *tmp;
430                                 len += len;
431
432                                 tmp = realloc(ret, len + 1);
433                                 if (!tmp) {
434                                         free(ret);
435                                         return NULL;
436                                 }
437
438                                 ret = tmp;
439                                 ptr = tmp + i;
440                         }
441
442                         strcpy(ptr, "<br>");
443                         ptr += 4;
444                         i += 4;
445                         break;
446                 default:
447                         *ptr++ = *str;
448                         i++;
449                         break;
450                 }
451
452                 str++;
453         }
454         *ptr = '\0';
455
456         return ret;
457 }
458
459 PUBLIC int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
460 {
461         struct dlist *l;
462         struct block *block;
463
464         dlist_foreach(handle->block_list, l, block) {
465                 if (block->idx == idx) {
466                         if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
467                                 ErrPrint("Invalid block is used\n");
468                                 return LB_STATUS_ERROR_INVALID;
469                         }
470
471                         free(block->target_id);
472                         block->target_id = NULL;
473
474                         if (!id || !strlen(id)) {
475                                 return LB_STATUS_SUCCESS;
476                         }
477
478                         block->target_id = strdup(id);
479                         if (!block->target_id) {
480                                 ErrPrint("Heap: %s\n", strerror(errno));
481                                 return LB_STATUS_ERROR_MEMORY;
482                         }
483
484                         return LB_STATUS_SUCCESS;
485                 }
486         }
487
488         return LB_STATUS_ERROR_NOT_EXIST;
489 }
490
491 /*!
492  * \return idx
493  */
494 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)
495 {
496         struct block *block;
497
498         if (!handle || !type) {
499                 return LB_STATUS_ERROR_INVALID;
500         }
501
502         if (!part) {
503                 part = "";
504         }
505
506         if (!data) {
507                 data = "";
508         }
509
510         block = calloc(1, sizeof(*block));
511         if (!block) {
512                 ErrPrint("Heap: %s\n", strerror(errno));
513                 return LB_STATUS_ERROR_MEMORY;
514         }
515
516         block->type = strdup(type);
517         if (!block->type) {
518                 ErrPrint("Heap: %s\n", strerror(errno));
519                 free(block);
520                 return LB_STATUS_ERROR_MEMORY;
521         }
522
523         block->part = strdup(part);
524         if (!block->part) {
525                 ErrPrint("Heap: %s\n", strerror(errno));
526                 free(block->type);
527                 free(block);
528                 return LB_STATUS_ERROR_MEMORY;
529         }
530
531         block->data = strdup(data);
532         if (!block->data) {
533                 ErrPrint("Heap: %s\n", strerror(errno));
534                 free(block->type);
535                 free(block->part);
536                 free(block);
537                 return LB_STATUS_ERROR_MEMORY;
538         }
539
540         if (option) {
541                 block->option = strdup(option);
542                 if (!block->option) {
543                         ErrPrint("Heap: %s\n", strerror(errno));
544                         free(block->data);
545                         free(block->type);
546                         free(block->part);
547                         free(block);
548                         return LB_STATUS_ERROR_MEMORY;
549                 }
550         }
551
552         if (id) {
553                 block->id = strdup(id);
554                 if (!block->id) {
555                         ErrPrint("Heap: %s\n", strerror(errno));
556                         free(block->option);
557                         free(block->data);
558                         free(block->type);
559                         free(block->part);
560                         free(block);
561                         return LB_STATUS_ERROR_MEMORY;
562                 }
563         }
564
565         block->idx = handle->last_idx++;
566         handle->block_list = dlist_append(handle->block_list, block);
567         return block->idx;
568 }
569
570 PUBLIC int livebox_desc_del_block(struct livebox_desc *handle, int idx)
571 {
572         struct dlist *l;
573         struct block *block;
574
575         if (!handle || idx < 0) {
576                 return LB_STATUS_ERROR_INVALID;
577         }
578
579         dlist_foreach(handle->block_list, l, block) {
580                 if (block->idx == idx) {
581                         handle->block_list = dlist_remove(handle->block_list, l);
582                         free(block->type);
583                         free(block->part);
584                         free(block->data);
585                         free(block->option);
586                         free(block->id);
587                         free(block->target_id);
588                         free(block);
589                         return LB_STATUS_SUCCESS;
590                 }
591         }
592
593         return LB_STATUS_ERROR_NOT_EXIST;
594 }
595
596 static inline int event_handler_wrapper_NEW(struct livebox_buffer *buffer, struct buffer_event_data *event_info, void *data)
597 {
598         const char *pkgname;
599         const char *id;
600         struct livebox_buffer_data *cbdata = data;
601         int ret;
602
603         pkgname = provider_buffer_pkgname(buffer);
604         if (!pkgname) {
605                 ErrPrint("pkgname is not valid\n");
606                 return LB_STATUS_ERROR_INVALID;
607         }
608
609         id = provider_buffer_id(buffer);
610         if (!id) {
611                 ErrPrint("id is not valid[%s]\n", pkgname);
612                 return LB_STATUS_ERROR_INVALID;
613         }
614
615         if (cbdata->handler_NEW) {
616                 ret = cbdata->handler_NEW(buffer, event_info, cbdata->cbdata);
617         } else {
618                 ret = LB_STATUS_ERROR_FAULT;
619         }
620
621         switch (event_info->type) {
622         case BUFFER_EVENT_HIGHLIGHT:
623         case BUFFER_EVENT_HIGHLIGHT_NEXT:
624         case BUFFER_EVENT_HIGHLIGHT_PREV:
625         case BUFFER_EVENT_ACTIVATE:
626         case BUFFER_EVENT_ACTION_UP:
627         case BUFFER_EVENT_ACTION_DOWN:
628         case BUFFER_EVENT_SCROLL_UP:
629         case BUFFER_EVENT_SCROLL_MOVE:
630         case BUFFER_EVENT_SCROLL_DOWN:
631         case BUFFER_EVENT_UNHIGHLIGHT:
632                 DbgPrint("Accessibility event: %d\n", event_info->type);
633                 if (ret < 0) {
634                         (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
635                 } else {
636                         (void)provider_send_access_status(pkgname, id, ret);
637                 }
638                 break;
639         case BUFFER_EVENT_KEY_UP:
640         case BUFFER_EVENT_KEY_DOWN:
641         case BUFFER_EVENT_KEY_FOCUS_IN:
642         case BUFFER_EVENT_KEY_FOCUS_OUT:
643                 DbgPrint("Key event: %d\n", event_info->type);
644                 if (ret < 0) {
645                         (void)provider_send_key_status(pkgname, id, LB_KEY_STATUS_ERROR);
646                 } else {
647                         (void)provider_send_key_status(pkgname, id, ret);
648                 }
649                 break;
650         default:
651                 break;
652         }
653
654         return ret;
655 }
656
657 /*!
658  * \note
659  * The last "data" argument is same with "user_data" which is managed by "provider_set_user_data).
660  */
661 static inline int event_handler_wrapper(struct livebox_buffer *buffer, enum buffer_event type, double timestamp, double x, double y, void *data)
662 {
663         const char *pkgname;
664         const char *id;
665         struct livebox_buffer_data *cbdata = data;
666         int ret;
667
668         pkgname = provider_buffer_pkgname(buffer);
669         if (!pkgname) {
670                 ErrPrint("pkgname is not valid\n");
671                 return LB_STATUS_ERROR_INVALID;
672         }
673
674         id = provider_buffer_id(buffer);
675         if (!id) {
676                 ErrPrint("id is not valid[%s]\n", pkgname);
677                 return LB_STATUS_ERROR_INVALID;
678         }
679
680         if (cbdata->handler) {
681                 ret = cbdata->handler(buffer, type, timestamp, x, y, cbdata->cbdata);
682         } else {
683                 ret = LB_STATUS_ERROR_FAULT;
684         }
685
686         switch (type) {
687         case BUFFER_EVENT_HIGHLIGHT:
688         case BUFFER_EVENT_HIGHLIGHT_NEXT:
689         case BUFFER_EVENT_HIGHLIGHT_PREV:
690         case BUFFER_EVENT_ACTIVATE:
691         case BUFFER_EVENT_ACTION_UP:
692         case BUFFER_EVENT_ACTION_DOWN:
693         case BUFFER_EVENT_SCROLL_UP:
694         case BUFFER_EVENT_SCROLL_MOVE:
695         case BUFFER_EVENT_SCROLL_DOWN:
696         case BUFFER_EVENT_UNHIGHLIGHT:
697                 DbgPrint("Accessibility event: %d\n", type);
698                 if (ret < 0) {
699                         (void)provider_send_access_status(pkgname, id, LB_ACCESS_STATUS_ERROR);
700                 } else {
701                         (void)provider_send_access_status(pkgname, id, ret);
702                 }
703                 break;
704         case BUFFER_EVENT_KEY_UP:
705         case BUFFER_EVENT_KEY_DOWN:
706         case BUFFER_EVENT_KEY_FOCUS_IN:
707         case BUFFER_EVENT_KEY_FOCUS_OUT:
708                 DbgPrint("Key event: %d\n", type);
709                 if (ret < 0) {
710                         (void)provider_send_key_status(pkgname, id, LB_KEY_STATUS_ERROR);
711                 } else {
712                         (void)provider_send_key_status(pkgname, id, ret);
713                 }
714                 break;
715         default:
716                 break;
717         }
718
719         return ret;
720 }
721
722 static inline int default_event_handler_NEW(struct livebox_buffer *buffer, struct buffer_event_data *event_info, void *data)
723 {
724         /* NOP */
725         return 0;
726 }
727
728 static inline int default_event_handler(struct livebox_buffer *buffer, enum buffer_event type, double timestamp, double x, double y, void *data)
729 {
730         /* NOP */
731         return 0;
732 }
733
734 PUBLIC struct livebox_buffer *livebox_acquire_buffer_NEW(const char *filename, int is_pd, int width, int height, int pixels, int (*handler)(struct livebox_buffer *, struct buffer_event_data *, void *), void *data)
735 {
736         struct livebox_buffer_data *user_data;
737         const char *pkgname;
738         struct livebox_buffer *handle;
739         char *uri;
740
741         if (!filename || !width || !height) {
742                 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
743                 return NULL;
744         }
745
746         user_data = calloc(1, sizeof(*user_data));
747         if (!user_data) {
748                 ErrPrint("Heap: %s\n", strerror(errno));
749                 return NULL;
750         }
751
752         user_data->is_pd = is_pd;
753         user_data->handler_NEW = handler ? handler : default_event_handler_NEW;
754         user_data->handler = NULL;
755         user_data->cbdata = data;
756
757         uri = id_to_uri(filename);
758         if (!uri) {
759                 ErrPrint("Heap: %s\n", strerror(errno));
760                 free(user_data);
761                 return NULL;
762         }
763
764         if (!s_info.find_pkgname) {
765                 s_info.find_pkgname = dlsym(RTLD_DEFAULT, "livebox_find_pkgname");
766                 if (!s_info.find_pkgname) {
767                         ErrPrint("Failed to find a \"livebox_find_pkgname\"\n");
768                         free(user_data);
769                         free(uri);
770                         return NULL;
771                 }
772         }
773
774         pkgname = s_info.find_pkgname(uri);
775         if (!pkgname) {
776                 ErrPrint("Invalid Request\n");
777                 free(user_data);
778                 free(uri);
779                 return NULL;
780         }
781
782         handle = provider_buffer_create((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, event_handler_wrapper_NEW, user_data);
783         free(uri);
784         if (!handle) {
785                 free(user_data);
786                 return NULL;
787         }
788
789         if (provider_buffer_acquire_NEW(handle, width, height, pixels) < 0) {
790                 provider_buffer_destroy(handle);
791                 free(user_data);
792                 return NULL;
793         }
794
795         (void)provider_buffer_set_user_data(handle, user_data);
796         return handle;
797 }
798
799 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)
800 {
801         struct livebox_buffer_data *user_data;
802         const char *pkgname;
803         struct livebox_buffer *handle;
804         char *uri;
805
806         if (!filename || !width || !height) {
807                 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
808                 return NULL;
809         }
810
811         user_data = calloc(1, sizeof(*user_data));
812         if (!user_data) {
813                 ErrPrint("Heap: %s\n", strerror(errno));
814                 return NULL;
815         }
816
817         user_data->is_pd = is_pd;
818         user_data->handler = handler ? handler : default_event_handler;
819         user_data->handler_NEW = NULL;
820         user_data->cbdata = data;
821
822         uri = id_to_uri(filename);
823         if (!uri) {
824                 ErrPrint("Heap: %s\n", strerror(errno));
825                 free(user_data);
826                 return NULL;
827         }
828
829         if (!s_info.find_pkgname) {
830                 s_info.find_pkgname = dlsym(RTLD_DEFAULT, "livebox_find_pkgname");
831                 if (!s_info.find_pkgname) {
832                         ErrPrint("Failed to find a \"livebox_find_pkgname\"\n");
833                         free(user_data);
834                         free(uri);
835                         return NULL;
836                 }
837         }
838
839         pkgname = s_info.find_pkgname(uri);
840         if (!pkgname) {
841                 ErrPrint("Invalid Request\n");
842                 free(user_data);
843                 free(uri);
844                 return NULL;
845         }
846
847         handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), event_handler_wrapper, user_data);
848         DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
849         free(uri);
850         if (!handle) {
851                 free(user_data);
852                 return NULL;
853         }
854
855         (void)provider_buffer_set_user_data(handle, user_data);
856         return handle;
857 }
858
859 PUBLIC int livebox_request_update(const char *filename)
860 {
861         char *uri;
862         int ret;
863
864         if (!filename) {
865                 ErrPrint("Invalid argument\n");
866                 return LB_STATUS_ERROR_INVALID;
867         }
868
869         uri = id_to_uri(filename);
870         if (!uri) {
871                 ErrPrint("Heap: %s\n", strerror(errno));
872                 return LB_STATUS_ERROR_MEMORY;
873         }
874
875         if (!s_info.request_update_by_id) {
876                 s_info.request_update_by_id = dlsym(RTLD_DEFAULT, "livebox_request_update_by_id");
877                 if (!s_info.request_update_by_id) {
878                         ErrPrint("\"livebox_request_update_by_id\" is not exists\n");
879                         free(uri);
880                         return LB_STATUS_ERROR_FAULT;
881                 }
882         }
883         ret = s_info.request_update_by_id(uri);
884         free(uri);
885         return ret;
886 }
887
888 PUBLIC int livebox_conf_premultiplied_alpha(void)
889 {
890         if (!s_info.conf) {
891                 s_info.conf = dlsym(RTLD_DEFAULT, "g_conf");
892                 if (!s_info.conf) {
893                         ErrPrint("g_conf is not found\n");
894                         return 1;
895                 }
896
897                 DbgPrint("Premultiplied alpha: %d\n", s_info.conf->premultiplied);
898         }
899
900         return s_info.conf->premultiplied;
901 }
902
903 PUBLIC unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
904 {
905         return provider_buffer_pixmap_id(handle);
906 }
907
908 PUBLIC int livebox_release_buffer(struct livebox_buffer *handle)
909 {
910         struct livebox_buffer_data *user_data;
911
912         if (!handle) {
913                 return LB_STATUS_ERROR_INVALID;
914         }
915
916         user_data = provider_buffer_user_data(handle);
917         if (user_data) {
918                 free(user_data->content);
919                 free(user_data->title);
920                 free(user_data->icon);
921                 free(user_data->name);
922                 free(user_data);
923                 provider_buffer_set_user_data(handle, NULL);
924         }
925
926         DbgPrint("Release buffer\n");
927         return provider_buffer_release(handle);
928 }
929
930 PUBLIC int livebox_release_buffer_NEW(struct livebox_buffer *handle)
931 {
932         struct livebox_buffer_data *user_data;
933
934         if (!handle) {
935                 return LB_STATUS_ERROR_INVALID;
936         }
937
938         user_data = provider_buffer_user_data(handle);
939         if (user_data) {
940                 free(user_data->content);
941                 free(user_data->title);
942                 free(user_data->icon);
943                 free(user_data->name);
944                 free(user_data);
945                 provider_buffer_set_user_data(handle, NULL);
946         }
947
948         (void)provider_buffer_release_NEW(handle);
949         (void)provider_buffer_destroy(handle);
950
951         DbgPrint("Release buffer\n");
952         return 0;
953 }
954
955 PUBLIC void *livebox_ref_buffer(struct livebox_buffer *handle)
956 {
957         struct livebox_buffer_data *user_data;
958         void *data;
959         int w, h, size;
960         int ret;
961
962         if (!handle) {
963                 return NULL;
964         }
965
966         user_data = provider_buffer_user_data(handle);
967         if (!user_data) {
968                 return NULL;
969         }
970
971         if (user_data->accelerated) {
972                 DbgPrint("H/W accelerated buffer is allocated\n");
973                 return NULL;
974         }
975
976         ret = provider_buffer_get_size(handle, &w, &h, &size);
977
978         data = provider_buffer_ref(handle);
979         if (data && !ret && w > 0 && h > 0 && size > 0) {
980                 memset(data, 0, w * h * size);
981                 (void)provider_buffer_sync(handle);
982         }
983
984         DbgPrint("Ref buffer %ds%d(%d)\n", w, h, size);
985         return data;
986 }
987
988 PUBLIC int livebox_unref_buffer(void *buffer)
989 {
990         if (!buffer) {
991                 return LB_STATUS_ERROR_INVALID;
992         }
993
994         DbgPrint("Unref buffer\n");
995         return provider_buffer_unref(buffer);
996 }
997
998 PUBLIC int livebox_sync_buffer(struct livebox_buffer *handle)
999 {
1000         struct livebox_buffer_data *user_data;
1001         const char *pkgname;
1002         const char *id;
1003
1004         if (!handle) {
1005                 return LB_STATUS_ERROR_INVALID;
1006         }
1007
1008         user_data = provider_buffer_user_data(handle);
1009         if (!user_data) {
1010                 ErrPrint("Invalid buffer\n");
1011                 return LB_STATUS_ERROR_INVALID;
1012         }
1013
1014         if (user_data->accelerated) {
1015                 DbgPrint("H/W Buffer allocated. skip the sync buffer\n");
1016                 return LB_STATUS_SUCCESS;
1017         }
1018
1019         pkgname = provider_buffer_pkgname(handle);
1020         if (!pkgname) {
1021                 ErrPrint("Invalid buffer handler\n");
1022                 return LB_STATUS_ERROR_INVALID;
1023         }
1024
1025         id = provider_buffer_id(handle);
1026         if (!id) {
1027                 ErrPrint("Invalid buffer handler\n");
1028                 return LB_STATUS_ERROR_INVALID;
1029         }
1030
1031         (void)provider_buffer_sync(handle);
1032
1033         if (user_data->is_pd == 1) {
1034                 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
1035                         ErrPrint("Failed to send PD updated (%s)\n", id);
1036                 }
1037         } else {
1038                 int w;
1039                 int h;
1040                 int pixel_size;
1041
1042                 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
1043                         ErrPrint("Failed to get size (%s)\n", id);
1044                 }
1045
1046                 if (provider_send_updated_NEW(pkgname, id, w, h, -1.0f, user_data->content, user_data->title, user_data->icon, user_data->name) < 0) {
1047                         ErrPrint("Failed to send updated (%s)\n", id);
1048                 }
1049         }
1050
1051         return LB_STATUS_SUCCESS;
1052 }
1053
1054 PUBLIC int livebox_support_hw_buffer(struct livebox_buffer *handle)
1055 {
1056         if (!handle) {
1057                 return LB_STATUS_ERROR_INVALID;
1058         }
1059
1060         return provider_buffer_pixmap_is_support_hw(handle);
1061 }
1062
1063 PUBLIC int livebox_create_hw_buffer(struct livebox_buffer *handle)
1064 {
1065         struct livebox_buffer_data *user_data;
1066         int ret;
1067
1068         if (!handle) {
1069                 return LB_STATUS_ERROR_INVALID;
1070         }
1071
1072         user_data = provider_buffer_user_data(handle);
1073         if (!user_data) {
1074                 return LB_STATUS_ERROR_INVALID;
1075         }
1076
1077         if (user_data->accelerated) {
1078                 return LB_STATUS_ERROR_ALREADY;
1079         }
1080
1081         ret = provider_buffer_pixmap_create_hw(handle);
1082         user_data->accelerated = (ret == 0);
1083         return ret;
1084 }
1085
1086 PUBLIC int livebox_destroy_hw_buffer(struct livebox_buffer *handle)
1087 {
1088         struct livebox_buffer_data *user_data;
1089
1090         if (!handle) {
1091                 LOGD("handle is NULL\n");
1092                 return LB_STATUS_ERROR_INVALID;
1093         }
1094
1095         user_data = provider_buffer_user_data(handle);
1096         if (!user_data || !user_data->accelerated) {
1097                 LOGD("user_data is NULL\n");
1098                 return LB_STATUS_ERROR_INVALID;
1099         }
1100
1101         user_data->accelerated = 0;
1102
1103         return provider_buffer_pixmap_destroy_hw(handle);
1104 }
1105
1106 PUBLIC void *livebox_buffer_hw_buffer(struct livebox_buffer *handle)
1107 {
1108         struct livebox_buffer_data *user_data;
1109
1110         if (!handle) {
1111                 return NULL;
1112         }
1113
1114         user_data = provider_buffer_user_data(handle);
1115         if (!user_data || !user_data->accelerated) {
1116                 return NULL;
1117         }
1118
1119         return provider_buffer_pixmap_hw_addr(handle);
1120 }
1121
1122 PUBLIC int livebox_buffer_pre_render(struct livebox_buffer *handle)
1123 {
1124         struct livebox_buffer_data *user_data;
1125
1126         if (!handle) {
1127                 return LB_STATUS_ERROR_INVALID;
1128         }
1129
1130         user_data = provider_buffer_user_data(handle);
1131         if (!user_data) {
1132                 return LB_STATUS_ERROR_INVALID;
1133         }
1134
1135         if (!user_data->accelerated) {
1136                 return LB_STATUS_SUCCESS;
1137         }
1138
1139         /*!
1140          * \note
1141          * Do preprocessing for accessing the H/W render buffer
1142          */
1143         return provider_buffer_pre_render(handle);
1144 }
1145
1146 PUBLIC int livebox_buffer_post_render(struct livebox_buffer *handle)
1147 {
1148         int ret;
1149         const char *pkgname;
1150         const char *id;
1151         struct livebox_buffer_data *user_data;
1152
1153         if (!handle) {
1154                 return LB_STATUS_ERROR_INVALID;
1155         }
1156
1157         user_data = provider_buffer_user_data(handle);
1158         if (!user_data) {
1159                 return LB_STATUS_ERROR_INVALID;
1160         }
1161
1162         if (!user_data->accelerated) {
1163                 return LB_STATUS_SUCCESS;
1164         }
1165
1166         pkgname = provider_buffer_pkgname(handle);
1167         if (!pkgname) {
1168                 ErrPrint("Invalid buffer handle\n");
1169                 return LB_STATUS_ERROR_INVALID;
1170         }
1171
1172         id = provider_buffer_id(handle);
1173         if (!id) {
1174                 ErrPrint("Invalid buffer handler\n");
1175                 return LB_STATUS_ERROR_INVALID;
1176         }
1177
1178         ret = provider_buffer_post_render(handle);
1179         if (ret < 0) {
1180                 ErrPrint("Failed to post render processing\n");
1181                 return ret;
1182         }
1183
1184         if (user_data->is_pd == 1) {
1185                 if (provider_send_desc_updated(pkgname, id, NULL) < 0) {
1186                         ErrPrint("Failed to send PD updated (%s)\n", id);
1187                 }
1188         } else {
1189                 int w;
1190                 int h;
1191                 int pixel_size;
1192
1193                 if (provider_buffer_get_size(handle, &w, &h, &pixel_size) < 0) {
1194                         ErrPrint("Failed to get size (%s)\n", id);
1195                 }
1196
1197                 if (provider_send_updated_NEW(pkgname, id, w, h, -1.0f, user_data->content, user_data->title, user_data->icon, user_data->name) < 0) {
1198                         ErrPrint("Failed to send updated (%s)\n", id);
1199                 }
1200         }
1201
1202         return LB_STATUS_SUCCESS;
1203 }
1204
1205 PUBLIC int livebox_content_is_updated(const char *filename, int is_pd)
1206 {
1207         if (!s_info.trigger_update_monitor) {
1208                 s_info.trigger_update_monitor = dlsym(RTLD_DEFAULT, "livebox_trigger_update_monitor");
1209                 if (!s_info.trigger_update_monitor) {
1210                         ErrPrint("Trigger update monitor function is not exists\n");
1211                         return LB_STATUS_ERROR_FAULT;
1212                 }
1213         }
1214
1215         return s_info.trigger_update_monitor(filename, is_pd);
1216 }
1217
1218 PUBLIC int livebox_request_close_pd(const char *pkgname, const char *id, int reason)
1219 {
1220         char *uri;
1221         int schema_len = strlen(FILE_SCHEMA);
1222         int ret;
1223
1224         if (!pkgname || !id) {
1225                 ErrPrint("Invalid parameters (%s) (%s)\n", pkgname, id);
1226                 return LB_STATUS_ERROR_INVALID;
1227         }
1228
1229         if (strncmp(id, FILE_SCHEMA, schema_len)) {
1230                 uri = id_to_uri(id);
1231                 if (!uri) {
1232                         ErrPrint("Heap: %s\n", strerror(errno));
1233                         return LB_STATUS_ERROR_MEMORY;
1234                 }
1235         } else {
1236                 uri = strdup(id);
1237                 if (!uri) {
1238                         ErrPrint("Heap: %s\n", strerror(errno));
1239                         return LB_STATUS_ERROR_MEMORY;
1240                 }
1241         }
1242
1243         ret = provider_send_request_close_pd(pkgname, uri, reason);
1244         free(uri);
1245         return ret;
1246 }
1247
1248 PUBLIC int livebox_freeze_scroller(const char *pkgname, const char *id)
1249 {
1250         char *uri;
1251         int ret;
1252
1253         uri = id_to_uri(id);
1254         if (!uri) {
1255                 ErrPrint("Heap: %s\n", strerror(errno));
1256                 return LB_STATUS_ERROR_MEMORY;
1257         }
1258
1259         ret = provider_send_hold_scroll(pkgname, uri, 1);
1260         free(uri);
1261         return ret;
1262 }
1263
1264 PUBLIC int livebox_release_scroller(const char *pkgname, const char *id)
1265 {
1266         char *uri;
1267         int ret;
1268
1269         uri = id_to_uri(id);
1270         if (!uri) {
1271                 ErrPrint("Heap: %s\n", strerror(errno));
1272                 return LB_STATUS_ERROR_MEMORY;
1273         }
1274
1275         ret = provider_send_hold_scroll(pkgname, uri, 0);
1276         free(uri);
1277         return ret;
1278 }
1279
1280 PUBLIC int livebox_set_extra_info(const char *id, const char *content, const char *title, const char *icon, const char *name)
1281 {
1282         struct livebox_buffer *handle;
1283         const char *pkgname;
1284         char *uri;
1285
1286         uri = id_to_uri(id);
1287         if (!uri) {
1288                 ErrPrint("Heap: %s\n", strerror(errno));
1289                 return LB_STATUS_ERROR_MEMORY;
1290         }
1291
1292         pkgname = s_info.find_pkgname(uri);
1293         if (!pkgname) {
1294                 ErrPrint("Failed to find a package (%s)\n", uri);
1295                 free(uri);
1296                 return LB_STATUS_ERROR_INVALID;
1297         }
1298
1299         handle = provider_buffer_find_buffer(TYPE_LB, pkgname, uri);
1300         free(uri);
1301         if (handle) {
1302                 struct livebox_buffer_data *user_data;
1303
1304                 user_data = provider_buffer_user_data(handle);
1305                 if (!user_data) {
1306                         ErrPrint("User data is not available\n");
1307                         return LB_STATUS_ERROR_FAULT;
1308                 }
1309
1310                 if (content && strlen(content)) {
1311                         char *_content;
1312
1313                         _content = strdup(content);
1314                         if (_content) {
1315                                 if (user_data->content) {
1316                                         free(user_data->content);
1317                                         user_data->content = NULL;
1318                                 }
1319
1320                                 user_data->content = _content;
1321                         } else {
1322                                 ErrPrint("Heap: %s\n", strerror(errno));
1323                         }
1324                 }
1325
1326                 if (title && strlen(title)) {
1327                         char *_title;
1328
1329                         _title = strdup(title);
1330                         if (_title) {
1331                                 if (user_data->title) {
1332                                         free(user_data->title);
1333                                         user_data->title = NULL;
1334                                 }
1335
1336                                 user_data->title = _title;
1337                         } else {
1338                                 ErrPrint("Heap: %s\n", strerror(errno));
1339                         }
1340                 }
1341
1342                 if (icon && strlen(icon)) {
1343                         char *_icon;
1344
1345                         _icon = strdup(icon);
1346                         if (_icon) {
1347                                 if (user_data->icon) {
1348                                         free(user_data->icon);
1349                                         user_data->icon = NULL;
1350                                 }
1351
1352                                 user_data->icon = _icon;
1353                         } else {
1354                                 ErrPrint("Heap: %s\n", strerror(errno));
1355                         }
1356                 }
1357
1358                 if (name && strlen(name)) {
1359                         char *_name;
1360
1361                         _name = strdup(name);
1362                         if (_name) {
1363                                 if (user_data->name) {
1364                                         free(user_data->name);
1365                                         user_data->name = NULL;
1366                                 }
1367
1368                                 user_data->name = _name;
1369                         } else {
1370                                 ErrPrint("Heap: %s\n", strerror(errno));
1371                         }
1372                 }
1373
1374                 return LB_STATUS_SUCCESS;
1375         }
1376
1377         if (!s_info.update_extra_info) {
1378                 s_info.update_extra_info = dlsym(RTLD_DEFAULT, "livebox_update_extra_info");
1379                 if (!s_info.update_extra_info) {
1380                         ErrPrint("Failed to find a \"livebox_update_extra_info\"\n");
1381                         return LB_STATUS_ERROR_INVALID;
1382                 }
1383         }
1384
1385         return s_info.update_extra_info(id, content, title, icon, name);
1386 }
1387
1388 /* End of a file */