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>
38 #include "widget_internal.h"
43 #define PUBLIC __attribute__((visibility("default")))
44 #define WIDGET_WIN_TAG "dynamic,box,win"
46 #define WIDGET_DEFAULT_WIDTH 1
47 #define WIDGET_DEFAULT_HEIGHT 1
48 #define GL_ENGINE "opengl_x11"
50 static struct static_info {
51 Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
52 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);
53 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);
56 .alloc_canvas_with_stride = NULL,
57 .alloc_canvas_with_pixmap = NULL,
62 * Abstracted Data Type of Virtual Window
64 typedef struct virtual_window_info {
65 char *id; /**< Identification */
66 widget_buffer_h handle; /**< Livebox buffer handle */
68 VWIN_SW_BUF = 0x00, /**< S/W buffer */
69 VWIN_GEM = 0x01, /**< GEM buffer */
70 VWIN_PIXMAP = 0x02, /**< PIXMAP */
71 VWIN_ERROR = 0x03 /**< Unknown */
79 unsigned int *resource_array;
85 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
89 o = evas_object_name_find(evas_object_evas_get(obj), "_elm_access_disp");
92 ho = evas_object_data_get(o, "_elm_access_target");
98 * Every user event (mouse) on the buffer will be passed via this event callback
100 static int event_handler_cb(widget_buffer_h handler, struct widget_buffer_event_data *event_info, void *data)
102 vwin_info_t info = data;
103 Elm_Access_Action_Info action_info;
104 Elm_Access_Action_Type action_type;
106 Evas_Object *parent_elm;
108 unsigned int flags = 0;
112 /* Just ignore this event */
116 if (WIDGET_CONF_USE_GETTIMEOFDAY) {
117 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
120 if (gettimeofday(&tv, NULL) < 0) {
121 ErrPrint("gettimeofday: %s\n", strerror(errno));
123 timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
124 timestamp -= event_info->timestamp;
126 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
127 DbgPrint("Dropped %lf\n", timestamp);
134 * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
135 * Evas only use the monotic time for animating objects
137 timestamp = ecore_time_get() * 1000.0f;
139 if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
140 timestamp = ecore_time_get();
142 timestamp -= event_info->timestamp;
143 if (timestamp > WIDGET_CONF_EVENT_FILTER) {
144 DbgPrint("Dropped %lf\n", timestamp);
149 timestamp = event_info->timestamp * 1000.0f;
156 switch (event_info->type) {
157 case WIDGET_BUFFER_EVENT_ON_HOLD:
158 flags = evas_event_default_flags_get(info->e);
159 flags |= EVAS_EVENT_FLAG_ON_HOLD;
160 evas_event_default_flags_set(info->e, flags);
161 ErrPrint("ON_HOLD[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
163 case WIDGET_BUFFER_EVENT_OFF_HOLD:
164 flags = evas_event_default_flags_get(info->e);
165 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
166 evas_event_default_flags_set(info->e, flags);
168 case WIDGET_BUFFER_EVENT_ON_SCROLL:
169 flags = evas_event_default_flags_get(info->e);
170 flags |= EVAS_EVENT_FLAG_ON_SCROLL;
171 evas_event_default_flags_set(info->e, flags);
173 case WIDGET_BUFFER_EVENT_OFF_SCROLL:
174 flags = evas_event_default_flags_get(info->e);
175 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
176 evas_event_default_flags_set(info->e, flags);
178 case WIDGET_BUFFER_EVENT_ENTER:
179 evas_event_feed_mouse_in(info->e, timestamp, NULL);
181 case WIDGET_BUFFER_EVENT_LEAVE:
182 evas_event_feed_mouse_out(info->e, timestamp, NULL);
184 case WIDGET_BUFFER_EVENT_DOWN:
186 ErrPrint("MOUSE UP is not called\n");
187 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
188 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
189 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
194 * Before processing the DOWN event,
195 * Reset the evas event flags regarding ON_HOLD option.
196 * It can be re-enabled while processing down-move-up events.
198 flags = evas_event_default_flags_get(info->e);
199 flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
200 flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
201 evas_event_default_flags_set(info->e, flags);
204 * Calculate the event occurred X & Y on the buffer
206 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
207 evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
209 ErrPrint("DOWN[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
211 case WIDGET_BUFFER_EVENT_MOVE:
214 * Calculate the event occurred X & Y on the buffer
216 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
218 case WIDGET_BUFFER_EVENT_UP:
219 evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
220 evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
224 * We have to keep the event flags, so we should not clear them from here.
225 * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
226 * so if we reset them from here, those kind of callbacks will fails to do their job properly.
228 ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
230 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
231 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
233 ret = WIDGET_ACCESS_STATUS_ERROR;
236 memset(&action_info, 0, sizeof(action_info));
237 action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
240 * Calculate the event occurred X & Y on the buffer
242 action_info.x = event_info->info.access.x;
243 action_info.y = event_info->info.access.y;
244 ret = elm_access_action(parent_elm, action_type, &action_info);
245 if (ret == EINA_TRUE) {
246 if (!get_highlighted_object(parent_elm)) {
247 ErrPrint("Highlighted object is not found\n");
248 ret = WIDGET_ACCESS_STATUS_ERROR;
250 DbgPrint("Highlighted object is found\n");
251 ret = WIDGET_ACCESS_STATUS_DONE;
254 ErrPrint("Action error\n");
255 ret = WIDGET_ACCESS_STATUS_ERROR;
258 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
259 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
261 ret = WIDGET_ACCESS_STATUS_ERROR;
264 memset(&action_info, 0, sizeof(action_info));
265 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
266 action_info.highlight_cycle = EINA_FALSE;
267 ret = elm_access_action(parent_elm, action_type, &action_info);
268 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
270 case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
271 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
273 ret = WIDGET_ACCESS_STATUS_ERROR;
276 memset(&action_info, 0, sizeof(action_info));
277 action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
278 action_info.highlight_cycle = EINA_FALSE;
279 ret = elm_access_action(parent_elm, action_type, &action_info);
280 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
282 case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
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_ACTIVATE;
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_UP:
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_UP;
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_ACTION_DOWN:
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_DOWN;
312 ret = elm_access_action(parent_elm, action_type, &action_info);
313 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
315 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
316 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
318 ret = WIDGET_ACCESS_STATUS_ERROR;
321 memset(&action_info, 0, sizeof(action_info));
322 action_type = ELM_ACCESS_ACTION_SCROLL;
323 action_info.x = event_info->info.access.x;
324 action_info.y = event_info->info.access.y;
325 action_info.mouse_type = event_info->info.access.mouse_type;
326 ret = elm_access_action(parent_elm, action_type, &action_info);
327 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
329 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
330 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
332 ret = WIDGET_ACCESS_STATUS_ERROR;
335 memset(&action_info, 0, sizeof(action_info));
336 action_type = ELM_ACCESS_ACTION_SCROLL;
337 action_info.x = event_info->info.access.x;
338 action_info.y = event_info->info.access.y;
339 action_info.mouse_type = event_info->info.access.mouse_type;
340 ret = elm_access_action(parent_elm, action_type, &action_info);
341 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
343 case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
344 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
346 ret = WIDGET_ACCESS_STATUS_ERROR;
349 memset(&action_info, 0, sizeof(action_info));
350 action_type = ELM_ACCESS_ACTION_SCROLL;
351 action_info.x = event_info->info.access.x;
352 action_info.y = event_info->info.access.y;
353 action_info.mouse_type = event_info->info.access.mouse_type;
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_UNHIGHLIGHT:
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_UNHIGHLIGHT;
365 ret = elm_access_action(parent_elm, action_type, &action_info);
366 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
368 case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
369 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
371 ret = WIDGET_ACCESS_STATUS_ERROR;
374 memset(&action_info, 0, sizeof(action_info));
375 action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
376 action_info.x = event_info->info.access.x;
377 action_info.y = event_info->info.access.y;
378 action_info.mouse_type = event_info->info.access.mouse_type;
379 ret = elm_access_action(parent_elm, action_type, &action_info);
380 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
382 case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
383 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
385 ret = WIDGET_ACCESS_STATUS_ERROR;
388 memset(&action_info, 0, sizeof(action_info));
389 action_type = ELM_ACCESS_ACTION_MOUSE;
390 action_info.x = event_info->info.access.x;
391 action_info.y = event_info->info.access.y;
392 action_info.mouse_type = event_info->info.access.mouse_type;
393 ret = elm_access_action(parent_elm, action_type, &action_info);
394 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
396 case WIDGET_BUFFER_EVENT_ACCESS_BACK:
397 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
399 ret = WIDGET_ACCESS_STATUS_ERROR;
402 memset(&action_info, 0, sizeof(action_info));
403 action_type = ELM_ACCESS_ACTION_BACK;
404 action_info.x = event_info->info.access.x;
405 action_info.y = event_info->info.access.y;
406 action_info.mouse_type = event_info->info.access.mouse_type;
407 ret = elm_access_action(parent_elm, action_type, &action_info);
408 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
410 case WIDGET_BUFFER_EVENT_ACCESS_OVER:
411 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
413 ret = WIDGET_ACCESS_STATUS_ERROR;
416 memset(&action_info, 0, sizeof(action_info));
417 action_type = ELM_ACCESS_ACTION_OVER;
418 action_info.x = event_info->info.access.x;
419 action_info.y = event_info->info.access.y;
420 action_info.mouse_type = event_info->info.access.mouse_type;
421 ret = elm_access_action(parent_elm, action_type, &action_info);
422 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
424 case WIDGET_BUFFER_EVENT_ACCESS_READ:
425 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
427 ret = WIDGET_ACCESS_STATUS_ERROR;
430 memset(&action_info, 0, sizeof(action_info));
431 action_type = ELM_ACCESS_ACTION_READ;
432 action_info.x = event_info->info.access.x;
433 action_info.y = event_info->info.access.y;
434 action_info.mouse_type = event_info->info.access.mouse_type;
435 ret = elm_access_action(parent_elm, action_type, &action_info);
436 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
438 case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
439 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
441 ret = WIDGET_ACCESS_STATUS_ERROR;
444 memset(&action_info, 0, sizeof(action_info));
445 action_type = ELM_ACCESS_ACTION_ENABLE;
446 action_info.x = event_info->info.access.x;
447 action_info.y = event_info->info.access.y;
448 action_info.mouse_type = event_info->info.access.mouse_type;
449 ret = elm_access_action(parent_elm, action_type, &action_info);
450 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
452 case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
453 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
455 ret = WIDGET_ACCESS_STATUS_ERROR;
458 memset(&action_info, 0, sizeof(action_info));
459 action_type = ELM_ACCESS_ACTION_DISABLE;
460 action_info.x = event_info->info.access.x;
461 action_info.y = event_info->info.access.y;
462 action_info.mouse_type = event_info->info.access.mouse_type;
463 ret = elm_access_action(parent_elm, action_type, &action_info);
464 ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
466 case WIDGET_BUFFER_EVENT_KEY_DOWN:
467 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
469 ret = WIDGET_ACCESS_STATUS_ERROR;
473 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
478 key_string = XKeysymToString(*key_symbol);
479 key_name = XKeysymToString(*key_symbol);
480 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
485 ret = WIDGET_KEY_STATUS_ERROR;
487 case WIDGET_BUFFER_EVENT_KEY_UP:
488 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
490 ret = WIDGET_ACCESS_STATUS_ERROR;
494 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
499 key_string = XKeysymToString(*key_symbol);
500 key_name = XKeysymToString(*key_symbol);
501 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
506 ret = WIDGET_KEY_STATUS_ERROR;
508 case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
509 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
511 ret = WIDGET_ACCESS_STATUS_ERROR;
515 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
520 key_string = XKeysymToString(*key_symbol);
521 key_name = XKeysymToString(*key_symbol);
522 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
527 ret = WIDGET_KEY_STATUS_ERROR;
529 case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
530 parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
532 ret = WIDGET_ACCESS_STATUS_ERROR;
536 key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
541 key_string = XKeysymToString(*key_symbol);
542 key_name = XKeysymToString(*key_symbol);
543 DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
548 ret = WIDGET_KEY_STATUS_ERROR;
551 DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
560 * This callback can be called twice (or more) to get a several pixmaps
561 * Acquired pixmaps are used for double/tripple buffering for canvas
563 static Ecore_X_Pixmap alloc_pixmap_cb(void *data, Ecore_X_Window parent, int w, int h, int depth)
565 vwin_info_t info = data;
566 Ecore_X_Pixmap pixmap;
569 ErrPrint("Invalid handle\n");
575 DbgPrint("Size of ee is updated: %dx%d - %d (info: %p)\n", info->w, info->h, depth, info);
578 if (widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER) == 0u) {
581 * Need to allocate a primary buffer
583 widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, depth);
585 ErrPrint("Failed to get the buffer\n");
589 pixmap = (Ecore_X_Pixmap)widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER);
590 } else if (WIDGET_CONF_EXTRA_BUFFER_COUNT > 0) {
593 if (!info->resource_array) {
594 info->resource_array = calloc(WIDGET_CONF_EXTRA_BUFFER_COUNT, sizeof(*info->resource_array));
595 if (!info->resource_array) {
596 ErrPrint("Out of memory: %s\n", strerror(errno));
602 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
603 if (info->resource_array[idx] == 0u) {
608 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
609 ErrPrint("Out of index: %d\n", idx);
614 if (widget_viewer_acquire_buffer(info->handle, idx, info->w, info->h, depth) < 0) {
615 ErrPrint("Failed to acquire a buffer for %d\n", idx);
619 info->resource_array[idx] = widget_viewer_get_resource_id(info->handle, idx);
620 if (info->resource_array[idx] == 0u) {
621 ErrPrint("Failed to allocate pixmap\n");
624 DbgPrint("Allocated index: %d/%d - %u\n", idx, WIDGET_CONF_EXTRA_BUFFER_COUNT, info->resource_array[idx]);
625 pixmap = info->resource_array[idx];
627 ErrPrint("Unable to allocate pixmap\n");
632 * Acquire a buffer for canvas.
634 info->type = VWIN_PIXMAP;
635 info->resource_cnt += !!(unsigned int)pixmap;
639 static void free_pixmap_cb(void *data, Ecore_X_Pixmap pixmap)
641 vwin_info_t info = data;
647 if (info->type != VWIN_PIXMAP) {
648 ErrPrint("Impossible\n");
651 if (widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER) == pixmap) {
652 if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
653 DbgPrint("Failed to release buffer\n");
655 info->resource_cnt--;
659 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
662 * Find a index to release it
664 if (info->resource_array[idx] == pixmap) {
665 if (widget_viewer_release_buffer(info->handle, idx) < 0) {
666 DbgPrint("Failed to release buffer\n");
668 info->resource_array[idx] = 0u;
669 info->resource_cnt--;
675 if (info->deleted && info->resource_cnt == 0) {
676 DbgPrint("Destroy buffer handle\n");
678 widget_destroy_buffer(info->handle);
679 free(info->resource_array);
685 static void *alloc_fb(void *data, int size)
687 vwin_info_t info = data;
691 ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
692 DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
696 ErrPrint("Failed to create a buffer\n");
700 if (widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, sizeof(int)) < 0) {
701 ErrPrint("Failed to acquire buffer\n");
706 * If it supports the H/W accelerated buffer,
709 if (widget_support_hw_buffer(info->handle)) {
710 if (widget_create_hw_buffer(info->handle) == 0) {
711 buffer = widget_buffer_hw_buffer(info->handle);
713 DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
714 info->type = VWIN_GEM;
719 ErrPrint("Failed to allocate HW Accelerated buffer\n");
723 * Or use the buffer of a S/W backend.
725 buffer = widget_ref_buffer(info->handle);
726 DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
727 info->type = VWIN_SW_BUF;
731 static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
735 buffer = alloc_fb(data, size);
737 vwin_info_t info = data;
741 _stride = widget_buffer_stride(info->handle);
743 _stride = info->w * *bpp;
748 DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
754 static void free_fb(void *data, void *ptr)
756 vwin_info_t info = data;
762 if (info->type == VWIN_GEM) {
763 if (widget_destroy_hw_buffer(info->handle) == 0) {
764 DbgPrint("HW Accelerated buffer is destroyed\n");
766 } else if (info->type == VWIN_SW_BUF) {
767 DbgPrint("SW buffer is destroyed, %p\n", info);
768 widget_unref_buffer(ptr);
769 } else if (info->type == VWIN_PIXMAP) {
770 ErrPrint("Unable to reach to here\n");
773 if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
774 ErrPrint("Failed to release buffer\n");
778 widget_destroy_buffer(info->handle);
779 free(info->resource_array);
785 static void pre_render_cb(void *data, Evas *e, void *event_info)
787 vwin_info_t info = data;
793 if (widget_conf_premultiplied_alpha()) {
797 ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
798 evas_damage_rectangle_add(e, 0, 0, w, h);
801 if (info->type == VWIN_GEM) {
802 widget_buffer_pre_render(info->handle);
803 } else if (info->type == VWIN_PIXMAP) {
805 * Only the pixmap type Ecore_Evas uses this variable
807 } else if (info->type == VWIN_SW_BUF) {
812 static void post_render_cb(void *data, Evas *e, void *event_info)
814 vwin_info_t info = data;
820 if (widget_conf_premultiplied_alpha()) {
824 // Get a pointer of a buffer of the virtual canvas
825 canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
827 ErrPrint("Failed to get pixel canvas\n");
831 ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
832 evas_data_argb_unpremul(canvas, w * h);
835 if (info->type == VWIN_GEM) {
836 widget_buffer_post_render(info->handle);
837 } else if (info->type == VWIN_PIXMAP) {
839 unsigned int front_resource_id;
841 front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
843 for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
844 if (front_resource_id == info->resource_array[idx]) {
847 widget_send_updated_by_idx(info->handle, idx);
852 if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
853 /* Send updated event for PRIMARY BUFFER */
854 if (front_resource_id == widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER)) {
855 widget_send_updated_by_idx(info->handle, WIDGET_PRIMARY_BUFFER);
857 DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER));
860 } else if (info->type == VWIN_SW_BUF) {
861 widget_viewer_sync_buffer(info->handle);
865 static void pre_destroy_cb(widget_pre_callback_e type, const char *pkgname, const char *id, void *data)
867 vwin_info_t info = data;
868 if (strcmp(info->id, id)) {
870 DbgPrint("SKIP: Pre destroy event callback is called [%s]\n", id);
873 DbgPrint("Pre destroy event callback is called [%s]\n", id);
876 DbgPrint("Toggle manual render mode to prevent from unwanted rendering");
877 ecore_evas_manual_render_set(info->ee, EINA_TRUE);
881 static void ecore_evas_free_cb(Ecore_Evas *ee)
885 info = ecore_evas_data_get(ee, "dynamic,box,info");
887 DbgPrint("Info is not valid\n");
891 widget_provider_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
894 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
895 evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
902 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
903 PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
904 #else /* WIDGET_FEATURE_GBAR_SUPPORTED */
905 PUBLIC Evas *widget_get_evas(const char *id)
906 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
914 * If the evas object is already created,
915 * this function should returns ERROR.
918 if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
919 s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
920 if (!s_info.alloc_canvas_with_pixmap) {
921 DbgPrint("pixmap_allocfunc_new is not found\n");
924 s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
925 if (!s_info.alloc_canvas_with_stride) {
926 DbgPrint("allocfunc_with_stirde_new is not found\n");
929 s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
930 if (!s_info.alloc_canvas) {
931 ErrPrint("allocfunc_new is not found\n");
934 if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
935 ErrPrint("No way to allocate canvas\n");
941 ErrPrint("Invalid parameter\n");
945 info = calloc(1, sizeof(*info));
947 ErrPrint("Heap: %s\n", strerror(errno));
951 info->id = strdup(id);
953 ErrPrint("Heap: %s\n", strerror(errno));
958 #ifdef WIDGET_FEATURE_GBAR_SUPPORTED
959 info->is_gbar = is_gbar;
962 #endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
965 * Acquire a buffer for canvas.
967 info->handle = widget_create_buffer(info->id, info->is_gbar,
968 (widget_conf_auto_align() || !s_info.alloc_canvas_with_stride),
969 event_handler_cb, info);
972 ErrPrint("Failed to create a widget buffer\n");
979 * Size information must be initialized before call the ecore_evas_buffer_new.
981 info->w = WIDGET_DEFAULT_WIDTH;
982 info->h = WIDGET_DEFAULT_HEIGHT;
984 engine = elm_config_preferred_engine_get();
985 DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
986 if (engine && !strcmp(engine, GL_ENGINE)) {
987 if (s_info.alloc_canvas_with_pixmap) {
988 info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
990 ErrPrint("Unable to create a ee for pixmap\n");
996 if (!widget_conf_auto_align() && s_info.alloc_canvas_with_stride) {
997 info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
998 } else if (s_info.alloc_canvas) {
999 info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
1004 ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
1005 widget_destroy_buffer(info->handle);
1011 ecore_evas_data_set(info->ee, "dynamic,box,info", info);
1015 * Free callback must be prepared before use the ecore_evas_free()
1017 ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
1019 info->e = ecore_evas_get(info->ee);
1021 ErrPrint("Failed to get evas\n");
1022 ecore_evas_free(info->ee);
1026 pre_render_cb(info, NULL, NULL);
1027 ecore_evas_alpha_set(info->ee, EINA_TRUE);
1028 post_render_cb(info, NULL, NULL);
1030 ecore_evas_manual_render_set(info->ee, EINA_FALSE);
1031 ecore_evas_resize(info->ee, info->w, info->h);
1033 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
1034 evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
1036 widget_provider_add_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);