Sync with the latest private repository
[apps/native/widget/widget.git] / src / virtual_window.c.orig
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 #define _GNU_SOURCE
18
19 #include <Elementary.h>
20 #include <string.h>
21 #include <Ecore_Evas.h>
22 #include <Ecore_X.h>
23 #include <Evas.h>
24 #include <dlfcn.h>
25
26 #include <X11/Xlib.h>
27
28 #include <dlog.h>
29 #include <livebox-errno.h>
30 #include <livebox-service.h>
31
32 #include "livebox.h"
33 #include "livebox_product.h"
34 #include "debug.h"
35
36 #define IS_PD 1
37
38 #define PUBLIC __attribute__((visibility("default")))
39
40 static struct static_info {
41         Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
42         Ecore_Evas *(*alloc_canvas_with_stride)(int w, int h, void *(*a)(void *data, int size, int *stride, int *bpp), void (*f)(void *data, void *ptr), void *data);
43 } s_info = {
44         .alloc_canvas = NULL,
45         .alloc_canvas_with_stride = NULL,
46 };
47
48 /*!
49  * \brief
50  * Abstracted Data Type of Virtual Window
51  */
52 struct info {
53         char *id; /*!< Identification */
54         struct livebox_buffer *handle; /*!< Livebox buffer handle */
55         int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
56         Ecore_Evas *ee;
57         Evas *e;
58         int is_pd;
59         int deleted;
60         int w;
61         int h;
62 };
63
64 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
65 {
66         Evas_Object *o, *ho;
67
68         o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
69         if (!o) return NULL;
70
71         ho = evas_object_data_get(o, "_elm_access_target");
72         return ho;
73 }
74
75 /*!
76  * \note
77  * Every user event (mouse) on the buffer will be passed via this event callback
78  */
79 static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_data *event_info, void *data)
80 {
81         struct info *info = data;
82         Elm_Access_Action_Info action_info;
83         Elm_Access_Action_Type action_type;
84         int ret = 0;
85         Evas_Object *parent_elm;
86         KeySym *key_symbol;
87         unsigned int flags = 0;
88
89         if (!info->handle) {
90                 /* Just ignore this event */
91                 return 0;
92         }
93
94         /*!
95          * \note
96          * Feed up events
97          */
98         switch (event_info->type) {
99         case BUFFER_EVENT_ON_HOLD:
100                 DbgPrint("ON_HOLD\n");
101                 flags = evas_event_default_flags_get(info->e);
102                 flags |= EVAS_EVENT_FLAG_ON_HOLD;
103                 evas_event_default_flags_set(info->e, flags);
104                 break;
105         case BUFFER_EVENT_OFF_HOLD:
106                 flags = evas_event_default_flags_get(info->e);
107                 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
108                 evas_event_default_flags_set(info->e, flags);
109                 break;
110         case BUFFER_EVENT_ON_SCROLL:
111                 flags = evas_event_default_flags_get(info->e);
112                 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
113                 evas_event_default_flags_set(info->e, flags);
114                 break;
115         case BUFFER_EVENT_OFF_SCROLL:
116                 flags = evas_event_default_flags_get(info->e);
117                 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
118                 evas_event_default_flags_set(info->e, flags);
119                 break;
120         case BUFFER_EVENT_ENTER:
121                 evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
122                 break;
123         case BUFFER_EVENT_LEAVE:
124                 evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
125                 break;
126         case BUFFER_EVENT_DOWN:
127                 /*!
128                  * \note
129                  * Calculate the event occurred X & Y on the buffer
130                  */
131                 flags = evas_event_default_flags_get(info->e);
132                 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
133                 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
134                 evas_event_default_flags_set(info->e, flags);
135
136                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
137                 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
138                 break;
139         case BUFFER_EVENT_MOVE:
140                 /*!
141                  * \note
142                  * Calculate the event occurred X & Y on the buffer
143                  */
144                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
145                 break;
146         case BUFFER_EVENT_UP:
147                 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
148                 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL);
149                 break;
150         case BUFFER_EVENT_HIGHLIGHT:
151                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
152                 if (!parent_elm) {
153                         ret = LB_ACCESS_STATUS_ERROR;
154                         break;
155                 }
156                 memset(&action_info, 0, sizeof(action_info));
157                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
158                 /*!
159                  * \note
160                  * Calculate the event occurred X & Y on the buffer
161                  */
162                 action_info.x = event_info->info.access.x;
163                 action_info.y = event_info->info.access.y;
164                 ret = elm_access_action(parent_elm, action_type, &action_info);
165                 if (ret == EINA_TRUE) {
166                         if (!get_highlighted_object(parent_elm)) {
167                                 LOGE("Highlighted object is not found\n");
168                                 ret = LB_ACCESS_STATUS_ERROR;
169                         } else {
170                                 LOGD("Highlighted object is found\n");
171                                 ret = LB_ACCESS_STATUS_DONE;
172                         }
173                 } else {
174                         LOGE("Action error\n");
175                         ret = LB_ACCESS_STATUS_ERROR;
176                 }
177                 break;
178         case BUFFER_EVENT_HIGHLIGHT_NEXT:
179                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
180                 if (!parent_elm) {
181                         ret = LB_ACCESS_STATUS_ERROR;
182                         break;
183                 }
184                 memset(&action_info, 0, sizeof(action_info));
185                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
186                 action_info.highlight_cycle = EINA_FALSE;
187                 ret = elm_access_action(parent_elm, action_type, &action_info);
188                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
189                 break;
190         case BUFFER_EVENT_HIGHLIGHT_PREV:
191                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
192                 if (!parent_elm) {
193                         ret = LB_ACCESS_STATUS_ERROR;
194                         break;
195                 }
196                 memset(&action_info, 0, sizeof(action_info));
197                 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
198                 action_info.highlight_cycle = EINA_FALSE;
199                 ret = elm_access_action(parent_elm, action_type, &action_info);
200                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
201                 break;
202         case BUFFER_EVENT_ACTIVATE:
203                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
204                 if (!parent_elm) {
205                         ret = LB_ACCESS_STATUS_ERROR;
206                         break;
207                 }
208                 memset(&action_info, 0, sizeof(action_info));
209                 action_type = ELM_ACCESS_ACTION_ACTIVATE;
210                 ret = elm_access_action(parent_elm, action_type, &action_info);
211                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
212                 break;
213         case BUFFER_EVENT_ACTION_UP:
214                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
215                 if (!parent_elm) {
216                         ret = LB_ACCESS_STATUS_ERROR;
217                         break;
218                 }
219                 memset(&action_info, 0, sizeof(action_info));
220                 action_type = ELM_ACCESS_ACTION_UP;
221                 ret = elm_access_action(parent_elm, action_type, &action_info);
222                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
223                 break;
224         case BUFFER_EVENT_ACTION_DOWN:
225                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
226                 if (!parent_elm) {
227                         ret = LB_ACCESS_STATUS_ERROR;
228                         break;
229                 }
230                 memset(&action_info, 0, sizeof(action_info));
231                 action_type = ELM_ACCESS_ACTION_DOWN;
232                 ret = elm_access_action(parent_elm, action_type, &action_info);
233                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
234                 break;
235         case BUFFER_EVENT_SCROLL_UP:
236                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
237                 if (!parent_elm) {
238                         ret = LB_ACCESS_STATUS_ERROR;
239                         break;
240                 }
241                 memset(&action_info, 0, sizeof(action_info));
242                 action_type = ELM_ACCESS_ACTION_SCROLL;
243                 action_info.x = event_info->info.access.x;
244                 action_info.y = event_info->info.access.y;
245                 action_info.mouse_type = event_info->info.access.mouse_type;
246                 ret = elm_access_action(parent_elm, action_type, &action_info);
247                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
248                 break;
249         case BUFFER_EVENT_SCROLL_MOVE:
250                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
251                 if (!parent_elm) {
252                         ret = LB_ACCESS_STATUS_ERROR;
253                         break;
254                 }
255                 memset(&action_info, 0, sizeof(action_info));
256                 action_type = ELM_ACCESS_ACTION_SCROLL;
257                 action_info.x = event_info->info.access.x;
258                 action_info.y = event_info->info.access.y;
259                 action_info.mouse_type = event_info->info.access.mouse_type;
260                 ret = elm_access_action(parent_elm, action_type, &action_info);
261                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
262                 break;
263         case BUFFER_EVENT_SCROLL_DOWN:
264                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
265                 if (!parent_elm) {
266                         ret = LB_ACCESS_STATUS_ERROR;
267                         break;
268                 }
269                 memset(&action_info, 0, sizeof(action_info));
270                 action_type = ELM_ACCESS_ACTION_SCROLL;
271                 action_info.x = event_info->info.access.x;
272                 action_info.y = event_info->info.access.y;
273                 action_info.mouse_type = event_info->info.access.mouse_type;
274                 ret = elm_access_action(parent_elm, action_type, &action_info);
275                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
276                 break;
277         case BUFFER_EVENT_UNHIGHLIGHT:
278                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
279                 if (!parent_elm) {
280                         ret = LB_ACCESS_STATUS_ERROR;
281                         break;
282                 }
283                 memset(&action_info, 0, sizeof(action_info));
284                 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
285                 ret = elm_access_action(parent_elm, action_type, &action_info);
286                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
287                 break;
288         case BUFFER_EVENT_VALUE_CHANGE:
289                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
290                 if (!parent_elm) {
291                         ret = LB_ACCESS_STATUS_ERROR;
292                         break;
293                 }
294                 memset(&action_info, 0, sizeof(action_info));
295                 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
296                 action_info.x = event_info->info.access.x;
297                 action_info.y = event_info->info.access.y;
298                 action_info.mouse_type = event_info->info.access.mouse_type;
299                 ret = elm_access_action(parent_elm, action_type, &action_info);
300                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
301                 break;
302         case BUFFER_EVENT_MOUSE:
303                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
304                 if (!parent_elm) {
305                         ret = LB_ACCESS_STATUS_ERROR;
306                         break;
307                 }
308                 memset(&action_info, 0, sizeof(action_info));
309                 action_type = ELM_ACCESS_ACTION_MOUSE;
310                 action_info.x = event_info->info.access.x;
311                 action_info.y = event_info->info.access.y;
312                 action_info.mouse_type = event_info->info.access.mouse_type;
313                 ret = elm_access_action(parent_elm, action_type, &action_info);
314                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
315                 break;
316         case BUFFER_EVENT_BACK:
317                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
318                 if (!parent_elm) {
319                         ret = LB_ACCESS_STATUS_ERROR;
320                         break;
321                 }
322                 memset(&action_info, 0, sizeof(action_info));
323                 action_type = ELM_ACCESS_ACTION_BACK;
324                 action_info.x = event_info->info.access.x;
325                 action_info.y = event_info->info.access.y;
326                 action_info.mouse_type = event_info->info.access.mouse_type;
327                 ret = elm_access_action(parent_elm, action_type, &action_info);
328                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
329                 break;
330         case BUFFER_EVENT_OVER:
331                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
332                 if (!parent_elm) {
333                         ret = LB_ACCESS_STATUS_ERROR;
334                         break;
335                 }
336                 memset(&action_info, 0, sizeof(action_info));
337                 action_type = ELM_ACCESS_ACTION_OVER;
338                 action_info.x = event_info->info.access.x;
339                 action_info.y = event_info->info.access.y;
340                 action_info.mouse_type = event_info->info.access.mouse_type;
341                 ret = elm_access_action(parent_elm, action_type, &action_info);
342                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
343                 break;
344         case BUFFER_EVENT_READ:
345                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
346                 if (!parent_elm) {
347                         ret = LB_ACCESS_STATUS_ERROR;
348                         break;
349                 }
350                 memset(&action_info, 0, sizeof(action_info));
351                 action_type = ELM_ACCESS_ACTION_READ;
352                 action_info.x = event_info->info.access.x;
353                 action_info.y = event_info->info.access.y;
354                 action_info.mouse_type = event_info->info.access.mouse_type;
355                 ret = elm_access_action(parent_elm, action_type, &action_info);
356                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
357                 break;
358         case BUFFER_EVENT_ENABLE:
359                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
360                 if (!parent_elm) {
361                         ret = LB_ACCESS_STATUS_ERROR;
362                         break;
363                 }
364                 memset(&action_info, 0, sizeof(action_info));
365                 action_type = ELM_ACCESS_ACTION_ENABLE;
366                 action_info.x = event_info->info.access.x;
367                 action_info.y = event_info->info.access.y;
368                 action_info.mouse_type = event_info->info.access.mouse_type;
369                 ret = elm_access_action(parent_elm, action_type, &action_info);
370                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
371                 break;
372         case BUFFER_EVENT_DISABLE:
373                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
374                 if (!parent_elm) {
375                         ret = LB_ACCESS_STATUS_ERROR;
376                         break;
377                 }
378                 memset(&action_info, 0, sizeof(action_info));
379                 action_type = ELM_ACCESS_ACTION_DISABLE;
380                 action_info.x = event_info->info.access.x;
381                 action_info.y = event_info->info.access.y;
382                 action_info.mouse_type = event_info->info.access.mouse_type;
383                 ret = elm_access_action(parent_elm, action_type, &action_info);
384                 ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
385                 break;
386         case BUFFER_EVENT_KEY_DOWN:
387                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
388                 if (!parent_elm) {
389                         ret = LB_ACCESS_STATUS_ERROR;
390                         break;
391                 }
392
393                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
394                 if (key_symbol) {
395                         char *key_name;
396                         char *key_string;
397
398                         key_string = XKeysymToString(*key_symbol);
399                         key_name = XKeysymToString(*key_symbol);
400                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
401                         XFree(key_symbol);
402                         XFree(key_name);
403                 }
404                 ret = LB_KEY_STATUS_ERROR;
405                 break;
406         case BUFFER_EVENT_KEY_UP:
407                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
408                 if (!parent_elm) {
409                         ret = LB_ACCESS_STATUS_ERROR;
410                         break;
411                 }
412
413                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
414                 if (key_symbol) {
415                         char *key_name;
416                         char *key_string;
417
418                         key_string = XKeysymToString(*key_symbol);
419                         key_name = XKeysymToString(*key_symbol);
420                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
421                         XFree(key_symbol);
422                         XFree(key_name);
423                 }
424                 ret = LB_KEY_STATUS_ERROR;
425                 break;
426         case BUFFER_EVENT_KEY_FOCUS_IN:
427                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
428                 if (!parent_elm) {
429                         ret = LB_ACCESS_STATUS_ERROR;
430                         break;
431                 }
432
433                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
434                 if (key_symbol) {
435                         char *key_name;
436                         char *key_string;
437
438                         key_string = XKeysymToString(*key_symbol);
439                         key_name = XKeysymToString(*key_symbol);
440                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
441                         XFree(key_symbol);
442                         XFree(key_name);
443                 }
444                 ret = LB_KEY_STATUS_ERROR;
445                 break;
446         case BUFFER_EVENT_KEY_FOCUS_OUT:
447                 parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
448                 if (!parent_elm) {
449                         ret = LB_ACCESS_STATUS_ERROR;
450                         break;
451                 }
452
453                 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
454                 if (key_symbol) {
455                         char *key_name;
456                         char *key_string;
457
458                         key_string = XKeysymToString(*key_symbol);
459                         key_name = XKeysymToString(*key_symbol);
460                         DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
461                         XFree(key_symbol);
462                         XFree(key_name);
463                 }
464                 ret = LB_KEY_STATUS_ERROR;
465                 break;
466         default:
467                 LOGD("Unhandled buffer event (%d)\n", event_info->type);
468                 break;
469         }
470
471         return ret;
472 }
473
474 static void *alloc_fb(void *data, int size)
475 {
476         struct info *info = data;
477         void *buffer;
478
479         if (info->ee) {
480                 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
481                 LOGD("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
482         }
483
484         /*!
485          * Acquire a buffer for canvas.
486          */
487         info->handle = livebox_acquire_buffer(info->id, info->is_pd,
488                                         info->w, info->h, sizeof(int), (livebox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
489                                         event_handler_cb, info);
490
491         /*!
492          * If it supports the H/W accelerated buffer,
493          * Use it.
494          */
495         if (livebox_support_hw_buffer(info->handle)) {
496                 if (livebox_create_hw_buffer(info->handle) == 0) {
497                         buffer = livebox_buffer_hw_buffer(info->handle);
498                         if (buffer) {
499                                 LOGD("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
500                                 info->is_hw = 1;
501                                 return buffer;
502                         }
503                 }
504
505                 LOGE("Failed to allocate HW Accelerated buffer\n");
506         }
507
508         /*!
509          * Or use the buffer of a S/W backend.
510          */
511         buffer = livebox_ref_buffer(info->handle);
512         LOGD("SW buffer is created (%dx%d)\n", info->w, info->h);
513         info->is_hw = 0;
514         return buffer;
515 }
516
517 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
518 {
519         void *buffer;
520
521         buffer = alloc_fb(data, size);
522         if (buffer) {
523                 struct info *info = data;
524                 int _stride;
525
526                 *bpp = sizeof(int);
527                 _stride = livebox_buffer_stride(info->handle);
528                 if (_stride < 0) {
529                         _stride = info->w * *bpp;
530                 }
531
532                 *stride = _stride;
533                 *bpp <<= 3;
534                 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
535         }
536
537         return buffer;
538 }
539
540 static void free_fb(void *data, void *ptr)
541 {
542         struct info *info = data;
543
544         if (!info->handle) {
545                 return;
546         }
547
548         if (info->is_hw) {
549                 if (livebox_destroy_hw_buffer(info->handle) == 0) {
550                         LOGD("HW Accelerated buffer is destroyed\n");
551                 }
552         } else {
553                 LOGD("SW buffer is destroyed, %p\n", info);
554                 livebox_unref_buffer(ptr);
555         }
556
557         livebox_release_buffer(info->handle);
558         info->handle = NULL;
559
560         if (info->deleted) {
561                 free(info->id);
562                 info->id = NULL;
563
564                 free(info);
565         }
566 }
567
568 static void pre_render_cb(void *data, Evas *e, void *event_info)
569 {
570         struct info *info = data;
571
572         if (!info->handle) {
573                 return;
574         }
575
576         if (livebox_conf_premultiplied_alpha()) {
577                 Evas_Coord w;
578                 Evas_Coord h;
579
580                 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
581                 evas_damage_rectangle_add(e, 0, 0, w, h);
582         }
583
584         if (info->is_hw) {
585                 livebox_buffer_pre_render(info->handle);
586         }
587 }
588
589 static void post_render_cb(void *data, Evas *e, void *event_info)
590 {
591         struct info *info = data;
592
593         if (!info->handle) {
594                 return;
595         }
596
597         if (livebox_conf_premultiplied_alpha()) {
598                 void *canvas;
599                 int x, y, w, h;
600
601                 // Get a pointer of a buffer of the virtual canvas
602                 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
603                 if (!canvas) {
604                         ErrPrint("Failed to get pixel canvas\n");
605                         return;
606                 }
607
608                 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
609                 evas_data_argb_unpremul(canvas, w * h);
610         }
611
612         if (info->is_hw) {
613                 livebox_buffer_post_render(info->handle);
614         } else {
615                 livebox_sync_buffer(info->handle);
616         }
617 }
618
619 static void ecore_evas_free_cb(Ecore_Evas *ee)
620 {
621         struct info *info;
622
623         info = ecore_evas_data_get(ee, "dynamic,box,info");
624         if (!info) {
625                 LOGD("Info is not valid\n");
626                 return;
627         }
628
629         if (info->e) {
630                 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
631                 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
632         }
633
634         info->deleted = 1;
635         info->ee = NULL;
636 }
637
638 PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
639 {
640         struct info *info;
641         Evas_Object *rect;
642
643         if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride) {
644                 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
645                 if (!s_info.alloc_canvas_with_stride) {
646                         DbgPrint("allocfunc_with_stirde_new is not found\n");
647                 }
648
649                 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
650                 if (!s_info.alloc_canvas) {
651                         ErrPrint("allocfunc_new is not found\n");
652                 }
653
654                 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas) {
655                         ErrPrint("No way to allocate canvas\n");
656                         return NULL;
657                 }
658         }
659
660         if (!id) {
661                 ErrPrint("Invalid parameter\n");
662                 return NULL;
663         }
664
665         info = calloc(1, sizeof(*info));
666         if (!info) {
667                 ErrPrint("Heap: %s\n", strerror(errno));
668                 return NULL;
669         }
670
671         info->id = strdup(id);
672         if (!info->id) {
673                 ErrPrint("Heap: %s\n", strerror(errno));
674                 free(info);
675                 return NULL;
676         }
677
678         info->is_pd = is_pd;
679
680         /*!
681          * Size information must be initialized before call the ecore_evas_buffer_new.
682          */
683         info->w = 1;
684         info->h = 1;
685
686         if (!livebox_conf_auto_align() && s_info.alloc_canvas_with_stride) {
687                 info->ee = s_info.alloc_canvas_with_stride(1, 1, alloc_stride_fb, free_fb, info);
688         } else {
689                 info->ee = s_info.alloc_canvas(1, 1, alloc_fb, free_fb, info);
690         }
691
692         if (!info->ee) {
693                 ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
694                 free(info->id);
695                 free(info);
696                 return NULL;
697         }
698
699         ecore_evas_data_set(info->ee, "dynamic,box,info", info);
700         ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
701
702         info->e = ecore_evas_get(info->ee);
703         if (!info->e) {
704                 ErrPrint("Failed to get evas\n");
705                 ecore_evas_free(info->ee);
706                 return NULL;
707         }
708
709         pre_render_cb(info, NULL, NULL);
710         ecore_evas_alpha_set(info->ee, EINA_TRUE);
711         post_render_cb(info, NULL, NULL);
712
713         ecore_evas_manual_render_set(info->ee, EINA_FALSE);
714         ecore_evas_resize(info->ee, 1, 1);
715
716         evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
717         evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
718
719         rect = evas_object_rectangle_add(info->e);
720         if (!rect) {
721                 ErrPrint("Failed to create evas_object\n");
722                 ecore_evas_free(info->ee);
723                 return NULL;
724         }
725
726         evas_object_resize(rect, 1, 1);
727         evas_object_color_set(rect, 0, 0, 0, 0);
728         return rect;
729 }
730
731 /* End of a file */