Initialize the project.
[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 /*!
36  * \brief This function is defined by the data-provider-slave
37  */
38 extern const char *livebox_find_pkgname(const char *filename);
39
40 struct block {
41         unsigned int idx;
42
43         char *type;
44         char *part;
45         char *data;
46         char *group;
47         char *id;
48         char *file;
49         char *target_id;
50 };
51
52 struct livebox_desc {
53         FILE *fp;
54         int for_pd;
55
56         unsigned int last_idx;
57
58         struct dlist *block_list;
59 };
60
61 EAPI const int DONE = 0x00;
62 EAPI const int NEED_TO_SCHEDULE = 0x01;
63 EAPI const int OUTPUT_UPDATED = 0x02;
64 EAPI const int NEED_TO_CREATE = 0x01;
65 EAPI const int NEED_TO_DESTROY = 0x01;
66 EAPI const int LB_SYS_EVENT_FONT_CHANGED = 0x01;
67 EAPI const int LB_SYS_EVENT_LANG_CHANGED = 0x02;
68 EAPI const int LB_SYS_EVENT_PAUSED = 0x04;
69 EAPI const int LB_SYS_EVENT_RESUMED = 0x08;
70
71 EAPI struct livebox_desc *livebox_desc_open(const char *filename, int for_pd)
72 {
73         struct livebox_desc *handle;
74         char *new_fname;
75
76         handle = calloc(1, sizeof(*handle));
77         if (!handle) {
78                 ErrPrint("Error: %s\n", strerror(errno));
79                 return NULL;
80         }
81
82         if (for_pd) {
83                 int len;
84                 len = strlen(filename) + strlen(".desc") + 1;
85                 new_fname = malloc(len);
86                 if (!new_fname) {
87                         ErrPrint("Error: %s\n", strerror(errno));
88                         free(handle);
89                         return NULL;
90                 }
91                 snprintf(new_fname, len, "%s.desc", filename);
92         } else {
93                 new_fname = strdup(filename);
94                 if (!new_fname) {
95                         ErrPrint("Error: %s\n", strerror(errno));
96                         free(handle);
97                         return NULL;
98                 }
99         }
100
101         DbgPrint("Open a new file: %s\n", new_fname);
102         handle->fp = fopen(new_fname, "w+t");
103         free(new_fname);
104         if (!handle->fp) {
105                 ErrPrint("Failed to open a file: %s\n", strerror(errno));
106                 free(handle);
107                 return NULL;
108         }
109
110         return handle;
111 }
112
113 EAPI int livebox_desc_close(struct livebox_desc *handle)
114 {
115         struct dlist *l;
116         struct dlist *n;
117         struct block *block;
118
119         if (!handle)
120                 return -EINVAL;
121
122         DbgPrint("Close and flush\n");
123         dlist_foreach_safe(handle->block_list, l, n, block) {
124                 handle->block_list = dlist_remove(handle->block_list, l);
125
126                 DbgPrint("{\n");
127                 fprintf(handle->fp, "{\n");
128                 if (block->type) {
129                         fprintf(handle->fp, "type=%s\n", block->type);
130                         DbgPrint("type=%s\n", block->type);
131                 }
132
133                 if (block->part) {
134                         fprintf(handle->fp, "part=%s\n", block->part);
135                         DbgPrint("part=%s\n", block->part);
136                 }
137
138                 if (block->data) {
139                         fprintf(handle->fp, "data=%s\n", block->data);
140                         DbgPrint("data=%s\n", block->data);
141                 }
142
143                 if (block->group) {
144                         fprintf(handle->fp, "group=%s\n", block->group);
145                         DbgPrint("group=%s\n", block->group);
146                 }
147
148                 if (block->id) {
149                         fprintf(handle->fp, "id=%s\n", block->id);
150                         DbgPrint("id=%s\n", block->id);
151                 }
152
153                 if (block->target_id) {
154                         fprintf(handle->fp, "target=%s\n", block->target_id);
155                         DbgPrint("target=%s\n", block->target_id);
156                 }
157
158                 fprintf(handle->fp, "}\n");
159                 DbgPrint("}\n");
160
161                 free(block->type);
162                 free(block->part);
163                 free(block->data);
164                 free(block->group);
165                 free(block->id);
166                 free(block->target_id);
167                 free(block);
168         }
169
170         fclose(handle->fp);
171         free(handle);
172         return 0;
173 }
174
175 EAPI int livebox_desc_set_category(struct livebox_desc *handle, const char *id, const char *category)
176 {
177         struct block *block;
178
179         if (!handle || !category)
180                 return -EINVAL;
181
182         block = calloc(1, sizeof(*block));
183         if (!block)
184                 return -ENOMEM;
185
186         block->type = strdup(LB_DESC_TYPE_INFO);
187         if (!block->type) {
188                 free(block);
189                 return -ENOMEM;
190         }
191
192         block->part = strdup("category");
193         if (!block->part) {
194                 free(block->type);
195                 free(block);
196                 return -ENOMEM;
197         }
198
199         block->data = strdup(category);
200         if (!block->data) {
201                 free(block->type);
202                 free(block->part);
203                 free(block);
204                 return -ENOMEM;
205         }
206
207         if (id) {
208                 block->id = strdup(id);
209                 if (!block->id) {
210                         free(block->data);
211                         free(block->type);
212                         free(block->part);
213                         free(block);
214                         return -ENOMEM;
215                 }
216         }
217
218         block->idx = handle->last_idx++;
219         handle->block_list = dlist_append(handle->block_list, block);
220         return block->idx;
221 }
222
223 EAPI int livebox_desc_set_size(struct livebox_desc *handle, const char *id, int w, int h)
224 {
225         struct block *block;
226         char buffer[BUFSIZ];
227
228         if (!handle)
229                 return -EINVAL;
230
231         block = calloc(1, sizeof(*block));
232         if (!block)
233                 return -ENOMEM;
234
235         block->type = strdup(LB_DESC_TYPE_INFO);
236         if (!block->type) {
237                 free(block);
238                 return -ENOMEM;
239         }
240
241         block->part = strdup("size");
242         if (!block->part) {
243                 free(block->type);
244                 free(block);
245                 return -ENOMEM;
246         }
247
248         if (id) {
249                 block->id = strdup(id);
250                 if (!block->id) {
251                         free(block->part);
252                         free(block->type);
253                         free(block);
254                         return -ENOMEM;
255                 }
256         }
257
258         snprintf(buffer, sizeof(buffer), "%dx%d", w, h);
259         block->data = strdup(buffer);
260         if (!block->data) {
261                 free(block->part);
262                 free(block->type);
263                 free(block);
264                 return -ENOMEM;
265         }
266
267         block->idx = handle->last_idx++;
268         handle->block_list = dlist_append(handle->block_list, block);
269         return block->idx;
270 }
271
272 EAPI char *livebox_util_nl2br(const char *str)
273 {
274         int len;
275         register int i;
276         char *ret;
277         char *ptr;
278
279         if (!str)
280                 return NULL;
281
282         len = strlen(str);
283         if (!len)
284                 return NULL;
285
286         ret = malloc(len);
287         if (!ret)
288                 return NULL;
289
290         ptr = ret;
291         i = 0;
292         while (*str) {
293                 switch (*str) {
294                 case '\n':
295                         if (len - i < 5) {
296                                 char *tmp;
297                                 len += len;
298
299                                 tmp = realloc(ret, len);
300                                 if (!tmp) {
301                                         free(ret);
302                                         return NULL;
303                                 }
304
305                                 ret = tmp;
306                                 ptr = tmp + i;
307                         }
308
309                         strcpy(ptr, "<br>");
310                         ptr += 4;
311                         i += 4;
312                         break;
313                 default:
314                         *ptr++ = *str;
315                         i++;
316                         break;
317                 }
318
319                 str++;
320         }
321         *ptr = '\0';
322
323         return ret;
324 }
325
326 EAPI int livebox_desc_set_id(struct livebox_desc *handle, int idx, const char *id)
327 {
328         struct dlist *l;
329         struct block *block;
330
331         dlist_foreach(handle->block_list, l, block) {
332                 if (block->idx == idx) {
333                         if (strcasecmp(block->type, LB_DESC_TYPE_SCRIPT)) {
334                                 ErrPrint("Invalid block is used\n");
335                                 return -EINVAL;
336                         }
337
338                         free(block->target_id);
339                         block->target_id = NULL;
340
341                         if (!id || !strlen(id))
342                                 return 0;
343
344                         block->target_id = strdup(id);
345                         if (!block->target_id) {
346                                 ErrPrint("Heap: %s\n", strerror(errno));
347                                 return -ENOMEM;
348                         }
349
350                         return 0;
351                 }
352         }
353
354         return -ENOENT;
355 }
356
357 /*!
358  * \return idx
359  */
360 EAPI int livebox_desc_add_block(struct livebox_desc *handle, const char *id, const char *type, const char *part, const char *data, const char *group)
361 {
362         struct block *block;
363
364         if (!handle || !type)
365                 return -EINVAL;
366
367         if (!part)
368                 part = "";
369
370         if (!data)
371                 data = "";
372
373         block = calloc(1, sizeof(*block));
374         if (!block)
375                 return -ENOMEM;
376
377         block->type = strdup(type);
378         if (!block->type) {
379                 free(block);
380                 return -ENOMEM;
381         }
382
383         block->part = strdup(part);
384         if (!block->part) {
385                 free(block->type);
386                 free(block);
387                 return -ENOMEM;
388         }
389
390         block->data = strdup(data);
391         if (!block->data) {
392                 free(block->type);
393                 free(block->part);
394                 free(block);
395                 return -ENOMEM;
396         }
397
398         if (group) {
399                 block->group = strdup(group);
400                 if (!block->group) {
401                         free(block->data);
402                         free(block->type);
403                         free(block->part);
404                         free(block);
405                         return -ENOMEM;
406                 }
407         }
408
409         if (id) {
410                 block->id = strdup(id);
411                 if (!block->id) {
412                         free(block->group);
413                         free(block->data);
414                         free(block->type);
415                         free(block->part);
416                         free(block);
417                         return -ENOMEM;
418                 }
419         }
420
421         block->idx = handle->last_idx++;
422         handle->block_list = dlist_append(handle->block_list, block);
423         return block->idx;
424 }
425
426 EAPI int livebox_desc_del_block(struct livebox_desc *handle, int idx)
427 {
428         struct dlist *l;
429         struct block *block;
430
431         dlist_foreach(handle->block_list, l, block) {
432                 if (block->idx == idx) {
433                         handle->block_list = dlist_remove(handle->block_list, l);
434                         free(block->type);
435                         free(block->part);
436                         free(block->data);
437                         free(block->group);
438                         free(block->id);
439                         free(block->target_id);
440                         free(block);
441                         return 0;
442                 }
443         }
444
445         return -ENOENT;
446 }
447
448 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)
449 {
450         const char *pkgname;
451         struct livebox_buffer *handle;
452         char *uri;
453         int uri_len;
454
455         if (!filename || !width || !height) {
456                 ErrPrint("Invalid argument: %p(%dx%d)\n", filename, width, height);
457                 return NULL;
458         }
459
460         uri_len = strlen(filename) + strlen("file://") + 1;
461         uri = malloc(uri_len);
462         if (!uri) {
463                 ErrPrint("Heap: %s\n", strerror(errno));
464                 return NULL;
465         }
466
467         snprintf(uri, uri_len, "file://%s", filename);
468         DbgPrint("Before call the livebox_find_pkgname\n");
469         pkgname = livebox_find_pkgname(uri);
470         DbgPrint("After call the livebox_find_pkgname\n");
471         if (!pkgname) {
472                 ErrPrint("Invalid Request\n");
473                 free(uri);
474                 return NULL;
475         }
476
477         DbgPrint("URI: %s\n", uri);
478         handle = provider_buffer_acquire((!!is_pd) ? TYPE_PD : TYPE_LB, pkgname, uri, width, height, sizeof(int), handler, data);
479         DbgPrint("Acquire buffer for PD(%s), %s, %p\n", pkgname, uri, handle);
480         free(uri);
481         return handle;
482 }
483
484 EAPI unsigned long livebox_pixmap_id(struct livebox_buffer *handle)
485 {
486         return provider_buffer_pixmap_id(handle);
487 }
488
489 EAPI int livebox_release_buffer(struct livebox_buffer *handle)
490 {
491         if (!handle)
492                 return -EINVAL;
493
494         DbgPrint("Release buffer\n");
495         return provider_buffer_release(handle);
496 }
497
498 EAPI void *livebox_ref_buffer(struct livebox_buffer *handle)
499 {
500         if (!handle)
501                 return -EINVAL;
502
503         DbgPrint("Ref buffer\n");
504         return provider_buffer_ref(handle);
505 }
506
507 EAPI int livebox_unref_buffer(void *buffer)
508 {
509         if (!buffer)
510                 return -EINVAL;
511
512         DbgPrint("Unref buffer\n");
513         return provider_buffer_unref(buffer);
514 }
515
516 EAPI int livebox_sync_buffer(struct livebox_buffer *handle)
517 {
518         const char *pkgname;
519         const char *id;
520
521         if (!handle)
522                 return -EINVAL;
523
524         pkgname = provider_buffer_pkgname(handle);
525         id = provider_buffer_id(handle);
526         if (!pkgname || !id) {
527                 ErrPrint("Invalid buffer handler\n");
528                 return -EINVAL;
529         }
530
531         DbgPrint("Sync buffer\n");
532         provider_buffer_sync(handle);
533         provider_send_desc_updated(pkgname, id, NULL);
534         return 0;
535 }
536
537 /* End of a file */