2 * Copyright 2013 Samsung Electronics Co., Ltd
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
8 * http://floralicense.org/license/
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.
19 #include <Elementary.h>
21 #include <Ecore_Evas.h>
30 #include <dynamicbox_errno.h>
31 #include <dynamicbox_service.h>
32 #include <dynamicbox_conf.h>
33 #include <dynamicbox_buffer.h>
35 #include "dynamicbox.h"
40 #define PUBLIC __attribute__((visibility("default")))
41 #define DBOX_WIN_TAG "dynamic,box,win"
43 #define DBOX_DEFAULT_WIDTH 1
44 #define DBOX_DEFAULT_HEIGHT 1
45 #define GL_ENGINE "opengl_x11"
47 static struct static_info {
48 Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
49 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);
50 Ecore_Evas *(*alloc_canvas_with_pixmap)(const char *disp_name, Ecore_X_Window parent, int x, int y, int w, int h, Ecore_X_Pixmap (*alloc_cb)(void *data, Ecore_X_Window parent, int w, int h, int depth), void (*free_cb)(void *data, Ecore_X_Pixmap pixmap), void *data);
53 .alloc_canvas_with_stride = NULL,
54 .alloc_canvas_with_pixmap = NULL,
59 * Abstracted Data Type of Virtual Window
61 typedef struct virtual_window_info {
62 char *id; /**< Identification */
63 dynamicbox_buffer_h handle; /**< Livebox buffer handle */
65 VWIN_SW_BUF = 0x00, /**< S/W buffer */
66 VWIN_GEM = 0x01, /**< GEM buffer */
67 VWIN_PIXMAP = 0x02, /**< PIXMAP */
68 VWIN_ERROR = 0x03 /**< Unknown */
76 unsigned int *resource_array;
79 unsigned int front_resource_id;
82 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
86 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
89 ho = evas_object_data_get(o, "_elm_access_target");
95 * Every user event (mouse) on the buffer will be passed via this event callback
97 static int event_handler_cb(dynamicbox_buffer_h handler, struct dynamicbox_buffer_event_data *event_info, void *data)
99 vwin_info_t info = data;
100 Elm_Access_Action_Info action_info;
101 Elm_Access_Action_Type action_type;
103 Evas_Object *parent_elm;
105 unsigned int flags = 0;
108 /* Just ignore this event */
116 switch (event_info->type) {
117 case DBOX_BUFFER_EVENT_ON_HOLD:
118 flags = evas_event_default_flags_get(info->e);
119 flags |= EVAS_EVENT_FLAG_ON_HOLD;
120 evas_event_default_flags_set(info->e, flags);
122 case DBOX_BUFFER_EVENT_OFF_HOLD:
123 flags = evas_event_default_flags_get(info->e);
124 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
125 evas_event_default_flags_set(info->e, flags);
127 case DBOX_BUFFER_EVENT_ON_SCROLL:
128 flags = evas_event_default_flags_get(info->e);
129 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
130 evas_event_default_flags_set(info->e, flags);
132 case DBOX_BUFFER_EVENT_OFF_SCROLL:
133 flags = evas_event_default_flags_get(info->e);
134 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
135 evas_event_default_flags_set(info->e, flags);
137 case DBOX_BUFFER_EVENT_ENTER:
138 evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
140 case DBOX_BUFFER_EVENT_LEAVE:
141 evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
143 case DBOX_BUFFER_EVENT_DOWN:
146 * Before processing the DOWN event,
147 * Reset the evas event flags regarding ON_HOLD option.
148 * It can be re-enabled while processing down-move-up events.
150 flags = evas_event_default_flags_get(info->e);
151 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
152 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
153 evas_event_default_flags_set(info->e, flags);
156 * Calculate the event occurred X & Y on the buffer
158 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
159 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
161 case DBOX_BUFFER_EVENT_MOVE:
164 * Calculate the event occurred X & Y on the buffer
166 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
168 case DBOX_BUFFER_EVENT_UP:
169 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
170 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL);
173 * We have to keep the event flags, so we should not clear them from here.
174 * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
175 * so if we reset them from here, those kind of callbacks will fails to do their job properly.
178 case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT:
179 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
181 ret = DBOX_ACCESS_STATUS_ERROR;
184 memset(&action_info, 0, sizeof(action_info));
185 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
188 * Calculate the event occurred X & Y on the buffer
190 action_info.x = event_info->info.access.x;
191 action_info.y = event_info->info.access.y;
192 ret = elm_access_action(parent_elm, action_type, &action_info);
193 if (ret == EINA_TRUE) {
194 if (!get_highlighted_object(parent_elm)) {
195 ErrPrint("Highlighted object is not found\n");
196 ret = DBOX_ACCESS_STATUS_ERROR;
198 DbgPrint("Highlighted object is found\n");
199 ret = DBOX_ACCESS_STATUS_DONE;
202 ErrPrint("Action error\n");
203 ret = DBOX_ACCESS_STATUS_ERROR;
206 case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
207 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
209 ret = DBOX_ACCESS_STATUS_ERROR;
212 memset(&action_info, 0, sizeof(action_info));
213 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
214 action_info.highlight_cycle = EINA_FALSE;
215 ret = elm_access_action(parent_elm, action_type, &action_info);
216 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_LAST : DBOX_ACCESS_STATUS_DONE;
218 case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
219 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
221 ret = DBOX_ACCESS_STATUS_ERROR;
224 memset(&action_info, 0, sizeof(action_info));
225 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
226 action_info.highlight_cycle = EINA_FALSE;
227 ret = elm_access_action(parent_elm, action_type, &action_info);
228 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_FIRST : DBOX_ACCESS_STATUS_DONE;
230 case DBOX_BUFFER_EVENT_ACCESS_ACTIVATE:
231 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
233 ret = DBOX_ACCESS_STATUS_ERROR;
236 memset(&action_info, 0, sizeof(action_info));
237 action_type = ELM_ACCESS_ACTION_ACTIVATE;
238 ret = elm_access_action(parent_elm, action_type, &action_info);
239 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
241 case DBOX_BUFFER_EVENT_ACCESS_ACTION_UP:
242 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
244 ret = DBOX_ACCESS_STATUS_ERROR;
247 memset(&action_info, 0, sizeof(action_info));
248 action_type = ELM_ACCESS_ACTION_UP;
249 ret = elm_access_action(parent_elm, action_type, &action_info);
250 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
252 case DBOX_BUFFER_EVENT_ACCESS_ACTION_DOWN:
253 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
255 ret = DBOX_ACCESS_STATUS_ERROR;
258 memset(&action_info, 0, sizeof(action_info));
259 action_type = ELM_ACCESS_ACTION_DOWN;
260 ret = elm_access_action(parent_elm, action_type, &action_info);
261 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
263 case DBOX_BUFFER_EVENT_ACCESS_SCROLL_UP:
264 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
266 ret = DBOX_ACCESS_STATUS_ERROR;
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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
277 case DBOX_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
278 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
280 ret = DBOX_ACCESS_STATUS_ERROR;
283 memset(&action_info, 0, sizeof(action_info));
284 action_type = ELM_ACCESS_ACTION_SCROLL;
285 action_info.x = event_info->info.access.x;
286 action_info.y = event_info->info.access.y;
287 action_info.mouse_type = event_info->info.access.mouse_type;
288 ret = elm_access_action(parent_elm, action_type, &action_info);
289 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
291 case DBOX_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
292 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
294 ret = DBOX_ACCESS_STATUS_ERROR;
297 memset(&action_info, 0, sizeof(action_info));
298 action_type = ELM_ACCESS_ACTION_SCROLL;
299 action_info.x = event_info->info.access.x;
300 action_info.y = event_info->info.access.y;
301 action_info.mouse_type = event_info->info.access.mouse_type;
302 ret = elm_access_action(parent_elm, action_type, &action_info);
303 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
305 case DBOX_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
306 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
308 ret = DBOX_ACCESS_STATUS_ERROR;
311 memset(&action_info, 0, sizeof(action_info));
312 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
313 ret = elm_access_action(parent_elm, action_type, &action_info);
314 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
316 case DBOX_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
317 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
319 ret = DBOX_ACCESS_STATUS_ERROR;
322 memset(&action_info, 0, sizeof(action_info));
323 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
330 case DBOX_BUFFER_EVENT_ACCESS_MOUSE:
331 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
333 ret = DBOX_ACCESS_STATUS_ERROR;
336 memset(&action_info, 0, sizeof(action_info));
337 action_type = ELM_ACCESS_ACTION_MOUSE;
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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
344 case DBOX_BUFFER_EVENT_ACCESS_BACK:
345 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
347 ret = DBOX_ACCESS_STATUS_ERROR;
350 memset(&action_info, 0, sizeof(action_info));
351 action_type = ELM_ACCESS_ACTION_BACK;
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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
358 case DBOX_BUFFER_EVENT_ACCESS_OVER:
359 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
361 ret = DBOX_ACCESS_STATUS_ERROR;
364 memset(&action_info, 0, sizeof(action_info));
365 action_type = ELM_ACCESS_ACTION_OVER;
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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
372 case DBOX_BUFFER_EVENT_ACCESS_READ:
373 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
375 ret = DBOX_ACCESS_STATUS_ERROR;
378 memset(&action_info, 0, sizeof(action_info));
379 action_type = ELM_ACCESS_ACTION_READ;
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) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
386 case DBOX_BUFFER_EVENT_ACCESS_ENABLE:
387 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
389 ret = DBOX_ACCESS_STATUS_ERROR;
392 memset(&action_info, 0, sizeof(action_info));
393 action_type = ELM_ACCESS_ACTION_ENABLE;
394 action_info.x = event_info->info.access.x;
395 action_info.y = event_info->info.access.y;
396 action_info.mouse_type = event_info->info.access.mouse_type;
397 ret = elm_access_action(parent_elm, action_type, &action_info);
398 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
400 case DBOX_BUFFER_EVENT_ACCESS_DISABLE:
401 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
403 ret = DBOX_ACCESS_STATUS_ERROR;
406 memset(&action_info, 0, sizeof(action_info));
407 action_type = ELM_ACCESS_ACTION_DISABLE;
408 action_info.x = event_info->info.access.x;
409 action_info.y = event_info->info.access.y;
410 action_info.mouse_type = event_info->info.access.mouse_type;
411 ret = elm_access_action(parent_elm, action_type, &action_info);
412 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
414 case DBOX_BUFFER_EVENT_KEY_DOWN:
415 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
417 ret = DBOX_ACCESS_STATUS_ERROR;
421 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
426 key_string = XKeysymToString(*key_symbol);
427 key_name = XKeysymToString(*key_symbol);
428 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
433 ret = DBOX_KEY_STATUS_ERROR;
435 case DBOX_BUFFER_EVENT_KEY_UP:
436 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
438 ret = DBOX_ACCESS_STATUS_ERROR;
442 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
447 key_string = XKeysymToString(*key_symbol);
448 key_name = XKeysymToString(*key_symbol);
449 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
454 ret = DBOX_KEY_STATUS_ERROR;
456 case DBOX_BUFFER_EVENT_KEY_FOCUS_IN:
457 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
459 ret = DBOX_ACCESS_STATUS_ERROR;
463 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
468 key_string = XKeysymToString(*key_symbol);
469 key_name = XKeysymToString(*key_symbol);
470 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
475 ret = DBOX_KEY_STATUS_ERROR;
477 case DBOX_BUFFER_EVENT_KEY_FOCUS_OUT:
478 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
480 ret = DBOX_ACCESS_STATUS_ERROR;
484 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
489 key_string = XKeysymToString(*key_symbol);
490 key_name = XKeysymToString(*key_symbol);
491 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
496 ret = DBOX_KEY_STATUS_ERROR;
499 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
508 * This callback can be called twice (or more) to get a several pixmaps
509 * Acquired pixmaps are used for double/tripple buffering for canvas
511 static Ecore_X_Pixmap alloc_pixmap_cb(void *data, Ecore_X_Window parent, int w, int h, int depth)
513 vwin_info_t info = data;
514 Ecore_X_Pixmap pixmap;
517 ErrPrint("Invalid handle\n");
523 DbgPrint("Size of ee is updated: %dx%d - %d (info: %p)\n", info->w, info->h, depth, info);
526 if (dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER) == 0u) {
529 * Need to allocate a primary buffer
531 dynamicbox_acquire_buffer(info->handle, DBOX_PRIMARY_BUFFER, info->w, info->h, depth);
533 ErrPrint("Failed to get the buffer\n");
537 pixmap = (Ecore_X_Pixmap)dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER);
538 } else if (DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT > 0) {
541 if (!info->resource_array) {
542 info->resource_array = calloc(DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT, sizeof(*info->resource_array));
543 if (!info->resource_array) {
544 ErrPrint("Out of memory: %s\n", strerror(errno));
550 for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
551 if (info->resource_array[idx] == 0u) {
556 if (idx == DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
557 ErrPrint("Out of index: %d\n", idx);
562 if (dynamicbox_acquire_buffer(info->handle, idx, info->w, info->h, depth) < 0) {
563 ErrPrint("Failed to acquire a buffer for %d\n", idx);
567 info->resource_array[idx] = dynamicbox_resource_id(info->handle, idx);
568 if (info->resource_array[idx] == 0u) {
569 ErrPrint("Failed to allocate pixmap\n");
572 DbgPrint("Allocated index: %d/%d - %u\n", idx, DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT, info->resource_array[idx]);
573 pixmap = info->resource_array[idx];
577 * Acquire a buffer for canvas.
579 info->type = VWIN_PIXMAP;
580 info->resource_cnt += !!pixmap;
584 static void free_pixmap_cb(void *data, Ecore_X_Pixmap pixmap)
586 vwin_info_t info = data;
592 if (info->type != VWIN_PIXMAP) {
593 ErrPrint("Impossible\n");
596 if (dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER) == pixmap) {
597 if (dynamicbox_release_buffer(info->handle, DBOX_PRIMARY_BUFFER) < 0) {
598 DbgPrint("Failed to release buffer\n");
600 info->resource_cnt--;
604 for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
607 * Find a index to release it
609 if (info->resource_array[idx] == pixmap) {
610 if (dynamicbox_release_buffer(info->handle, idx) < 0) {
611 DbgPrint("Failed to release buffer\n");
613 info->resource_array[idx] = 0u;
614 info->resource_cnt--;
620 if (info->deleted && info->resource_cnt == 0) {
621 DbgPrint("Destroy buffer handle\n");
623 dynamicbox_destroy_buffer(info->handle);
624 free(info->resource_array);
630 static void *alloc_fb(void *data, int size)
632 vwin_info_t info = data;
636 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
637 DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
641 ErrPrint("Failed to create a buffer\n");
645 if (dynamicbox_acquire_buffer(info->handle, DBOX_PRIMARY_BUFFER, info->w, info->h, sizeof(int)) < 0) {
646 ErrPrint("Failed to acquire buffer\n");
651 * If it supports the H/W accelerated buffer,
654 if (dynamicbox_support_hw_buffer(info->handle)) {
655 if (dynamicbox_create_hw_buffer(info->handle) == 0) {
656 buffer = dynamicbox_buffer_hw_buffer(info->handle);
658 DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
659 info->type = VWIN_GEM;
664 ErrPrint("Failed to allocate HW Accelerated buffer\n");
668 * Or use the buffer of a S/W backend.
670 buffer = dynamicbox_ref_buffer(info->handle);
671 DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
672 info->type = VWIN_SW_BUF;
676 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
680 buffer = alloc_fb(data, size);
682 vwin_info_t info = data;
686 _stride = dynamicbox_buffer_stride(info->handle);
688 _stride = info->w * *bpp;
693 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
699 static void free_fb(void *data, void *ptr)
701 vwin_info_t info = data;
707 if (info->type == VWIN_GEM) {
708 if (dynamicbox_destroy_hw_buffer(info->handle) == 0) {
709 DbgPrint("HW Accelerated buffer is destroyed\n");
711 } else if (info->type == VWIN_SW_BUF) {
712 DbgPrint("SW buffer is destroyed, %p\n", info);
713 dynamicbox_unref_buffer(ptr);
714 } else if (info->type == VWIN_PIXMAP) {
715 ErrPrint("Unable to reach to here\n");
718 if (dynamicbox_release_buffer(info->handle, DBOX_PRIMARY_BUFFER) < 0) {
719 ErrPrint("Failed to release buffer\n");
723 dynamicbox_destroy_buffer(info->handle);
724 free(info->resource_array);
730 static void pre_render_cb(void *data, Evas *e, void *event_info)
732 vwin_info_t info = data;
738 if (dynamicbox_conf_premultiplied_alpha()) {
742 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
743 evas_damage_rectangle_add(e, 0, 0, w, h);
746 if (info->type == VWIN_GEM) {
747 dynamicbox_buffer_pre_render(info->handle);
748 } else if (info->type == VWIN_PIXMAP) {
750 * Only the pixmap type Ecore_Evas uses this variable
752 info->front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
753 } else if (info->type == VWIN_SW_BUF) {
758 static void post_render_cb(void *data, Evas *e, void *event_info)
760 vwin_info_t info = data;
766 if (dynamicbox_conf_premultiplied_alpha()) {
770 // Get a pointer of a buffer of the virtual canvas
771 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
773 ErrPrint("Failed to get pixel canvas\n");
777 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
778 evas_data_argb_unpremul(canvas, w * h);
781 if (info->type == VWIN_GEM) {
782 dynamicbox_buffer_post_render(info->handle);
783 } else if (info->type == VWIN_PIXMAP) {
786 for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
787 if (info->front_resource_id == info->resource_array[idx]) {
790 dynamicbox_send_updated_by_idx(info->handle, idx);
795 if (idx == DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
796 /* Send updated event for PRIMARY BUFFER */
797 if (info->front_resource_id == dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER)) {
798 dynamicbox_send_updated_by_idx(info->handle, DBOX_PRIMARY_BUFFER);
800 DbgPrint("Unable to send updated: %u (%u)\n", info->front_resource_id, dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER));
803 } else if (info->type == VWIN_SW_BUF) {
804 dynamicbox_sync_buffer(info->handle);
808 static void ecore_evas_free_cb(Ecore_Evas *ee)
812 info = ecore_evas_data_get(ee, "dynamic,box,info");
814 DbgPrint("Info is not valid\n");
819 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
820 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
827 PUBLIC void *dynamicbox_get_evas_object(const char *id, int is_gbar)
832 int gl_is_turned_on = 0;
834 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
835 s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
836 if (!s_info.alloc_canvas_with_pixmap) {
837 DbgPrint("pixmap_allocfunc_new is not found\n");
840 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
841 if (!s_info.alloc_canvas_with_stride) {
842 DbgPrint("allocfunc_with_stirde_new is not found\n");
845 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
846 if (!s_info.alloc_canvas) {
847 ErrPrint("allocfunc_new is not found\n");
850 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
851 ErrPrint("No way to allocate canvas\n");
857 ErrPrint("Invalid parameter\n");
861 info = calloc(1, sizeof(*info));
863 ErrPrint("Heap: %s\n", strerror(errno));
867 info->id = strdup(id);
869 ErrPrint("Heap: %s\n", strerror(errno));
874 info->is_gbar = is_gbar;
877 * Acquire a buffer for canvas.
879 info->handle = dynamicbox_create_buffer(info->id, info->is_gbar,
880 (dynamicbox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
881 event_handler_cb, info);
884 ErrPrint("Failed to create a dynamicbox buffer\n");
891 * Size information must be initialized before call the ecore_evas_buffer_new.
893 info->w = DBOX_DEFAULT_WIDTH;
894 info->h = DBOX_DEFAULT_HEIGHT;
896 engine = elm_config_preferred_engine_get();
897 DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
898 if (engine && !strcmp(engine, GL_ENGINE)) {
899 if (s_info.alloc_canvas_with_pixmap) {
900 info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
902 ErrPrint("Unable to create a ee for pixmap\n");
910 if (!dynamicbox_conf_auto_align() && s_info.alloc_canvas_with_stride) {
911 info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
912 } else if (s_info.alloc_canvas) {
913 info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
918 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
919 dynamicbox_destroy_buffer(info->handle);
925 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
929 * Free callback must be prepared before use the ecore_evas_free()
931 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
933 info->e = ecore_evas_get(info->ee);
935 ErrPrint("Failed to get evas\n");
936 ecore_evas_free(info->ee);
940 if (!gl_is_turned_on) {
941 pre_render_cb(info, NULL, NULL);
942 ecore_evas_alpha_set(info->ee, EINA_TRUE);
943 post_render_cb(info, NULL, NULL);
945 DbgPrint("opengl-x11 engine should not turn on the alpha\n");
948 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
949 ecore_evas_resize(info->ee, info->w, info->h);
951 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
952 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
954 rect = evas_object_rectangle_add(info->e);
956 ErrPrint("Failed to create evas_object\n");
957 ecore_evas_free(info->ee);
961 evas_object_resize(rect, info->w, info->h);
962 evas_object_color_set(rect, 0, 0, 0, 0);