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