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 <widget_errno.h>
31 #include <widget_service.h>
32 #include <widget_conf.h>
33 #include <widget_buffer.h>
36 #include "widget_internal.h"
41 #define PUBLIC __attribute__((visibility("default")))
42 #define WIDGET_WIN_TAG "dynamic,box,win"
44 #define WIDGET_DEFAULT_WIDTH 1
45 #define WIDGET_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 widget_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(widget_buffer_h handler, struct widget_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 (WIDGET_CONF_USE_GETTIMEOFDAY) {
115 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_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 > WIDGET_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 (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
138 timestamp = ecore_time_get();
140 timestamp -= event_info->timestamp;
141 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
142 DbgPrint("Dropped %lf\n", timestamp);
147 timestamp = event_info->timestamp * 1000.0f;
154 switch (event_info->type) {
155 case WIDGET_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 WIDGET_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 WIDGET_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 WIDGET_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 WIDGET_BUFFER_EVENT_ENTER:
177 evas_event_feed_mouse_in(info->e, timestamp, NULL);
179 case WIDGET_BUFFER_EVENT_LEAVE:
180 evas_event_feed_mouse_out(info->e, timestamp, NULL);
182 case WIDGET_BUFFER_EVENT_DOWN:
184 ErrPrint("MOUSE UP is not called\n");
185 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
186 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
187 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
192 * Before processing the DOWN event,
193 * Reset the evas event flags regarding ON_HOLD option.
194 * It can be re-enabled while processing down-move-up events.
196 flags = evas_event_default_flags_get(info->e);
197 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
198 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
199 evas_event_default_flags_set(info->e, flags);
202 * Calculate the event occurred X & Y on the buffer
204 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
205 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
207 ErrPrint("DOWN[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
209 case WIDGET_BUFFER_EVENT_MOVE:
212 * Calculate the event occurred X & Y on the buffer
214 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
216 case WIDGET_BUFFER_EVENT_UP:
217 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
218 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
222 * We have to keep the event flags, so we should not clear them from here.
223 * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
224 * so if we reset them from here, those kind of callbacks will fails to do their job properly.
226 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
228 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
229 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
231 ret = WIDGET_ACCESS_STATUS_ERROR;
234 memset(&action_info, 0, sizeof(action_info));
235 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
238 * Calculate the event occurred X & Y on the buffer
240 action_info.x = event_info->info.access.x;
241 action_info.y = event_info->info.access.y;
242 ret = elm_access_action(parent_elm, action_type, &action_info);
243 if (ret == EINA_TRUE) {
244 if (!get_highlighted_object(parent_elm)) {
245 ErrPrint("Highlighted object is not found\n");
246 ret = WIDGET_ACCESS_STATUS_ERROR;
248 DbgPrint("Highlighted object is found\n");
249 ret = WIDGET_ACCESS_STATUS_DONE;
252 ErrPrint("Action error\n");
253 ret = WIDGET_ACCESS_STATUS_ERROR;
256 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
257 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
259 ret = WIDGET_ACCESS_STATUS_ERROR;
262 memset(&action_info, 0, sizeof(action_info));
263 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
264 action_info.highlight_cycle = EINA_FALSE;
265 ret = elm_access_action(parent_elm, action_type, &action_info);
266 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
268 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
269 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
271 ret = WIDGET_ACCESS_STATUS_ERROR;
274 memset(&action_info, 0, sizeof(action_info));
275 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
276 action_info.highlight_cycle = EINA_FALSE;
277 ret = elm_access_action(parent_elm, action_type, &action_info);
278 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
280 case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
281 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
283 ret = WIDGET_ACCESS_STATUS_ERROR;
286 memset(&action_info, 0, sizeof(action_info));
287 action_type = ELM_ACCESS_ACTION_ACTIVATE;
288 ret = elm_access_action(parent_elm, action_type, &action_info);
289 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
291 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
292 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
294 ret = WIDGET_ACCESS_STATUS_ERROR;
297 memset(&action_info, 0, sizeof(action_info));
298 action_type = ELM_ACCESS_ACTION_UP;
299 ret = elm_access_action(parent_elm, action_type, &action_info);
300 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
302 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
303 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
305 ret = WIDGET_ACCESS_STATUS_ERROR;
308 memset(&action_info, 0, sizeof(action_info));
309 action_type = ELM_ACCESS_ACTION_DOWN;
310 ret = elm_access_action(parent_elm, action_type, &action_info);
311 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
313 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
314 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
316 ret = WIDGET_ACCESS_STATUS_ERROR;
319 memset(&action_info, 0, sizeof(action_info));
320 action_type = ELM_ACCESS_ACTION_SCROLL;
321 action_info.x = event_info->info.access.x;
322 action_info.y = event_info->info.access.y;
323 action_info.mouse_type = event_info->info.access.mouse_type;
324 ret = elm_access_action(parent_elm, action_type, &action_info);
325 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
327 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
328 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
330 ret = WIDGET_ACCESS_STATUS_ERROR;
333 memset(&action_info, 0, sizeof(action_info));
334 action_type = ELM_ACCESS_ACTION_SCROLL;
335 action_info.x = event_info->info.access.x;
336 action_info.y = event_info->info.access.y;
337 action_info.mouse_type = event_info->info.access.mouse_type;
338 ret = elm_access_action(parent_elm, action_type, &action_info);
339 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
341 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
342 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
344 ret = WIDGET_ACCESS_STATUS_ERROR;
347 memset(&action_info, 0, sizeof(action_info));
348 action_type = ELM_ACCESS_ACTION_SCROLL;
349 action_info.x = event_info->info.access.x;
350 action_info.y = event_info->info.access.y;
351 action_info.mouse_type = event_info->info.access.mouse_type;
352 ret = elm_access_action(parent_elm, action_type, &action_info);
353 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
355 case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
356 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
358 ret = WIDGET_ACCESS_STATUS_ERROR;
361 memset(&action_info, 0, sizeof(action_info));
362 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
363 ret = elm_access_action(parent_elm, action_type, &action_info);
364 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
366 case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
367 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
369 ret = WIDGET_ACCESS_STATUS_ERROR;
372 memset(&action_info, 0, sizeof(action_info));
373 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
374 action_info.x = event_info->info.access.x;
375 action_info.y = event_info->info.access.y;
376 action_info.mouse_type = event_info->info.access.mouse_type;
377 ret = elm_access_action(parent_elm, action_type, &action_info);
378 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
380 case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
381 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
383 ret = WIDGET_ACCESS_STATUS_ERROR;
386 memset(&action_info, 0, sizeof(action_info));
387 action_type = ELM_ACCESS_ACTION_MOUSE;
388 action_info.x = event_info->info.access.x;
389 action_info.y = event_info->info.access.y;
390 action_info.mouse_type = event_info->info.access.mouse_type;
391 ret = elm_access_action(parent_elm, action_type, &action_info);
392 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
394 case WIDGET_BUFFER_EVENT_ACCESS_BACK:
395 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
397 ret = WIDGET_ACCESS_STATUS_ERROR;
400 memset(&action_info, 0, sizeof(action_info));
401 action_type = ELM_ACCESS_ACTION_BACK;
402 action_info.x = event_info->info.access.x;
403 action_info.y = event_info->info.access.y;
404 action_info.mouse_type = event_info->info.access.mouse_type;
405 ret = elm_access_action(parent_elm, action_type, &action_info);
406 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
408 case WIDGET_BUFFER_EVENT_ACCESS_OVER:
409 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
411 ret = WIDGET_ACCESS_STATUS_ERROR;
414 memset(&action_info, 0, sizeof(action_info));
415 action_type = ELM_ACCESS_ACTION_OVER;
416 action_info.x = event_info->info.access.x;
417 action_info.y = event_info->info.access.y;
418 action_info.mouse_type = event_info->info.access.mouse_type;
419 ret = elm_access_action(parent_elm, action_type, &action_info);
420 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
422 case WIDGET_BUFFER_EVENT_ACCESS_READ:
423 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
425 ret = WIDGET_ACCESS_STATUS_ERROR;
428 memset(&action_info, 0, sizeof(action_info));
429 action_type = ELM_ACCESS_ACTION_READ;
430 action_info.x = event_info->info.access.x;
431 action_info.y = event_info->info.access.y;
432 action_info.mouse_type = event_info->info.access.mouse_type;
433 ret = elm_access_action(parent_elm, action_type, &action_info);
434 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
436 case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
437 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
439 ret = WIDGET_ACCESS_STATUS_ERROR;
442 memset(&action_info, 0, sizeof(action_info));
443 action_type = ELM_ACCESS_ACTION_ENABLE;
444 action_info.x = event_info->info.access.x;
445 action_info.y = event_info->info.access.y;
446 action_info.mouse_type = event_info->info.access.mouse_type;
447 ret = elm_access_action(parent_elm, action_type, &action_info);
448 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
450 case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
451 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
453 ret = WIDGET_ACCESS_STATUS_ERROR;
456 memset(&action_info, 0, sizeof(action_info));
457 action_type = ELM_ACCESS_ACTION_DISABLE;
458 action_info.x = event_info->info.access.x;
459 action_info.y = event_info->info.access.y;
460 action_info.mouse_type = event_info->info.access.mouse_type;
461 ret = elm_access_action(parent_elm, action_type, &action_info);
462 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
464 case WIDGET_BUFFER_EVENT_KEY_DOWN:
465 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
467 ret = WIDGET_ACCESS_STATUS_ERROR;
471 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
476 key_string = XKeysymToString(*key_symbol);
477 key_name = XKeysymToString(*key_symbol);
478 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
483 ret = WIDGET_KEY_STATUS_ERROR;
485 case WIDGET_BUFFER_EVENT_KEY_UP:
486 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
488 ret = WIDGET_ACCESS_STATUS_ERROR;
492 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
497 key_string = XKeysymToString(*key_symbol);
498 key_name = XKeysymToString(*key_symbol);
499 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
504 ret = WIDGET_KEY_STATUS_ERROR;
506 case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
507 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
509 ret = WIDGET_ACCESS_STATUS_ERROR;
513 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
518 key_string = XKeysymToString(*key_symbol);
519 key_name = XKeysymToString(*key_symbol);
520 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
525 ret = WIDGET_KEY_STATUS_ERROR;
527 case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
528 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
530 ret = WIDGET_ACCESS_STATUS_ERROR;
534 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
539 key_string = XKeysymToString(*key_symbol);
540 key_name = XKeysymToString(*key_symbol);
541 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
546 ret = WIDGET_KEY_STATUS_ERROR;
549 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
558 * This callback can be called twice (or more) to get a several pixmaps
559 * Acquired pixmaps are used for double/tripple buffering for canvas
561 static Ecore_X_Pixmap alloc_pixmap_cb(void *data, Ecore_X_Window parent, int w, int h, int depth)
563 vwin_info_t info = data;
564 Ecore_X_Pixmap pixmap;
567 ErrPrint("Invalid handle\n");
573 DbgPrint("Size of ee is updated: %dx%d - %d (info: %p)\n", info->w, info->h, depth, info);
576 if (widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER) == 0u) {
579 * Need to allocate a primary buffer
581 widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, depth);
583 ErrPrint("Failed to get the buffer\n");
587 pixmap = (Ecore_X_Pixmap)widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER);
588 } else if (WIDGET_CONF_EXTRA_BUFFER_COUNT > 0) {
591 if (!info->resource_array) {
592 info->resource_array = calloc(WIDGET_CONF_EXTRA_BUFFER_COUNT, sizeof(*info->resource_array));
593 if (!info->resource_array) {
594 ErrPrint("Out of memory: %s\n", strerror(errno));
600 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
601 if (info->resource_array[idx] == 0u) {
606 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
607 ErrPrint("Out of index: %d\n", idx);
612 if (widget_viewer_acquire_buffer(info->handle, idx, info->w, info->h, depth) < 0) {
613 ErrPrint("Failed to acquire a buffer for %d\n", idx);
617 info->resource_array[idx] = widget_viewer_get_resource_id(info->handle, idx);
618 if (info->resource_array[idx] == 0u) {
619 ErrPrint("Failed to allocate pixmap\n");
622 DbgPrint("Allocated index: %d/%d - %u\n", idx, WIDGET_CONF_EXTRA_BUFFER_COUNT, info->resource_array[idx]);
623 pixmap = info->resource_array[idx];
625 ErrPrint("Unable to allocate pixmap\n");
630 * Acquire a buffer for canvas.
632 info->type = VWIN_PIXMAP;
633 info->resource_cnt += !!(unsigned int)pixmap;
637 static void free_pixmap_cb(void *data, Ecore_X_Pixmap pixmap)
639 vwin_info_t info = data;
645 if (info->type != VWIN_PIXMAP) {
646 ErrPrint("Impossible\n");
649 if (widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER) == pixmap) {
650 if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
651 DbgPrint("Failed to release buffer\n");
653 info->resource_cnt--;
657 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
660 * Find a index to release it
662 if (info->resource_array[idx] == pixmap) {
663 if (widget_viewer_release_buffer(info->handle, idx) < 0) {
664 DbgPrint("Failed to release buffer\n");
666 info->resource_array[idx] = 0u;
667 info->resource_cnt--;
673 if (info->deleted && info->resource_cnt == 0) {
674 DbgPrint("Destroy buffer handle\n");
676 widget_destroy_buffer(info->handle);
677 free(info->resource_array);
683 static void *alloc_fb(void *data, int size)
685 vwin_info_t info = data;
689 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
690 DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
694 ErrPrint("Failed to create a buffer\n");
698 if (widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, sizeof(int)) < 0) {
699 ErrPrint("Failed to acquire buffer\n");
704 * If it supports the H/W accelerated buffer,
707 if (widget_support_hw_buffer(info->handle)) {
708 if (widget_create_hw_buffer(info->handle) == 0) {
709 buffer = widget_buffer_hw_buffer(info->handle);
711 DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
712 info->type = VWIN_GEM;
717 ErrPrint("Failed to allocate HW Accelerated buffer\n");
721 * Or use the buffer of a S/W backend.
723 buffer = widget_ref_buffer(info->handle);
724 DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
725 info->type = VWIN_SW_BUF;
729 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
733 buffer = alloc_fb(data, size);
735 vwin_info_t info = data;
739 _stride = widget_buffer_stride(info->handle);
741 _stride = info->w * *bpp;
746 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
752 static void free_fb(void *data, void *ptr)
754 vwin_info_t info = data;
760 if (info->type == VWIN_GEM) {
761 if (widget_destroy_hw_buffer(info->handle) == 0) {
762 DbgPrint("HW Accelerated buffer is destroyed\n");
764 } else if (info->type == VWIN_SW_BUF) {
765 DbgPrint("SW buffer is destroyed, %p\n", info);
766 widget_unref_buffer(ptr);
767 } else if (info->type == VWIN_PIXMAP) {
768 ErrPrint("Unable to reach to here\n");
771 if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
772 ErrPrint("Failed to release buffer\n");
776 widget_destroy_buffer(info->handle);
777 free(info->resource_array);
783 static void pre_render_cb(void *data, Evas *e, void *event_info)
785 vwin_info_t info = data;
791 if (widget_conf_premultiplied_alpha()) {
795 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
796 evas_damage_rectangle_add(e, 0, 0, w, h);
799 if (info->type == VWIN_GEM) {
800 widget_buffer_pre_render(info->handle);
801 } else if (info->type == VWIN_PIXMAP) {
803 * Only the pixmap type Ecore_Evas uses this variable
805 } else if (info->type == VWIN_SW_BUF) {
810 static void post_render_cb(void *data, Evas *e, void *event_info)
812 vwin_info_t info = data;
818 if (widget_conf_premultiplied_alpha()) {
822 // Get a pointer of a buffer of the virtual canvas
823 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
825 ErrPrint("Failed to get pixel canvas\n");
829 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
830 evas_data_argb_unpremul(canvas, w * h);
833 if (info->type == VWIN_GEM) {
834 widget_buffer_post_render(info->handle);
835 } else if (info->type == VWIN_PIXMAP) {
837 unsigned int front_resource_id;
839 front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
841 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
842 if (front_resource_id == info->resource_array[idx]) {
845 widget_send_updated_by_idx(info->handle, idx);
850 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
851 /* Send updated event for PRIMARY BUFFER */
852 if (front_resource_id == widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER)) {
853 widget_send_updated_by_idx(info->handle, WIDGET_PRIMARY_BUFFER);
855 DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER));
858 } else if (info->type == VWIN_SW_BUF) {
859 widget_viewer_sync_buffer(info->handle);
863 static void ecore_evas_free_cb(Ecore_Evas *ee)
867 info = ecore_evas_data_get(ee, "dynamic,box,info");
869 DbgPrint("Info is not valid\n");
874 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
875 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
882 PUBLIC void *widget_get_evas_object(const char *id, int is_gbar)
888 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
889 s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
890 if (!s_info.alloc_canvas_with_pixmap) {
891 DbgPrint("pixmap_allocfunc_new is not found\n");
894 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
895 if (!s_info.alloc_canvas_with_stride) {
896 DbgPrint("allocfunc_with_stirde_new is not found\n");
899 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
900 if (!s_info.alloc_canvas) {
901 ErrPrint("allocfunc_new is not found\n");
904 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
905 ErrPrint("No way to allocate canvas\n");
911 ErrPrint("Invalid parameter\n");
915 info = calloc(1, sizeof(*info));
917 ErrPrint("Heap: %s\n", strerror(errno));
921 info->id = strdup(id);
923 ErrPrint("Heap: %s\n", strerror(errno));
928 info->is_gbar = is_gbar;
931 * Acquire a buffer for canvas.
933 info->handle = widget_create_buffer(info->id, info->is_gbar,
934 (widget_conf_auto_align() || !s_info.alloc_canvas_with_stride),
935 event_handler_cb, info);
938 ErrPrint("Failed to create a widget buffer\n");
945 * Size information must be initialized before call the ecore_evas_buffer_new.
947 info->w = WIDGET_DEFAULT_WIDTH;
948 info->h = WIDGET_DEFAULT_HEIGHT;
950 engine = elm_config_preferred_engine_get();
951 DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
952 if (engine && !strcmp(engine, GL_ENGINE)) {
953 if (s_info.alloc_canvas_with_pixmap) {
954 info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
956 ErrPrint("Unable to create a ee for pixmap\n");
962 if (!widget_conf_auto_align() && s_info.alloc_canvas_with_stride) {
963 info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
964 } else if (s_info.alloc_canvas) {
965 info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
970 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
971 widget_destroy_buffer(info->handle);
977 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
981 * Free callback must be prepared before use the ecore_evas_free()
983 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
985 info->e = ecore_evas_get(info->ee);
987 ErrPrint("Failed to get evas\n");
988 ecore_evas_free(info->ee);
992 pre_render_cb(info, NULL, NULL);
993 ecore_evas_alpha_set(info->ee, EINA_TRUE);
994 post_render_cb(info, NULL, NULL);
996 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
997 ecore_evas_resize(info->ee, info->w, info->h);
999 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
1000 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
1002 rect = evas_object_rectangle_add(info->e);
1004 ErrPrint("Failed to create evas_object\n");
1005 ecore_evas_free(info->ee);
1009 evas_object_resize(rect, info->w, info->h);
1010 evas_object_color_set(rect, 0, 0, 0, 0);