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