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.
17 #include <Elementary.h>
19 #include <Ecore_Evas.h>
24 #include <widget_errno.h>
25 #include <widget_service.h>
32 #define PUBLIC __attribute__((visibility("default")))
33 #define WIDGET_WIN_TAG "dynamic,box,win"
35 #define WIDGET_DEFAULT_WIDTH 1
36 #define WIDGET_DEFAULT_HEIGHT 1
37 #define GL_ENGINE "opengl_x11"
39 static struct static_info {
40 Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
41 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);
42 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);
45 .alloc_canvas_with_stride = NULL,
46 .alloc_canvas_with_pixmap = NULL,
51 * Abstracted Data Type of Virtual Window
53 typedef struct virtual_window_info {
54 char *id; /**< Identification */
55 widget_buffer_h handle; /**< Livebox buffer handle */
57 VWIN_SW_BUF = 0x00, /**< S/W buffer */
58 VWIN_GEM = 0x01, /**< GEM buffer */
59 VWIN_PIXMAP = 0x02, /**< PIXMAP */
60 VWIN_ERROR = 0x03 /**< Unknown */
68 unsigned int *resource_array;
74 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
78 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
81 ho = evas_object_data_get(o, "_elm_access_target");
87 * Every user event (mouse) on the buffer will be passed via this event callback
89 static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_event_data *event_info, void *data)
91 vwin_info_t info = data;
92 Elm_Access_Action_Info action_info;
93 Elm_Access_Action_Type action_type;
95 Evas_Object *parent_elm;
96 unsigned int flags = 0;
101 /* Just ignore this event */
105 if (WIDGET_CONF_USE_GETTIMEOFDAY) {
106 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
109 if (gettimeofday(&tv, NULL) < 0) {
110 ErrPrint("gettimeofday: %s\n", strerror(errno));
112 timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
113 timestamp -= event_info->timestamp;
115 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
116 DbgPrint("Dropped %lf\n", timestamp);
123 * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
124 * Evas only use the monotic time for animating objects
126 timestamp = ecore_time_get() * 1000.0f;
128 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
129 timestamp = ecore_time_get();
131 timestamp -= event_info->timestamp;
132 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
133 DbgPrint("Dropped %lf\n", timestamp);
138 timestamp = event_info->timestamp * 1000.0f;
145 switch (event_info->type) {
146 case WIDGET_BUFFER_EVENT_ON_HOLD:
147 flags = evas_event_default_flags_get(info->e);
148 flags |= EVAS_EVENT_FLAG_ON_HOLD;
149 evas_event_default_flags_set(info->e, flags);
150 ErrPrint("ON_HOLD[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
152 case WIDGET_BUFFER_EVENT_OFF_HOLD:
153 flags = evas_event_default_flags_get(info->e);
154 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
155 evas_event_default_flags_set(info->e, flags);
157 case WIDGET_BUFFER_EVENT_ON_SCROLL:
158 flags = evas_event_default_flags_get(info->e);
159 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
160 evas_event_default_flags_set(info->e, flags);
162 case WIDGET_BUFFER_EVENT_OFF_SCROLL:
163 flags = evas_event_default_flags_get(info->e);
164 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
165 evas_event_default_flags_set(info->e, flags);
167 case WIDGET_BUFFER_EVENT_ENTER:
168 evas_event_feed_mouse_in(info->e, timestamp, NULL);
170 case WIDGET_BUFFER_EVENT_LEAVE:
171 evas_event_feed_mouse_out(info->e, timestamp, NULL);
173 case WIDGET_BUFFER_EVENT_DOWN:
175 ErrPrint("MOUSE UP is not called\n");
176 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
177 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
178 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
183 * Before processing the DOWN event,
184 * Reset the evas event flags regarding ON_HOLD option.
185 * It can be re-enabled while processing down-move-up events.
187 flags = evas_event_default_flags_get(info->e);
188 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
189 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
190 evas_event_default_flags_set(info->e, flags);
193 * Calculate the event occurred X & Y on the buffer
195 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
196 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
198 ErrPrint("DOWN[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
200 case WIDGET_BUFFER_EVENT_MOVE:
203 * Calculate the event occurred X & Y on the buffer
205 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
207 case WIDGET_BUFFER_EVENT_UP:
208 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
209 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
213 * We have to keep the event flags, so we should not clear them from here.
214 * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
215 * so if we reset them from here, those kind of callbacks will fails to do their job properly.
217 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
219 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
220 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
222 ret = WIDGET_ACCESS_STATUS_ERROR;
225 memset(&action_info, 0, sizeof(action_info));
226 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
229 * Calculate the event occurred X & Y on the buffer
231 action_info.x = event_info->info.access.x;
232 action_info.y = event_info->info.access.y;
233 ret = elm_access_action(parent_elm, action_type, &action_info);
234 if (ret == EINA_TRUE) {
235 if (!get_highlighted_object(parent_elm)) {
236 ErrPrint("Highlighted object is not found\n");
237 ret = WIDGET_ACCESS_STATUS_ERROR;
239 DbgPrint("Highlighted object is found\n");
240 ret = WIDGET_ACCESS_STATUS_DONE;
243 ErrPrint("Action error\n");
244 ret = WIDGET_ACCESS_STATUS_ERROR;
247 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
248 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
250 ret = WIDGET_ACCESS_STATUS_ERROR;
253 memset(&action_info, 0, sizeof(action_info));
254 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
255 action_info.highlight_cycle = EINA_FALSE;
256 ret = elm_access_action(parent_elm, action_type, &action_info);
257 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
259 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
260 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
262 ret = WIDGET_ACCESS_STATUS_ERROR;
265 memset(&action_info, 0, sizeof(action_info));
266 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
267 action_info.highlight_cycle = EINA_FALSE;
268 ret = elm_access_action(parent_elm, action_type, &action_info);
269 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
271 case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
272 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
274 ret = WIDGET_ACCESS_STATUS_ERROR;
277 memset(&action_info, 0, sizeof(action_info));
278 action_type = ELM_ACCESS_ACTION_ACTIVATE;
279 ret = elm_access_action(parent_elm, action_type, &action_info);
280 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
282 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
283 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
285 ret = WIDGET_ACCESS_STATUS_ERROR;
288 memset(&action_info, 0, sizeof(action_info));
289 action_type = ELM_ACCESS_ACTION_UP;
290 ret = elm_access_action(parent_elm, action_type, &action_info);
291 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
293 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
294 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
296 ret = WIDGET_ACCESS_STATUS_ERROR;
299 memset(&action_info, 0, sizeof(action_info));
300 action_type = ELM_ACCESS_ACTION_DOWN;
301 ret = elm_access_action(parent_elm, action_type, &action_info);
302 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
304 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
305 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
307 ret = WIDGET_ACCESS_STATUS_ERROR;
310 memset(&action_info, 0, sizeof(action_info));
311 action_type = ELM_ACCESS_ACTION_SCROLL;
312 action_info.x = event_info->info.access.x;
313 action_info.y = event_info->info.access.y;
314 action_info.mouse_type = event_info->info.access.mouse_type;
315 ret = elm_access_action(parent_elm, action_type, &action_info);
316 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
318 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
319 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
321 ret = WIDGET_ACCESS_STATUS_ERROR;
324 memset(&action_info, 0, sizeof(action_info));
325 action_type = ELM_ACCESS_ACTION_SCROLL;
326 action_info.x = event_info->info.access.x;
327 action_info.y = event_info->info.access.y;
328 action_info.mouse_type = event_info->info.access.mouse_type;
329 ret = elm_access_action(parent_elm, action_type, &action_info);
330 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
332 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
333 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
335 ret = WIDGET_ACCESS_STATUS_ERROR;
338 memset(&action_info, 0, sizeof(action_info));
339 action_type = ELM_ACCESS_ACTION_SCROLL;
340 action_info.x = event_info->info.access.x;
341 action_info.y = event_info->info.access.y;
342 action_info.mouse_type = event_info->info.access.mouse_type;
343 ret = elm_access_action(parent_elm, action_type, &action_info);
344 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
346 case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
347 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
349 ret = WIDGET_ACCESS_STATUS_ERROR;
352 memset(&action_info, 0, sizeof(action_info));
353 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
354 ret = elm_access_action(parent_elm, action_type, &action_info);
355 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
357 case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
358 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
360 ret = WIDGET_ACCESS_STATUS_ERROR;
363 memset(&action_info, 0, sizeof(action_info));
364 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
365 action_info.x = event_info->info.access.x;
366 action_info.y = event_info->info.access.y;
367 action_info.mouse_type = event_info->info.access.mouse_type;
368 ret = elm_access_action(parent_elm, action_type, &action_info);
369 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
371 case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
372 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
374 ret = WIDGET_ACCESS_STATUS_ERROR;
377 memset(&action_info, 0, sizeof(action_info));
378 action_type = ELM_ACCESS_ACTION_MOUSE;
379 action_info.x = event_info->info.access.x;
380 action_info.y = event_info->info.access.y;
381 action_info.mouse_type = event_info->info.access.mouse_type;
382 ret = elm_access_action(parent_elm, action_type, &action_info);
383 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
385 case WIDGET_BUFFER_EVENT_ACCESS_BACK:
386 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
388 ret = WIDGET_ACCESS_STATUS_ERROR;
391 memset(&action_info, 0, sizeof(action_info));
392 action_type = ELM_ACCESS_ACTION_BACK;
393 action_info.x = event_info->info.access.x;
394 action_info.y = event_info->info.access.y;
395 action_info.mouse_type = event_info->info.access.mouse_type;
396 ret = elm_access_action(parent_elm, action_type, &action_info);
397 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
399 case WIDGET_BUFFER_EVENT_ACCESS_OVER:
400 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
402 ret = WIDGET_ACCESS_STATUS_ERROR;
405 memset(&action_info, 0, sizeof(action_info));
406 action_type = ELM_ACCESS_ACTION_OVER;
407 action_info.x = event_info->info.access.x;
408 action_info.y = event_info->info.access.y;
409 action_info.mouse_type = event_info->info.access.mouse_type;
410 ret = elm_access_action(parent_elm, action_type, &action_info);
411 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
413 case WIDGET_BUFFER_EVENT_ACCESS_READ:
414 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
416 ret = WIDGET_ACCESS_STATUS_ERROR;
419 memset(&action_info, 0, sizeof(action_info));
420 action_type = ELM_ACCESS_ACTION_READ;
421 action_info.x = event_info->info.access.x;
422 action_info.y = event_info->info.access.y;
423 action_info.mouse_type = event_info->info.access.mouse_type;
424 ret = elm_access_action(parent_elm, action_type, &action_info);
425 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
427 case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
428 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
430 ret = WIDGET_ACCESS_STATUS_ERROR;
433 memset(&action_info, 0, sizeof(action_info));
434 action_type = ELM_ACCESS_ACTION_ENABLE;
435 action_info.x = event_info->info.access.x;
436 action_info.y = event_info->info.access.y;
437 action_info.mouse_type = event_info->info.access.mouse_type;
438 ret = elm_access_action(parent_elm, action_type, &action_info);
439 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
441 case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
442 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
444 ret = WIDGET_ACCESS_STATUS_ERROR;
447 memset(&action_info, 0, sizeof(action_info));
448 action_type = ELM_ACCESS_ACTION_DISABLE;
449 action_info.x = event_info->info.access.x;
450 action_info.y = event_info->info.access.y;
451 action_info.mouse_type = event_info->info.access.mouse_type;
452 ret = elm_access_action(parent_elm, action_type, &action_info);
453 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
455 case WIDGET_BUFFER_EVENT_KEY_DOWN:
456 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
458 ret = WIDGET_ACCESS_STATUS_ERROR;
462 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
467 key_string = XKeysymToString(*key_symbol);
468 key_name = XKeysymToString(*key_symbol);
469 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
474 ret = WIDGET_KEY_STATUS_ERROR;
476 case WIDGET_BUFFER_EVENT_KEY_UP:
477 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
479 ret = WIDGET_ACCESS_STATUS_ERROR;
483 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
488 key_string = XKeysymToString(*key_symbol);
489 key_name = XKeysymToString(*key_symbol);
490 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
495 ret = WIDGET_KEY_STATUS_ERROR;
497 case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
498 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
500 ret = WIDGET_ACCESS_STATUS_ERROR;
504 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
509 key_string = XKeysymToString(*key_symbol);
510 key_name = XKeysymToString(*key_symbol);
511 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
516 ret = WIDGET_KEY_STATUS_ERROR;
518 case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
519 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
521 ret = WIDGET_ACCESS_STATUS_ERROR;
525 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
530 key_string = XKeysymToString(*key_symbol);
531 key_name = XKeysymToString(*key_symbol);
532 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
537 ret = WIDGET_KEY_STATUS_ERROR;
540 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
547 static void *alloc_fb(void *data, int size)
549 vwin_info_t info = data;
553 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
554 DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
558 ErrPrint("Failed to create a buffer\n");
562 if (widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, sizeof(int)) < 0) {
563 ErrPrint("Failed to acquire buffer\n");
568 * If it supports the H/W accelerated buffer,
571 if (widget_support_hw_buffer(info->handle)) {
572 if (widget_create_hw_buffer(info->handle) == 0) {
573 buffer = widget_buffer_hw_buffer(info->handle);
575 DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
576 info->type = VWIN_GEM;
581 ErrPrint("Failed to allocate HW Accelerated buffer\n");
585 * Or use the buffer of a S/W backend.
587 buffer = widget_ref_buffer(info->handle);
588 DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
589 info->type = VWIN_SW_BUF;
593 static void free_fb(void *data, void *ptr)
595 vwin_info_t info = data;
601 if (info->type == VWIN_GEM) {
602 if (widget_destroy_hw_buffer(info->handle) == 0) {
603 DbgPrint("HW Accelerated buffer is destroyed\n");
605 } else if (info->type == VWIN_SW_BUF) {
606 DbgPrint("SW buffer is destroyed, %p\n", info);
607 widget_unref_buffer(ptr);
608 } else if (info->type == VWIN_PIXMAP) {
609 ErrPrint("Unable to reach to here\n");
612 if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
613 ErrPrint("Failed to release buffer\n");
617 widget_destroy_buffer(info->handle);
618 free(info->resource_array);
624 static void pre_render_cb(void *data, Evas *e, void *event_info)
626 vwin_info_t info = data;
632 if (widget_conf_premultiplied_alpha()) {
636 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
637 evas_damage_rectangle_add(e, 0, 0, w, h);
640 if (info->type == VWIN_GEM) {
641 widget_buffer_pre_render(info->handle);
642 } else if (info->type == VWIN_PIXMAP) {
644 * Only the pixmap type Ecore_Evas uses this variable
646 } else if (info->type == VWIN_SW_BUF) {
651 static void post_render_cb(void *data, Evas *e, void *event_info)
653 vwin_info_t info = data;
659 if (widget_conf_premultiplied_alpha()) {
663 // Get a pointer of a buffer of the virtual canvas
664 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
666 ErrPrint("Failed to get pixel canvas\n");
670 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
671 evas_data_argb_unpremul(canvas, w * h);
674 if (info->type == VWIN_GEM) {
675 widget_buffer_post_render(info->handle);
676 } else if (info->type == VWIN_PIXMAP) {
678 unsigned int front_resource_id;
680 front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
682 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
683 if (front_resource_id == info->resource_array[idx]) {
686 widget_send_updated_by_idx(info->handle, idx);
691 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
692 /* Send updated event for PRIMARY BUFFER */
693 if (front_resource_id == widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER)) {
694 widget_send_updated_by_idx(info->handle, WIDGET_PRIMARY_BUFFER);
696 DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER));
699 } else if (info->type == VWIN_SW_BUF) {
700 widget_viewer_sync_buffer(info->handle);
704 static void pre_destroy_cb(const char *id, void *data)
706 vwin_info_t info = data;
708 if (id && strcmp(info->id, widget_util_uri_to_path(id))) {
710 DbgPrint("SKIP: Pre destroy event callback is called [%s], %s\n", id, info->id);
714 DbgPrint("Pre destroy event callback is called [%s]\n", id);
717 DbgPrint("Toggle manual render mode to prevent from unwanted rendering");
718 ecore_evas_manual_render_set(info->ee, EINA_TRUE);
722 static void ecore_evas_free_cb(Ecore_Evas *ee)
726 info = ecore_evas_data_get(ee, "dynamic,box,info");
728 DbgPrint("Info is not valid\n");
732 widget_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
735 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
736 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
743 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
744 PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
745 #else /* WIDGET_FEATURE_GBAR_SUPPORTED */
746 PUBLIC Evas *widget_get_evas(const char *id)
747 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
755 * If the evas object is already created,
756 * this function should returns ERROR.
759 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
761 s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
762 if (!s_info.alloc_canvas_with_pixmap) {
763 DbgPrint("pixmap_allocfunc_new is not found\n");
767 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
768 if (!s_info.alloc_canvas_with_stride) {
769 DbgPrint("allocfunc_with_stirde_new is not found\n");
772 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
773 if (!s_info.alloc_canvas) {
774 ErrPrint("allocfunc_new is not found\n");
777 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
778 ErrPrint("No way to allocate canvas\n");
784 ErrPrint("Invalid parameter\n");
788 info = calloc(1, sizeof(*info));
790 ErrPrint("Heap: %d\n", errno);
794 info->id = strdup(id);
796 ErrPrint("Heap: %d\n", errno);
801 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
802 info->is_gbar = is_gbar;
805 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
808 * Acquire a buffer for canvas.
810 info->handle = widget_create_buffer(info->id, info->is_gbar,
811 (widget_conf_auto_align() || !s_info.alloc_canvas_with_stride),
812 event_handler_cb, info);
815 ErrPrint("Failed to create a widget buffer\n");
822 * Size information must be initialized before call the ecore_evas_buffer_new.
824 info->w = WIDGET_DEFAULT_WIDTH;
825 info->h = WIDGET_DEFAULT_HEIGHT;
827 engine = elm_config_preferred_engine_get();
828 DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
829 if (engine && !strcmp(engine, GL_ENGINE)) {
830 if (s_info.alloc_canvas_with_pixmap) {
831 info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
833 ErrPrint("Unable to create a ee for pixmap\n");
839 if (!widget_conf_auto_align() && s_info.alloc_canvas_with_stride) {
840 info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
841 } else if (s_info.alloc_canvas) {
842 info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
847 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
848 widget_destroy_buffer(info->handle);
854 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
858 * Free callback must be prepared before use the ecore_evas_free()
860 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
862 info->e = ecore_evas_get(info->ee);
864 ErrPrint("Failed to get evas\n");
865 ecore_evas_free(info->ee);
869 pre_render_cb(info, NULL, NULL);
870 ecore_evas_alpha_set(info->ee, EINA_TRUE);
871 post_render_cb(info, NULL, NULL);
873 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
874 ecore_evas_resize(info->ee, info->w, info->h);
876 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
877 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
879 widget_add_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);