Update SMACK, Fix a crash of terminating sequence, etc, ...
[apps/livebox/data-provider-master.git] / src / fb.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 <unistd.h> /* access */
19 #include <errno.h>
20
21 #include <dlog.h>
22 #include <Ecore_Evas.h>
23 #include <Evas.h>
24 #include <livebox-errno.h>
25
26 #include "util.h"
27 #include "conf.h"
28 #include "debug.h"
29 #include "buffer_handler.h"
30 #include "fb.h"
31
32 int errno;
33
34 struct fb_info {
35         Ecore_Evas *ee;
36
37         struct buffer_info *buffer;
38 };
39
40 HAPI int fb_init(void)
41 {
42         return LB_STATUS_SUCCESS;
43 }
44
45 HAPI int fb_fini(void)
46 {
47         return LB_STATUS_SUCCESS;
48 }
49
50 static void *alloc_fb(void *data, int size)
51 {
52         struct fb_info *info = data;
53
54         DbgPrint("FB size: %d\n", size);
55
56         if (buffer_handler_load(info->buffer) < 0) {
57                 ErrPrint("Failed to load buffer handler\n");
58                 return NULL;
59         }
60
61         return buffer_handler_fb(info->buffer);
62 }
63
64 static void free_fb(void *data, void *ptr)
65 {
66         struct fb_info *info = data;
67
68         if (!info->buffer) {
69                 ErrPrint("Buffer is not valid (maybe already released)\n");
70                 return;
71         }
72
73         if (buffer_handler_fb(info->buffer) != ptr)
74                 ErrPrint("Buffer pointer is not matched\n");
75
76         (void)buffer_handler_unload(info->buffer);
77 }
78
79 HAPI struct fb_info *fb_create(struct inst_info *inst, int w, int h, enum buffer_type type)
80 {
81         struct fb_info *info;
82
83         info = calloc(1, sizeof(*info));
84         if (!info) {
85                 ErrPrint("Heap: %s\n", strerror(errno));
86                 return NULL;
87         }
88
89         info->buffer = buffer_handler_create(inst, type, w, h, sizeof(int));
90         if (!info->buffer) {
91                 ErrPrint("Failed to create a buffer\n");
92                 DbgFree(info);
93                 return NULL;
94         }
95
96         info->ee = NULL;
97         return info;
98 }
99
100 static void sw_render_pre_cb(void *data, Evas *e, void *event_info)
101 {
102         struct fb_info *info = data;
103         int w;
104         int h;
105
106         buffer_handler_get_size(info->buffer, &w, &h);
107         evas_damage_rectangle_add(e, 0, 0, w, h);
108 }
109
110 static void sw_render_post_cb(void *data, Evas *e, void *event_info)
111 {
112         void *canvas;
113         Ecore_Evas *internal_ee;
114         int x, y, w, h;
115
116         internal_ee = ecore_evas_ecore_evas_get(e);
117         if (!internal_ee) {
118                 ErrPrint("Failed to get ecore evas\n");
119                 return;
120         }
121
122         // Get a pointer of a buffer of the virtual canvas
123         canvas = (void*)ecore_evas_buffer_pixels_get(internal_ee);
124         if (!canvas) {
125                 ErrPrint("Failed to get pixel canvas\n");
126                 return;
127         }
128
129         ecore_evas_geometry_get(internal_ee, &x, &y, &w, &h);
130         evas_data_argb_unpremul(canvas, w * h);
131 }
132
133 static void render_pre_cb(void *data, Evas *e, void *event_info)
134 {
135         fb_pixmap_render_pre(data);
136         sw_render_pre_cb(data, e, event_info);
137 }
138
139 static void render_post_cb(void *data, Evas *e, void *event_info)
140 {
141         sw_render_post_cb(data, e, event_info);
142         fb_pixmap_render_post(data);
143 }
144
145 HAPI int fb_create_buffer(struct fb_info *info)
146 {
147         int ow;
148         int oh;
149         Evas *e;
150
151         buffer_handler_get_size(info->buffer, &ow, &oh);
152         DbgPrint("Buffer handler size: %dx%d\n", ow, oh);
153         if (ow == 0 && oh == 0) {
154                 DbgPrint("ZERO Size FB accessed\n");
155                 return LB_STATUS_SUCCESS;
156         }
157
158         if (info->ee) {
159                 int w = 0;
160                 int h = 0;
161
162                 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
163                 if (w != ow || h != oh) {
164                         ErrPrint("EE exists, size mismatched requested (%dx%d) but (%dx%d)\n", ow, oh, w, h);
165                         ecore_evas_resize(info->ee, ow, oh);
166                 }
167
168                 return LB_STATUS_SUCCESS;
169         }
170
171         info->ee = ecore_evas_buffer_allocfunc_new(ow, oh, alloc_fb, free_fb, info);
172         if (!info->ee) {
173                 ErrPrint("Failed to create a buffer\n");
174                 return LB_STATUS_ERROR_FAULT;
175         }
176
177         e = ecore_evas_get(info->ee);
178         if (buffer_handler_type(info->buffer) == BUFFER_TYPE_PIXMAP) {
179                 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb, info);
180                 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, render_post_cb, info);
181
182                 /*!
183                  * \note
184                  * ecore_evas_alpha_set tries to access the canvas buffer.
185                  * Without any render_pre/render_post callback.
186                  */
187                 fb_pixmap_render_pre(info);
188                 ecore_evas_alpha_set(info->ee, EINA_TRUE);
189                 fb_pixmap_render_post(info);
190         } else {
191                 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_PRE, sw_render_pre_cb, info);
192                 evas_event_callback_add(e, EVAS_CALLBACK_RENDER_POST, sw_render_post_cb, info);
193                 ecore_evas_alpha_set(info->ee, EINA_TRUE);
194         }
195
196         return LB_STATUS_SUCCESS;
197 }
198
199 HAPI int fb_destroy_buffer(struct fb_info *info)
200 {
201         if (!info->ee) {
202                 ErrPrint("EE is not exists (Maybe ZERO byte ee?)\n");
203                 return LB_STATUS_ERROR_INVALID;
204         }
205
206         if (buffer_handler_type(info->buffer) == BUFFER_TYPE_PIXMAP) {
207                 Evas *e;
208                 e = ecore_evas_get(info->ee);
209                 if (e) {
210                         evas_event_callback_del(e, EVAS_CALLBACK_RENDER_POST, render_post_cb);
211                         evas_event_callback_del(e, EVAS_CALLBACK_RENDER_PRE, render_pre_cb);
212                 }
213         }
214
215         ecore_evas_free(info->ee);
216         info->ee = NULL;
217         return LB_STATUS_SUCCESS;
218 }
219
220 HAPI int fb_destroy(struct fb_info *info)
221 {
222         fb_destroy_buffer(info);
223         DbgFree(info);
224         return LB_STATUS_SUCCESS;
225 }
226
227 HAPI Ecore_Evas * const fb_canvas(struct fb_info *info)
228 {
229         return info->ee;
230 }
231
232 HAPI const char *fb_id(struct fb_info *fb)
233 {
234         return fb ? buffer_handler_id(fb->buffer) : "";
235 }
236
237 HAPI int fb_resize(struct fb_info *info, int w, int h)
238 {
239         buffer_handler_update_size(info->buffer, w, h);
240
241         if (info->ee) {
242                 ecore_evas_resize(info->ee, w, h);
243         } else if (!info->ee && !info->buffer) {
244                 /*!
245                  * This object has no size at the initial time.
246                  * Create a new buffer and use it
247                  */
248         }
249
250         return LB_STATUS_SUCCESS;
251 }
252
253 HAPI int fb_get_size(struct fb_info *info, int *w, int *h)
254 {
255         return buffer_handler_get_size(info->buffer, w, h);
256 }
257
258 HAPI void fb_sync(struct fb_info *info)
259 {
260         buffer_handler_flush(info->buffer);
261 }
262
263 HAPI void *fb_pixmap_render_pre(struct fb_info *info)
264 {
265         void *canvas;
266         canvas = buffer_handler_pixmap_acquire_buffer(info->buffer);
267         return canvas;
268 }
269
270 HAPI int fb_pixmap_render_post(struct fb_info *info)
271 {
272         void *canvas;
273
274         /*!
275          * \note
276          * info->buffer == struct buffer_info
277          */
278         canvas = buffer_handler_pixmap_buffer(info->buffer);
279         return buffer_handler_pixmap_release_buffer(canvas);
280 }
281
282 /* End of a file */