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_service_internal.h>
33 #include <widget_conf.h>
34 #include <widget_buffer.h>
35 #include <widget_provider.h>
36 #include <widget_util.h>
39 #include "widget_internal.h"
44 #define PUBLIC __attribute__((visibility("default")))
45 #define WIDGET_WIN_TAG "dynamic,box,win"
47 #define WIDGET_DEFAULT_WIDTH 1
48 #define WIDGET_DEFAULT_HEIGHT 1
49 #define GL_ENGINE "opengl_x11"
51 static struct static_info {
52 Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
53 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);
54 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);
57 .alloc_canvas_with_stride = NULL,
58 .alloc_canvas_with_pixmap = NULL,
63 * Abstracted Data Type of Virtual Window
65 typedef struct virtual_window_info {
66 char *id; /**< Identification */
67 widget_buffer_h handle; /**< Livebox buffer handle */
69 VWIN_SW_BUF = 0x00, /**< S/W buffer */
70 VWIN_GEM = 0x01, /**< GEM buffer */
71 VWIN_PIXMAP = 0x02, /**< PIXMAP */
72 VWIN_ERROR = 0x03 /**< Unknown */
80 unsigned int *resource_array;
86 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
90 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
93 ho = evas_object_data_get(o, "_elm_access_target");
99 * Every user event (mouse) on the buffer will be passed via this event callback
101 static int event_handler_cb(widget_buffer_h handler, struct widget_buffer_event_data *event_info, void *data)
103 vwin_info_t info = data;
104 Elm_Access_Action_Info action_info;
105 Elm_Access_Action_Type action_type;
107 Evas_Object *parent_elm;
109 unsigned int flags = 0;
113 /* Just ignore this event */
117 if (WIDGET_CONF_USE_GETTIMEOFDAY) {
118 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
121 if (gettimeofday(&tv, NULL) < 0) {
122 ErrPrint("gettimeofday: %d\n", errno);
124 timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
125 timestamp -= event_info->timestamp;
127 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
128 DbgPrint("Dropped %lf\n", timestamp);
135 * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
136 * Evas only use the monotic time for animating objects
138 timestamp = ecore_time_get() * 1000.0f;
140 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
141 timestamp = ecore_time_get();
143 timestamp -= event_info->timestamp;
144 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
145 DbgPrint("Dropped %lf\n", timestamp);
150 timestamp = event_info->timestamp * 1000.0f;
157 switch (event_info->type) {
158 case WIDGET_BUFFER_EVENT_ON_HOLD:
159 flags = evas_event_default_flags_get(info->e);
160 flags |= EVAS_EVENT_FLAG_ON_HOLD;
161 evas_event_default_flags_set(info->e, flags);
162 ErrPrint("ON_HOLD[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
164 case WIDGET_BUFFER_EVENT_OFF_HOLD:
165 flags = evas_event_default_flags_get(info->e);
166 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
167 evas_event_default_flags_set(info->e, flags);
169 case WIDGET_BUFFER_EVENT_ON_SCROLL:
170 flags = evas_event_default_flags_get(info->e);
171 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
172 evas_event_default_flags_set(info->e, flags);
174 case WIDGET_BUFFER_EVENT_OFF_SCROLL:
175 flags = evas_event_default_flags_get(info->e);
176 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
177 evas_event_default_flags_set(info->e, flags);
179 case WIDGET_BUFFER_EVENT_ENTER:
180 evas_event_feed_mouse_in(info->e, timestamp, NULL);
182 case WIDGET_BUFFER_EVENT_LEAVE:
183 evas_event_feed_mouse_out(info->e, timestamp, NULL);
185 case WIDGET_BUFFER_EVENT_DOWN:
187 ErrPrint("MOUSE UP is not called\n");
188 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
189 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
190 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
195 * Before processing the DOWN event,
196 * Reset the evas event flags regarding ON_HOLD option.
197 * It can be re-enabled while processing down-move-up events.
199 flags = evas_event_default_flags_get(info->e);
200 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
201 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
202 evas_event_default_flags_set(info->e, flags);
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);
208 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
210 ErrPrint("DOWN[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
212 case WIDGET_BUFFER_EVENT_MOVE:
215 * Calculate the event occurred X & Y on the buffer
217 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
219 case WIDGET_BUFFER_EVENT_UP:
220 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
221 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
225 * We have to keep the event flags, so we should not clear them from here.
226 * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
227 * so if we reset them from here, those kind of callbacks will fails to do their job properly.
229 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
231 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
232 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
234 ret = WIDGET_ACCESS_STATUS_ERROR;
237 memset(&action_info, 0, sizeof(action_info));
238 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
241 * Calculate the event occurred X & Y on the buffer
243 action_info.x = event_info->info.access.x;
244 action_info.y = event_info->info.access.y;
245 ret = elm_access_action(parent_elm, action_type, &action_info);
246 if (ret == EINA_TRUE) {
247 if (!get_highlighted_object(parent_elm)) {
248 ErrPrint("Highlighted object is not found\n");
249 ret = WIDGET_ACCESS_STATUS_ERROR;
251 DbgPrint("Highlighted object is found\n");
252 ret = WIDGET_ACCESS_STATUS_DONE;
255 ErrPrint("Action error\n");
256 ret = WIDGET_ACCESS_STATUS_ERROR;
259 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
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_NEXT;
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_LAST : WIDGET_ACCESS_STATUS_DONE;
271 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
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_HIGHLIGHT_PREV;
279 action_info.highlight_cycle = EINA_FALSE;
280 ret = elm_access_action(parent_elm, action_type, &action_info);
281 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
283 case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
284 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
286 ret = WIDGET_ACCESS_STATUS_ERROR;
289 memset(&action_info, 0, sizeof(action_info));
290 action_type = ELM_ACCESS_ACTION_ACTIVATE;
291 ret = elm_access_action(parent_elm, action_type, &action_info);
292 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
294 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
295 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
297 ret = WIDGET_ACCESS_STATUS_ERROR;
300 memset(&action_info, 0, sizeof(action_info));
301 action_type = ELM_ACCESS_ACTION_UP;
302 ret = elm_access_action(parent_elm, action_type, &action_info);
303 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
305 case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
306 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
308 ret = WIDGET_ACCESS_STATUS_ERROR;
311 memset(&action_info, 0, sizeof(action_info));
312 action_type = ELM_ACCESS_ACTION_DOWN;
313 ret = elm_access_action(parent_elm, action_type, &action_info);
314 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
316 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
317 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
319 ret = WIDGET_ACCESS_STATUS_ERROR;
322 memset(&action_info, 0, sizeof(action_info));
323 action_type = ELM_ACCESS_ACTION_SCROLL;
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) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
330 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
331 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
333 ret = WIDGET_ACCESS_STATUS_ERROR;
336 memset(&action_info, 0, sizeof(action_info));
337 action_type = ELM_ACCESS_ACTION_SCROLL;
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) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
344 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
345 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
347 ret = WIDGET_ACCESS_STATUS_ERROR;
350 memset(&action_info, 0, sizeof(action_info));
351 action_type = ELM_ACCESS_ACTION_SCROLL;
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) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
358 case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
359 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
361 ret = WIDGET_ACCESS_STATUS_ERROR;
364 memset(&action_info, 0, sizeof(action_info));
365 action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
366 ret = elm_access_action(parent_elm, action_type, &action_info);
367 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
369 case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
370 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
372 ret = WIDGET_ACCESS_STATUS_ERROR;
375 memset(&action_info, 0, sizeof(action_info));
376 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
377 action_info.x = event_info->info.access.x;
378 action_info.y = event_info->info.access.y;
379 action_info.mouse_type = event_info->info.access.mouse_type;
380 ret = elm_access_action(parent_elm, action_type, &action_info);
381 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
383 case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
384 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
386 ret = WIDGET_ACCESS_STATUS_ERROR;
389 memset(&action_info, 0, sizeof(action_info));
390 action_type = ELM_ACCESS_ACTION_MOUSE;
391 action_info.x = event_info->info.access.x;
392 action_info.y = event_info->info.access.y;
393 action_info.mouse_type = event_info->info.access.mouse_type;
394 ret = elm_access_action(parent_elm, action_type, &action_info);
395 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
397 case WIDGET_BUFFER_EVENT_ACCESS_BACK:
398 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
400 ret = WIDGET_ACCESS_STATUS_ERROR;
403 memset(&action_info, 0, sizeof(action_info));
404 action_type = ELM_ACCESS_ACTION_BACK;
405 action_info.x = event_info->info.access.x;
406 action_info.y = event_info->info.access.y;
407 action_info.mouse_type = event_info->info.access.mouse_type;
408 ret = elm_access_action(parent_elm, action_type, &action_info);
409 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
411 case WIDGET_BUFFER_EVENT_ACCESS_OVER:
412 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
414 ret = WIDGET_ACCESS_STATUS_ERROR;
417 memset(&action_info, 0, sizeof(action_info));
418 action_type = ELM_ACCESS_ACTION_OVER;
419 action_info.x = event_info->info.access.x;
420 action_info.y = event_info->info.access.y;
421 action_info.mouse_type = event_info->info.access.mouse_type;
422 ret = elm_access_action(parent_elm, action_type, &action_info);
423 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
425 case WIDGET_BUFFER_EVENT_ACCESS_READ:
426 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
428 ret = WIDGET_ACCESS_STATUS_ERROR;
431 memset(&action_info, 0, sizeof(action_info));
432 action_type = ELM_ACCESS_ACTION_READ;
433 action_info.x = event_info->info.access.x;
434 action_info.y = event_info->info.access.y;
435 action_info.mouse_type = event_info->info.access.mouse_type;
436 ret = elm_access_action(parent_elm, action_type, &action_info);
437 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
439 case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
440 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
442 ret = WIDGET_ACCESS_STATUS_ERROR;
445 memset(&action_info, 0, sizeof(action_info));
446 action_type = ELM_ACCESS_ACTION_ENABLE;
447 action_info.x = event_info->info.access.x;
448 action_info.y = event_info->info.access.y;
449 action_info.mouse_type = event_info->info.access.mouse_type;
450 ret = elm_access_action(parent_elm, action_type, &action_info);
451 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
453 case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
454 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
456 ret = WIDGET_ACCESS_STATUS_ERROR;
459 memset(&action_info, 0, sizeof(action_info));
460 action_type = ELM_ACCESS_ACTION_DISABLE;
461 action_info.x = event_info->info.access.x;
462 action_info.y = event_info->info.access.y;
463 action_info.mouse_type = event_info->info.access.mouse_type;
464 ret = elm_access_action(parent_elm, action_type, &action_info);
465 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
467 case WIDGET_BUFFER_EVENT_KEY_DOWN:
468 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
470 ret = WIDGET_ACCESS_STATUS_ERROR;
474 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
479 key_string = XKeysymToString(*key_symbol);
480 key_name = XKeysymToString(*key_symbol);
481 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
486 ret = WIDGET_KEY_STATUS_ERROR;
488 case WIDGET_BUFFER_EVENT_KEY_UP:
489 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
491 ret = WIDGET_ACCESS_STATUS_ERROR;
495 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
500 key_string = XKeysymToString(*key_symbol);
501 key_name = XKeysymToString(*key_symbol);
502 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
507 ret = WIDGET_KEY_STATUS_ERROR;
509 case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
510 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
512 ret = WIDGET_ACCESS_STATUS_ERROR;
516 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
521 key_string = XKeysymToString(*key_symbol);
522 key_name = XKeysymToString(*key_symbol);
523 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
528 ret = WIDGET_KEY_STATUS_ERROR;
530 case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
531 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
533 ret = WIDGET_ACCESS_STATUS_ERROR;
537 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
542 key_string = XKeysymToString(*key_symbol);
543 key_name = XKeysymToString(*key_symbol);
544 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
549 ret = WIDGET_KEY_STATUS_ERROR;
552 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
561 * This callback can be called twice (or more) to get a several pixmaps
562 * Acquired pixmaps are used for double/tripple buffering for canvas
564 static Ecore_X_Pixmap alloc_pixmap_cb(void *data, Ecore_X_Window parent, int w, int h, int depth)
566 vwin_info_t info = data;
567 Ecore_X_Pixmap pixmap;
570 ErrPrint("Invalid handle\n");
576 DbgPrint("Size of ee is updated: %dx%d - %d (info: %p)\n", info->w, info->h, depth, info);
579 if (widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER) == 0u) {
582 * Need to allocate a primary buffer
584 widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, depth);
586 ErrPrint("Failed to get the buffer\n");
590 pixmap = (Ecore_X_Pixmap)widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER);
591 } else if (WIDGET_CONF_EXTRA_BUFFER_COUNT > 0) {
594 if (!info->resource_array) {
595 info->resource_array = calloc(WIDGET_CONF_EXTRA_BUFFER_COUNT, sizeof(*info->resource_array));
596 if (!info->resource_array) {
597 ErrPrint("Out of memory: %d\n", errno);
603 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
604 if (info->resource_array[idx] == 0u) {
609 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
610 ErrPrint("Out of index: %d\n", idx);
615 if (widget_viewer_acquire_buffer(info->handle, idx, info->w, info->h, depth) < 0) {
616 ErrPrint("Failed to acquire a buffer for %d\n", idx);
620 info->resource_array[idx] = widget_viewer_get_resource_id(info->handle, idx);
621 if (info->resource_array[idx] == 0u) {
622 ErrPrint("Failed to allocate pixmap\n");
625 DbgPrint("Allocated index: %d/%d - %u\n", idx, WIDGET_CONF_EXTRA_BUFFER_COUNT, info->resource_array[idx]);
626 pixmap = info->resource_array[idx];
628 ErrPrint("Unable to allocate pixmap\n");
633 * Acquire a buffer for canvas.
635 info->type = VWIN_PIXMAP;
636 info->resource_cnt += !!(unsigned int)pixmap;
640 static void free_pixmap_cb(void *data, Ecore_X_Pixmap pixmap)
642 vwin_info_t info = data;
648 if (info->type != VWIN_PIXMAP) {
649 ErrPrint("Impossible\n");
652 if (widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER) == pixmap) {
653 if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
654 DbgPrint("Failed to release buffer\n");
656 info->resource_cnt--;
660 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
663 * Find a index to release it
665 if (info->resource_array[idx] == pixmap) {
666 if (widget_viewer_release_buffer(info->handle, idx) < 0) {
667 DbgPrint("Failed to release buffer\n");
669 info->resource_array[idx] = 0u;
670 info->resource_cnt--;
676 if (info->deleted && info->resource_cnt == 0) {
677 DbgPrint("Destroy buffer handle\n");
679 widget_destroy_buffer(info->handle);
680 free(info->resource_array);
686 static void *alloc_fb(void *data, int size)
688 vwin_info_t info = data;
692 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
693 DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
697 ErrPrint("Failed to create a buffer\n");
701 if (widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, sizeof(int)) < 0) {
702 ErrPrint("Failed to acquire buffer\n");
707 * If it supports the H/W accelerated buffer,
710 if (widget_support_hw_buffer(info->handle)) {
711 if (widget_create_hw_buffer(info->handle) == 0) {
712 buffer = widget_buffer_hw_buffer(info->handle);
714 DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
715 info->type = VWIN_GEM;
720 ErrPrint("Failed to allocate HW Accelerated buffer\n");
724 * Or use the buffer of a S/W backend.
726 buffer = widget_ref_buffer(info->handle);
727 DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
728 info->type = VWIN_SW_BUF;
732 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
736 buffer = alloc_fb(data, size);
738 vwin_info_t info = data;
742 _stride = widget_buffer_stride(info->handle);
744 _stride = info->w * *bpp;
749 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
755 static void free_fb(void *data, void *ptr)
757 vwin_info_t info = data;
763 if (info->type == VWIN_GEM) {
764 if (widget_destroy_hw_buffer(info->handle) == 0) {
765 DbgPrint("HW Accelerated buffer is destroyed\n");
767 } else if (info->type == VWIN_SW_BUF) {
768 DbgPrint("SW buffer is destroyed, %p\n", info);
769 widget_unref_buffer(ptr);
770 } else if (info->type == VWIN_PIXMAP) {
771 ErrPrint("Unable to reach to here\n");
774 if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
775 ErrPrint("Failed to release buffer\n");
779 widget_destroy_buffer(info->handle);
780 free(info->resource_array);
786 static void pre_render_cb(void *data, Evas *e, void *event_info)
788 vwin_info_t info = data;
794 if (widget_conf_premultiplied_alpha()) {
798 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
799 evas_damage_rectangle_add(e, 0, 0, w, h);
802 if (info->type == VWIN_GEM) {
803 widget_buffer_pre_render(info->handle);
804 } else if (info->type == VWIN_PIXMAP) {
806 * Only the pixmap type Ecore_Evas uses this variable
808 } else if (info->type == VWIN_SW_BUF) {
813 static void post_render_cb(void *data, Evas *e, void *event_info)
815 vwin_info_t info = data;
821 if (widget_conf_premultiplied_alpha()) {
825 // Get a pointer of a buffer of the virtual canvas
826 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
828 ErrPrint("Failed to get pixel canvas\n");
832 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
833 evas_data_argb_unpremul(canvas, w * h);
836 if (info->type == VWIN_GEM) {
837 widget_buffer_post_render(info->handle);
838 } else if (info->type == VWIN_PIXMAP) {
840 unsigned int front_resource_id;
842 front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
844 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
845 if (front_resource_id == info->resource_array[idx]) {
848 widget_send_updated_by_idx(info->handle, idx);
853 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
854 /* Send updated event for PRIMARY BUFFER */
855 if (front_resource_id == widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER)) {
856 widget_send_updated_by_idx(info->handle, WIDGET_PRIMARY_BUFFER);
858 DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER));
861 } else if (info->type == VWIN_SW_BUF) {
862 widget_viewer_sync_buffer(info->handle);
866 static void pre_destroy_cb(const char *id, void *data)
868 vwin_info_t info = data;
872 path = widget_util_uri_to_path(id);
874 if (path && strcmp(info->id, path)) {
876 DbgPrint("SKIP: Pre destroy event callback is called [%s], %s\n", id, info->id);
881 DbgPrint("Pre destroy event callback is called [%s]\n", id);
884 DbgPrint("Toggle manual render mode to prevent from unwanted rendering");
885 ecore_evas_manual_render_set(info->ee, EINA_TRUE);
889 static void ecore_evas_free_cb(Ecore_Evas *ee)
893 info = ecore_evas_data_get(ee, "dynamic,box,info");
895 DbgPrint("Info is not valid\n");
899 widget_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
902 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
903 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
910 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
911 PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
912 #else /* WIDGET_FEATURE_GBAR_SUPPORTED */
913 PUBLIC Evas *widget_get_evas(const char *id)
914 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
922 * If the evas object is already created,
923 * this function should returns ERROR.
926 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
927 s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
928 if (!s_info.alloc_canvas_with_pixmap) {
929 DbgPrint("pixmap_allocfunc_new is not found\n");
932 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
933 if (!s_info.alloc_canvas_with_stride) {
934 DbgPrint("allocfunc_with_stirde_new is not found\n");
937 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
938 if (!s_info.alloc_canvas) {
939 ErrPrint("allocfunc_new is not found\n");
942 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
943 ErrPrint("No way to allocate canvas\n");
949 ErrPrint("Invalid parameter\n");
953 info = calloc(1, sizeof(*info));
955 ErrPrint("Heap: %d\n", errno);
959 info->id = strdup(id);
961 ErrPrint("Heap: %d\n", errno);
966 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
967 info->is_gbar = is_gbar;
970 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
973 * Acquire a buffer for canvas.
975 info->handle = widget_create_buffer(info->id, info->is_gbar,
976 (widget_conf_auto_align() || !s_info.alloc_canvas_with_stride),
977 event_handler_cb, info);
980 ErrPrint("Failed to create a widget buffer\n");
987 * Size information must be initialized before call the ecore_evas_buffer_new.
989 info->w = WIDGET_DEFAULT_WIDTH;
990 info->h = WIDGET_DEFAULT_HEIGHT;
992 engine = elm_config_preferred_engine_get();
993 DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
994 if (engine && !strcmp(engine, GL_ENGINE)) {
995 if (s_info.alloc_canvas_with_pixmap) {
996 info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
998 ErrPrint("Unable to create a ee for pixmap\n");
1004 if (!widget_conf_auto_align() && s_info.alloc_canvas_with_stride) {
1005 info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
1006 } else if (s_info.alloc_canvas) {
1007 info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
1012 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
1013 widget_destroy_buffer(info->handle);
1019 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
1023 * Free callback must be prepared before use the ecore_evas_free()
1025 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
1027 info->e = ecore_evas_get(info->ee);
1029 ErrPrint("Failed to get evas\n");
1030 ecore_evas_free(info->ee);
1034 pre_render_cb(info, NULL, NULL);
1035 ecore_evas_alpha_set(info->ee, EINA_TRUE);
1036 post_render_cb(info, NULL, NULL);
1038 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
1039 ecore_evas_resize(info->ee, info->w, info->h);
1041 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
1042 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
1044 widget_add_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);