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"
36 #include "internal/dynamicbox.h"
41 #define PUBLIC __attribute__((visibility("default")))
42 #define DBOX_WIN_TAG "dynamic,box,win"
44 #define DBOX_DEFAULT_WIDTH 1
45 #define DBOX_DEFAULT_HEIGHT 1
46 #define GL_ENGINE "opengl_x11"
48 static struct static_info {
49 Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
50 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);
51 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);
54 .alloc_canvas_with_stride = NULL,
55 .alloc_canvas_with_pixmap = NULL,
60 * Abstracted Data Type of Virtual Window
62 typedef struct virtual_window_info {
63 char *id; /**< Identification */
64 dynamicbox_buffer_h handle; /**< Livebox buffer handle */
66 VWIN_SW_BUF = 0x00, /**< S/W buffer */
67 VWIN_GEM = 0x01, /**< GEM buffer */
68 VWIN_PIXMAP = 0x02, /**< PIXMAP */
69 VWIN_ERROR = 0x03 /**< Unknown */
77 unsigned int *resource_array;
83 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
87 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
90 ho = evas_object_data_get(o, "_elm_access_target");
96 * Every user event (mouse) on the buffer will be passed via this event callback
98 static int event_handler_cb(dynamicbox_buffer_h handler, struct dynamicbox_buffer_event_data *event_info, void *data)
100 vwin_info_t info = data;
101 Elm_Access_Action_Info action_info;
102 Elm_Access_Action_Type action_type;
104 Evas_Object *parent_elm;
106 unsigned int flags = 0;
110 /* Just ignore this event */
114 if (DYNAMICBOX_CONF_USE_GETTIMEOFDAY) {
115 if (DYNAMICBOX_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == DBOX_BUFFER_EVENT_MOVE)) {
118 if (gettimeofday(&tv, NULL) < 0) {
119 ErrPrint("gettimeofday: %s\n", strerror(errno));
121 timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
122 timestamp -= event_info->timestamp;
124 if (timestamp > DYNAMICBOX_CONF_EVENT_FILTER) {
125 DbgPrint("Dropped %lf\n", timestamp);
132 * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
133 * Evas only use the monotic time for animating objects
135 timestamp = ecore_time_get() * 1000.0f;
137 if (DYNAMICBOX_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == DBOX_BUFFER_EVENT_MOVE)) {
138 timestamp = ecore_time_get();
140 timestamp -= event_info->timestamp;
141 if (timestamp > DYNAMICBOX_CONF_EVENT_FILTER) {
142 DbgPrint("Dropped %lf\n", timestamp);
147 timestamp = event_info->timestamp * 1000.0f;
154 switch (event_info->type) {
155 case DBOX_BUFFER_EVENT_ON_HOLD:
156 flags = evas_event_default_flags_get(info->e);
157 flags |= EVAS_EVENT_FLAG_ON_HOLD;
158 evas_event_default_flags_set(info->e, flags);
159 ErrPrint("ON_HOLD[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
161 case DBOX_BUFFER_EVENT_OFF_HOLD:
162 flags = evas_event_default_flags_get(info->e);
163 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
164 evas_event_default_flags_set(info->e, flags);
166 case DBOX_BUFFER_EVENT_ON_SCROLL:
167 flags = evas_event_default_flags_get(info->e);
168 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
169 evas_event_default_flags_set(info->e, flags);
171 case DBOX_BUFFER_EVENT_OFF_SCROLL:
172 flags = evas_event_default_flags_get(info->e);
173 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
174 evas_event_default_flags_set(info->e, flags);
176 case DBOX_BUFFER_EVENT_ENTER:
177 evas_event_feed_mouse_in(info->e, timestamp, NULL);
179 case DBOX_BUFFER_EVENT_LEAVE:
180 evas_event_feed_mouse_out(info->e, timestamp, NULL);
182 case DBOX_BUFFER_EVENT_DOWN:
185 * Before processing the DOWN event,
186 * Reset the evas event flags regarding ON_HOLD option.
187 * It can be re-enabled while processing down-move-up events.
189 flags = evas_event_default_flags_get(info->e);
190 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
191 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
192 evas_event_default_flags_set(info->e, flags);
195 * Calculate the event occurred X & Y on the buffer
197 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
198 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
200 ErrPrint("DOWN[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
202 case DBOX_BUFFER_EVENT_MOVE:
205 * Calculate the event occurred X & Y on the buffer
207 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
209 case DBOX_BUFFER_EVENT_UP:
210 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
211 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
215 * We have to keep the event flags, so we should not clear them from here.
216 * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
217 * so if we reset them from here, those kind of callbacks will fails to do their job properly.
219 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
221 case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT:
222 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
224 ret = DBOX_ACCESS_STATUS_ERROR;
227 memset(&action_info, 0, sizeof(action_info));
228 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
231 * Calculate the event occurred X & Y on the buffer
233 action_info.x = event_info->info.access.x;
234 action_info.y = event_info->info.access.y;
235 ret = elm_access_action(parent_elm, action_type, &action_info);
236 if (ret == EINA_TRUE) {
237 if (!get_highlighted_object(parent_elm)) {
238 ErrPrint("Highlighted object is not found\n");
239 ret = DBOX_ACCESS_STATUS_ERROR;
241 DbgPrint("Highlighted object is found\n");
242 ret = DBOX_ACCESS_STATUS_DONE;
245 ErrPrint("Action error\n");
246 ret = DBOX_ACCESS_STATUS_ERROR;
249 case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
250 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
252 ret = DBOX_ACCESS_STATUS_ERROR;
255 memset(&action_info, 0, sizeof(action_info));
256 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
257 action_info.highlight_cycle = EINA_FALSE;
258 ret = elm_access_action(parent_elm, action_type, &action_info);
259 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_LAST : DBOX_ACCESS_STATUS_DONE;
261 case DBOX_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
262 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
264 ret = DBOX_ACCESS_STATUS_ERROR;
267 memset(&action_info, 0, sizeof(action_info));
268 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
269 action_info.highlight_cycle = EINA_FALSE;
270 ret = elm_access_action(parent_elm, action_type, &action_info);
271 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_FIRST : DBOX_ACCESS_STATUS_DONE;
273 case DBOX_BUFFER_EVENT_ACCESS_ACTIVATE:
274 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
276 ret = DBOX_ACCESS_STATUS_ERROR;
279 memset(&action_info, 0, sizeof(action_info));
280 action_type = ELM_ACCESS_ACTION_ACTIVATE;
281 ret = elm_access_action(parent_elm, action_type, &action_info);
282 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
284 case DBOX_BUFFER_EVENT_ACCESS_ACTION_UP:
285 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
287 ret = DBOX_ACCESS_STATUS_ERROR;
290 memset(&action_info, 0, sizeof(action_info));
291 action_type = ELM_ACCESS_ACTION_UP;
292 ret = elm_access_action(parent_elm, action_type, &action_info);
293 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
295 case DBOX_BUFFER_EVENT_ACCESS_ACTION_DOWN:
296 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
298 ret = DBOX_ACCESS_STATUS_ERROR;
301 memset(&action_info, 0, sizeof(action_info));
302 action_type = ELM_ACCESS_ACTION_DOWN;
303 ret = elm_access_action(parent_elm, action_type, &action_info);
304 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
306 case DBOX_BUFFER_EVENT_ACCESS_SCROLL_UP:
307 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
309 ret = DBOX_ACCESS_STATUS_ERROR;
312 memset(&action_info, 0, sizeof(action_info));
313 action_type = ELM_ACCESS_ACTION_SCROLL;
314 action_info.x = event_info->info.access.x;
315 action_info.y = event_info->info.access.y;
316 action_info.mouse_type = event_info->info.access.mouse_type;
317 ret = elm_access_action(parent_elm, action_type, &action_info);
318 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
320 case DBOX_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
321 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
323 ret = DBOX_ACCESS_STATUS_ERROR;
326 memset(&action_info, 0, sizeof(action_info));
327 action_type = ELM_ACCESS_ACTION_SCROLL;
328 action_info.x = event_info->info.access.x;
329 action_info.y = event_info->info.access.y;
330 action_info.mouse_type = event_info->info.access.mouse_type;
331 ret = elm_access_action(parent_elm, action_type, &action_info);
332 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
334 case DBOX_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
335 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
337 ret = DBOX_ACCESS_STATUS_ERROR;
340 memset(&action_info, 0, sizeof(action_info));
341 action_type = ELM_ACCESS_ACTION_SCROLL;
342 action_info.x = event_info->info.access.x;
343 action_info.y = event_info->info.access.y;
344 action_info.mouse_type = event_info->info.access.mouse_type;
345 ret = elm_access_action(parent_elm, action_type, &action_info);
346 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
348 case DBOX_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
349 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
351 ret = DBOX_ACCESS_STATUS_ERROR;
354 memset(&action_info, 0, sizeof(action_info));
355 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
356 ret = elm_access_action(parent_elm, action_type, &action_info);
357 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
359 case DBOX_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
360 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
362 ret = DBOX_ACCESS_STATUS_ERROR;
365 memset(&action_info, 0, sizeof(action_info));
366 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
367 action_info.x = event_info->info.access.x;
368 action_info.y = event_info->info.access.y;
369 action_info.mouse_type = event_info->info.access.mouse_type;
370 ret = elm_access_action(parent_elm, action_type, &action_info);
371 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
373 case DBOX_BUFFER_EVENT_ACCESS_MOUSE:
374 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
376 ret = DBOX_ACCESS_STATUS_ERROR;
379 memset(&action_info, 0, sizeof(action_info));
380 action_type = ELM_ACCESS_ACTION_MOUSE;
381 action_info.x = event_info->info.access.x;
382 action_info.y = event_info->info.access.y;
383 action_info.mouse_type = event_info->info.access.mouse_type;
384 ret = elm_access_action(parent_elm, action_type, &action_info);
385 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
387 case DBOX_BUFFER_EVENT_ACCESS_BACK:
388 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
390 ret = DBOX_ACCESS_STATUS_ERROR;
393 memset(&action_info, 0, sizeof(action_info));
394 action_type = ELM_ACCESS_ACTION_BACK;
395 action_info.x = event_info->info.access.x;
396 action_info.y = event_info->info.access.y;
397 action_info.mouse_type = event_info->info.access.mouse_type;
398 ret = elm_access_action(parent_elm, action_type, &action_info);
399 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
401 case DBOX_BUFFER_EVENT_ACCESS_OVER:
402 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
404 ret = DBOX_ACCESS_STATUS_ERROR;
407 memset(&action_info, 0, sizeof(action_info));
408 action_type = ELM_ACCESS_ACTION_OVER;
409 action_info.x = event_info->info.access.x;
410 action_info.y = event_info->info.access.y;
411 action_info.mouse_type = event_info->info.access.mouse_type;
412 ret = elm_access_action(parent_elm, action_type, &action_info);
413 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
415 case DBOX_BUFFER_EVENT_ACCESS_READ:
416 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
418 ret = DBOX_ACCESS_STATUS_ERROR;
421 memset(&action_info, 0, sizeof(action_info));
422 action_type = ELM_ACCESS_ACTION_READ;
423 action_info.x = event_info->info.access.x;
424 action_info.y = event_info->info.access.y;
425 action_info.mouse_type = event_info->info.access.mouse_type;
426 ret = elm_access_action(parent_elm, action_type, &action_info);
427 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
429 case DBOX_BUFFER_EVENT_ACCESS_ENABLE:
430 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
432 ret = DBOX_ACCESS_STATUS_ERROR;
435 memset(&action_info, 0, sizeof(action_info));
436 action_type = ELM_ACCESS_ACTION_ENABLE;
437 action_info.x = event_info->info.access.x;
438 action_info.y = event_info->info.access.y;
439 action_info.mouse_type = event_info->info.access.mouse_type;
440 ret = elm_access_action(parent_elm, action_type, &action_info);
441 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
443 case DBOX_BUFFER_EVENT_ACCESS_DISABLE:
444 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
446 ret = DBOX_ACCESS_STATUS_ERROR;
449 memset(&action_info, 0, sizeof(action_info));
450 action_type = ELM_ACCESS_ACTION_DISABLE;
451 action_info.x = event_info->info.access.x;
452 action_info.y = event_info->info.access.y;
453 action_info.mouse_type = event_info->info.access.mouse_type;
454 ret = elm_access_action(parent_elm, action_type, &action_info);
455 ret = (ret == EINA_FALSE) ? DBOX_ACCESS_STATUS_ERROR : DBOX_ACCESS_STATUS_DONE;
457 case DBOX_BUFFER_EVENT_KEY_DOWN:
458 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
460 ret = DBOX_ACCESS_STATUS_ERROR;
464 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
469 key_string = XKeysymToString(*key_symbol);
470 key_name = XKeysymToString(*key_symbol);
471 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
476 ret = DBOX_KEY_STATUS_ERROR;
478 case DBOX_BUFFER_EVENT_KEY_UP:
479 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
481 ret = DBOX_ACCESS_STATUS_ERROR;
485 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
490 key_string = XKeysymToString(*key_symbol);
491 key_name = XKeysymToString(*key_symbol);
492 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
497 ret = DBOX_KEY_STATUS_ERROR;
499 case DBOX_BUFFER_EVENT_KEY_FOCUS_IN:
500 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
502 ret = DBOX_ACCESS_STATUS_ERROR;
506 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
511 key_string = XKeysymToString(*key_symbol);
512 key_name = XKeysymToString(*key_symbol);
513 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
518 ret = DBOX_KEY_STATUS_ERROR;
520 case DBOX_BUFFER_EVENT_KEY_FOCUS_OUT:
521 parent_elm = ecore_evas_data_get(info->ee, DBOX_WIN_TAG);
523 ret = DBOX_ACCESS_STATUS_ERROR;
527 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
532 key_string = XKeysymToString(*key_symbol);
533 key_name = XKeysymToString(*key_symbol);
534 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
539 ret = DBOX_KEY_STATUS_ERROR;
542 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
551 * This callback can be called twice (or more) to get a several pixmaps
552 * Acquired pixmaps are used for double/tripple buffering for canvas
554 static Ecore_X_Pixmap alloc_pixmap_cb(void *data, Ecore_X_Window parent, int w, int h, int depth)
556 vwin_info_t info = data;
557 Ecore_X_Pixmap pixmap;
560 ErrPrint("Invalid handle\n");
566 DbgPrint("Size of ee is updated: %dx%d - %d (info: %p)\n", info->w, info->h, depth, info);
569 if (dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER) == 0u) {
572 * Need to allocate a primary buffer
574 dynamicbox_acquire_buffer(info->handle, DBOX_PRIMARY_BUFFER, info->w, info->h, depth);
576 ErrPrint("Failed to get the buffer\n");
580 pixmap = (Ecore_X_Pixmap)dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER);
581 } else if (DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT > 0) {
584 if (!info->resource_array) {
585 info->resource_array = calloc(DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT, sizeof(*info->resource_array));
586 if (!info->resource_array) {
587 ErrPrint("Out of memory: %s\n", strerror(errno));
593 for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
594 if (info->resource_array[idx] == 0u) {
599 if (idx == DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
600 ErrPrint("Out of index: %d\n", idx);
605 if (dynamicbox_acquire_buffer(info->handle, idx, info->w, info->h, depth) < 0) {
606 ErrPrint("Failed to acquire a buffer for %d\n", idx);
610 info->resource_array[idx] = dynamicbox_resource_id(info->handle, idx);
611 if (info->resource_array[idx] == 0u) {
612 ErrPrint("Failed to allocate pixmap\n");
615 DbgPrint("Allocated index: %d/%d - %u\n", idx, DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT, info->resource_array[idx]);
616 pixmap = info->resource_array[idx];
618 ErrPrint("Unable to allocate pixmap\n");
623 * Acquire a buffer for canvas.
625 info->type = VWIN_PIXMAP;
626 info->resource_cnt += !!(unsigned int)pixmap;
630 static void free_pixmap_cb(void *data, Ecore_X_Pixmap pixmap)
632 vwin_info_t info = data;
638 if (info->type != VWIN_PIXMAP) {
639 ErrPrint("Impossible\n");
642 if (dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER) == pixmap) {
643 if (dynamicbox_release_buffer(info->handle, DBOX_PRIMARY_BUFFER) < 0) {
644 DbgPrint("Failed to release buffer\n");
646 info->resource_cnt--;
650 for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
653 * Find a index to release it
655 if (info->resource_array[idx] == pixmap) {
656 if (dynamicbox_release_buffer(info->handle, idx) < 0) {
657 DbgPrint("Failed to release buffer\n");
659 info->resource_array[idx] = 0u;
660 info->resource_cnt--;
666 if (info->deleted && info->resource_cnt == 0) {
667 DbgPrint("Destroy buffer handle\n");
669 dynamicbox_destroy_buffer(info->handle);
670 free(info->resource_array);
676 static void *alloc_fb(void *data, int size)
678 vwin_info_t info = data;
682 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
683 DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
687 ErrPrint("Failed to create a buffer\n");
691 if (dynamicbox_acquire_buffer(info->handle, DBOX_PRIMARY_BUFFER, info->w, info->h, sizeof(int)) < 0) {
692 ErrPrint("Failed to acquire buffer\n");
697 * If it supports the H/W accelerated buffer,
700 if (dynamicbox_support_hw_buffer(info->handle)) {
701 if (dynamicbox_create_hw_buffer(info->handle) == 0) {
702 buffer = dynamicbox_buffer_hw_buffer(info->handle);
704 DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
705 info->type = VWIN_GEM;
710 ErrPrint("Failed to allocate HW Accelerated buffer\n");
714 * Or use the buffer of a S/W backend.
716 buffer = dynamicbox_ref_buffer(info->handle);
717 DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
718 info->type = VWIN_SW_BUF;
722 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
726 buffer = alloc_fb(data, size);
728 vwin_info_t info = data;
732 _stride = dynamicbox_buffer_stride(info->handle);
734 _stride = info->w * *bpp;
739 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
745 static void free_fb(void *data, void *ptr)
747 vwin_info_t info = data;
753 if (info->type == VWIN_GEM) {
754 if (dynamicbox_destroy_hw_buffer(info->handle) == 0) {
755 DbgPrint("HW Accelerated buffer is destroyed\n");
757 } else if (info->type == VWIN_SW_BUF) {
758 DbgPrint("SW buffer is destroyed, %p\n", info);
759 dynamicbox_unref_buffer(ptr);
760 } else if (info->type == VWIN_PIXMAP) {
761 ErrPrint("Unable to reach to here\n");
764 if (dynamicbox_release_buffer(info->handle, DBOX_PRIMARY_BUFFER) < 0) {
765 ErrPrint("Failed to release buffer\n");
769 dynamicbox_destroy_buffer(info->handle);
770 free(info->resource_array);
776 static void pre_render_cb(void *data, Evas *e, void *event_info)
778 vwin_info_t info = data;
784 if (dynamicbox_conf_premultiplied_alpha()) {
788 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
789 evas_damage_rectangle_add(e, 0, 0, w, h);
792 if (info->type == VWIN_GEM) {
793 dynamicbox_buffer_pre_render(info->handle);
794 } else if (info->type == VWIN_PIXMAP) {
796 * Only the pixmap type Ecore_Evas uses this variable
798 } else if (info->type == VWIN_SW_BUF) {
803 static void post_render_cb(void *data, Evas *e, void *event_info)
805 vwin_info_t info = data;
811 if (dynamicbox_conf_premultiplied_alpha()) {
815 // Get a pointer of a buffer of the virtual canvas
816 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
818 ErrPrint("Failed to get pixel canvas\n");
822 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
823 evas_data_argb_unpremul(canvas, w * h);
826 if (info->type == VWIN_GEM) {
827 dynamicbox_buffer_post_render(info->handle);
828 } else if (info->type == VWIN_PIXMAP) {
830 unsigned int front_resource_id;
832 front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
834 for (idx = 0; idx < DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT; idx++) {
835 if (front_resource_id == info->resource_array[idx]) {
838 dynamicbox_send_updated_by_idx(info->handle, idx);
843 if (idx == DYNAMICBOX_CONF_EXTRA_BUFFER_COUNT) {
844 /* Send updated event for PRIMARY BUFFER */
845 if (front_resource_id == dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER)) {
846 dynamicbox_send_updated_by_idx(info->handle, DBOX_PRIMARY_BUFFER);
848 DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, dynamicbox_resource_id(info->handle, DBOX_PRIMARY_BUFFER));
851 } else if (info->type == VWIN_SW_BUF) {
852 dynamicbox_sync_buffer(info->handle);
856 static void ecore_evas_free_cb(Ecore_Evas *ee)
860 info = ecore_evas_data_get(ee, "dynamic,box,info");
862 DbgPrint("Info is not valid\n");
867 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
868 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
875 PUBLIC void *dynamicbox_get_evas_object(const char *id, int is_gbar)
881 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
882 s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
883 if (!s_info.alloc_canvas_with_pixmap) {
884 DbgPrint("pixmap_allocfunc_new is not found\n");
887 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
888 if (!s_info.alloc_canvas_with_stride) {
889 DbgPrint("allocfunc_with_stirde_new is not found\n");
892 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
893 if (!s_info.alloc_canvas) {
894 ErrPrint("allocfunc_new is not found\n");
897 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
898 ErrPrint("No way to allocate canvas\n");
904 ErrPrint("Invalid parameter\n");
908 info = calloc(1, sizeof(*info));
910 ErrPrint("Heap: %s\n", strerror(errno));
914 info->id = strdup(id);
916 ErrPrint("Heap: %s\n", strerror(errno));
921 info->is_gbar = is_gbar;
924 * Acquire a buffer for canvas.
926 info->handle = dynamicbox_create_buffer(info->id, info->is_gbar,
927 (dynamicbox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
928 event_handler_cb, info);
931 ErrPrint("Failed to create a dynamicbox buffer\n");
938 * Size information must be initialized before call the ecore_evas_buffer_new.
940 info->w = DBOX_DEFAULT_WIDTH;
941 info->h = DBOX_DEFAULT_HEIGHT;
943 engine = elm_config_preferred_engine_get();
944 DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
945 if (engine && !strcmp(engine, GL_ENGINE)) {
946 if (s_info.alloc_canvas_with_pixmap) {
947 info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
949 ErrPrint("Unable to create a ee for pixmap\n");
955 if (!dynamicbox_conf_auto_align() && s_info.alloc_canvas_with_stride) {
956 info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
957 } else if (s_info.alloc_canvas) {
958 info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
963 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
964 dynamicbox_destroy_buffer(info->handle);
970 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
974 * Free callback must be prepared before use the ecore_evas_free()
976 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
978 info->e = ecore_evas_get(info->ee);
980 ErrPrint("Failed to get evas\n");
981 ecore_evas_free(info->ee);
985 pre_render_cb(info, NULL, NULL);
986 ecore_evas_alpha_set(info->ee, EINA_TRUE);
987 post_render_cb(info, NULL, NULL);
989 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
990 ecore_evas_resize(info->ee, info->w, info->h);
992 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
993 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
995 rect = evas_object_rectangle_add(info->e);
997 ErrPrint("Failed to create evas_object\n");
998 ecore_evas_free(info->ee);
1002 evas_object_resize(rect, info->w, info->h);
1003 evas_object_color_set(rect, 0, 0, 0, 0);