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