Prepare for porting to the wayland
authorSung-jae Park <nicesj.park@samsung.com>
Mon, 20 Apr 2015 05:58:49 +0000 (14:58 +0900)
committerSung-jae Park <nicesj.park@samsung.com>
Mon, 20 Apr 2015 05:58:49 +0000 (14:58 +0900)
[model] Redwood,Kiran,B3(Wearable)
[binary_type] AP
[customer] Docomo/Orange/ATT/Open
[issue#] N/A
[problem]
[cause]
[solution]
[team] HomeTF
[request]
[horizontal_expansion]

Change-Id: I1850ee192c0d8e1e787b348c32d2021c8caf04bd

src/virtual_window_wayland.c

index d332aaa..4ae8122 100644 (file)
 #include "widget.h"
 #include "debug.h"
 
-#define IS_PD 1
+#define IS_GBAR 1
 
 #define PUBLIC __attribute__((visibility("default")))
+#define WIDGET_WIN_TAG "dynamic,box,win"
+
+#define WIDGET_DEFAULT_WIDTH 1
+#define WIDGET_DEFAULT_HEIGHT 1
+#define GL_ENGINE "opengl_x11"
+
+static struct static_info {
+       Ecore_Evas *(*alloc_canvas)(int w, int h, void *(*a)(void *data, int size), void (*f)(void *data, void *ptr), void *data);
+       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);
+       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);
+} s_info = {
+       .alloc_canvas = NULL,
+       .alloc_canvas_with_stride = NULL,
+       .alloc_canvas_with_pixmap = NULL,
+};
 
-/*!
- * \brief
+/**
+ * @brief
  * Abstracted Data Type of Virtual Window
  */
-struct info {
-       char *id; /*!< Identification */
-       struct widget_buffer *handle; /*!< Livebox buffer handle */
-       int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
+typedef struct virtual_window_info {
+       char *id; /**< Identification */
+       widget_buffer_h handle; /**< Livebox buffer handle */
+       enum win_type {
+               VWIN_SW_BUF = 0x00, /**< S/W buffer */
+               VWIN_GEM    = 0x01, /**< GEM buffer */
+               VWIN_PIXMAP = 0x02, /**< PIXMAP */
+               VWIN_ERROR  = 0x03  /**< Unknown */
+       } type;
        Ecore_Evas *ee;
        Evas *e;
        int is_gbar;
-};
+       int deleted;
+       int w;
+       int h;
+       unsigned int *resource_array;
+       int resource_cnt;
+
+       int pressed;
+} *vwin_info_t;
 
 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
 {
@@ -61,11 +88,13 @@ static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
  */
 static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_event_data *event_info, void *data)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
        Elm_Access_Action_Info action_info;
        Elm_Access_Action_Type action_type;
        int ret = 0;
        Evas_Object *parent_elm;
+       unsigned int flags = 0;
+       double timestamp;
 
 
        if (!info->handle) {
@@ -73,66 +102,150 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
                return 0;
        }
 
+       if (WIDGET_CONF_USE_GETTIMEOFDAY) {
+               if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
+                       struct timeval tv;
+
+                       if (gettimeofday(&tv, NULL) < 0) {
+                               ErrPrint("gettimeofday: %s\n", strerror(errno));
+                       } else {
+                               timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
+                               timestamp -= event_info->timestamp;
+
+                               if (timestamp > WIDGET_CONF_EVENT_FILTER) {
+                                       DbgPrint("Dropped %lf\n", timestamp);
+                                       return 0;
+                               }
+                       }
+               }
+
+               /**
+                * If the device doesn't use the clock monotic time, we have to emulate it for EVAS
+                * Evas only use the monotic time for animating objects
+                */
+               timestamp = ecore_time_get() * 1000.0f;
+       } else {
+               if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
+                       timestamp = ecore_time_get();
+
+                       timestamp -= event_info->timestamp;
+                       if (timestamp > WIDGET_CONF_EVENT_FILTER) {
+                               DbgPrint("Dropped %lf\n", timestamp);
+                               return 0;
+                       }
+               }
+
+               timestamp = event_info->timestamp * 1000.0f;
+       }
+
        /*!
         * \note
         * Feed up events
         */
        switch (event_info->type) {
+       case WIDGET_BUFFER_EVENT_ON_HOLD:
+               flags = evas_event_default_flags_get(info->e);
+               flags |= EVAS_EVENT_FLAG_ON_HOLD;
+               evas_event_default_flags_set(info->e, flags);
+               ErrPrint("ON_HOLD[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
+               break;
+       case WIDGET_BUFFER_EVENT_OFF_HOLD:
+               flags = evas_event_default_flags_get(info->e);
+               flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
+               evas_event_default_flags_set(info->e, flags);
+               break;
+       case WIDGET_BUFFER_EVENT_ON_SCROLL:
+               flags = evas_event_default_flags_get(info->e);
+               flags |= EVAS_EVENT_FLAG_ON_SCROLL;
+               evas_event_default_flags_set(info->e, flags);
+               break;
+       case WIDGET_BUFFER_EVENT_OFF_SCROLL:
+               flags = evas_event_default_flags_get(info->e);
+               flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
+               evas_event_default_flags_set(info->e, flags);
+               break;
        case WIDGET_BUFFER_EVENT_ENTER:
-               evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
+               evas_event_feed_mouse_in(info->e, timestamp, NULL);
                break;
        case WIDGET_BUFFER_EVENT_LEAVE:
-               evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
+               evas_event_feed_mouse_out(info->e, timestamp, NULL);
                break;
        case WIDGET_BUFFER_EVENT_DOWN:
-               /*!
-                * \note
+               if (info->pressed) {
+                       ErrPrint("MOUSE UP is not called\n");
+                       ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
+                       evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
+                       evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
+               }
+
+               /**
+                * @note
+                * Before processing the DOWN event,
+                * Reset the evas event flags regarding ON_HOLD option.
+                * It can be re-enabled while processing down-move-up events.
+                */
+               flags = evas_event_default_flags_get(info->e);
+               flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
+               flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
+               evas_event_default_flags_set(info->e, flags);
+               /**
+                * @note
                 * Calculate the event occurred X & Y on the buffer
                 */
-               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, (event_info->timestamp - 0.001f) * 1000, NULL); /* + 0.1f just for fake event */
-               evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
+               evas_event_feed_mouse_down(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
+               info->pressed = 1;
+               ErrPrint("DOWN[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
                break;
        case WIDGET_BUFFER_EVENT_MOVE:
-               /*!
-                * \note
+               /**
+                * @note
                 * Calculate the event occurred X & Y on the buffer
                 */
-               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
                break;
        case WIDGET_BUFFER_EVENT_UP:
-               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, event_info->timestamp * 1000, NULL);
-               evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, (event_info->timestamp + 0.001f) * 1000, NULL);
+               evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
+               evas_event_feed_mouse_up(info->e, 1, EVAS_BUTTON_NONE, timestamp, NULL);
+               info->pressed = 0;
+               /**
+                * @note
+                * We have to keep the event flags, so we should not clear them from here.
+                * Sometimes, asynchronously callable Callbacks can refer the evas event flags after up event.
+                * so if we reset them from here, those kind of callbacks will fails to do their job properly.
+                */
+               ErrPrint("UP[%s] %dx%d - %lf\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp);
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
                action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
-               /*!
-                * \note
+               /**
+                * @note
                 * Calculate the event occurred X & Y on the buffer
                 */
-               action_info.x = event_info->info.pointer.x;
-               action_info.y = event_info->info.pointer.y;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
                ret = elm_access_action(parent_elm, action_type, &action_info);
                if (ret == EINA_TRUE) {
                        if (!get_highlighted_object(parent_elm)) {
-                               LOGE("Highlighted object is not found\n");
+                               ErrPrint("Highlighted object is not found\n");
                                ret = WIDGET_ACCESS_STATUS_ERROR;
                        } else {
-                               LOGD("Highlighted object is found\n");
+                               DbgPrint("Highlighted object is found\n");
                                ret = WIDGET_ACCESS_STATUS_DONE;
                        }
                } else {
-                       LOGE("Action error\n");
+                       ErrPrint("Action error\n");
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                }
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
@@ -144,7 +257,7 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
@@ -156,7 +269,7 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_FIRST : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_ACTIVATE:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
@@ -167,7 +280,7 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_ACTION_UP:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
@@ -178,7 +291,7 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_ACTION_DOWN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
@@ -189,49 +302,49 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
                action_type = ELM_ACCESS_ACTION_SCROLL;
-               action_info.x = event_info->info.pointer.x;
-               action_info.y = event_info->info.pointer.y;
-               action_info.mouse_type = 2;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
                ret = elm_access_action(parent_elm, action_type, &action_info);
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
                action_type = ELM_ACCESS_ACTION_SCROLL;
-               action_info.x = event_info->info.pointer.x;
-               action_info.y = event_info->info.pointer.y;
-               action_info.mouse_type = 1;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
                ret = elm_access_action(parent_elm, action_type, &action_info);
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
                action_type = ELM_ACCESS_ACTION_SCROLL;
-               action_info.x = event_info->info.pointer.x;
-               action_info.y = event_info->info.pointer.y;
-               action_info.mouse_type = 0;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
                ret = elm_access_action(parent_elm, action_type, &action_info);
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
        case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
@@ -241,44 +354,190 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
                ret = elm_access_action(parent_elm, action_type, &action_info);
                ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
+       case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_VALUE_CHANGE;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
+               break;
+       case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_MOUSE;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
+               break;
+       case WIDGET_BUFFER_EVENT_ACCESS_BACK:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_BACK;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
+               break;
+       case WIDGET_BUFFER_EVENT_ACCESS_OVER:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_OVER;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
+               break;
+       case WIDGET_BUFFER_EVENT_ACCESS_READ:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_READ;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
+               break;
+       case WIDGET_BUFFER_EVENT_ACCESS_ENABLE:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_ENABLE;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
+               break;
+       case WIDGET_BUFFER_EVENT_ACCESS_DISABLE:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = ELM_ACCESS_ACTION_DISABLE;
+               action_info.x = event_info->info.access.x;
+               action_info.y = event_info->info.access.y;
+               action_info.mouse_type = event_info->info.access.mouse_type;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
+               break;
        case WIDGET_BUFFER_EVENT_KEY_DOWN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+                       XFree(key_string);
+               }
                ret = WIDGET_KEY_STATUS_ERROR;
                break;
        case WIDGET_BUFFER_EVENT_KEY_UP:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+                       XFree(key_string);
+               }
                ret = WIDGET_KEY_STATUS_ERROR;
                break;
        case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+                       XFree(key_string);
+               }
                ret = WIDGET_KEY_STATUS_ERROR;
                break;
        case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
                        ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
+               key_symbol = XGetKeyboardMapping(ecore_x_display_get(), event_info->info.keycode, 1, &ret);
+               if (key_symbol) {
+                       char *key_name;
+                       char *key_string;
+
+                       key_string = XKeysymToString(*key_symbol);
+                       key_name = XKeysymToString(*key_symbol);
+                       DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
+                       XFree(key_symbol);
+                       XFree(key_name);
+                       XFree(key_string);
+               }
                ret = WIDGET_KEY_STATUS_ERROR;
                break;
        default:
-               LOGD("Unhandled buffer event (%d)\n", event_info->type);
+               DbgPrint("Unhandled buffer event (%d)\n", event_info->type);
                break;
        }
 
@@ -287,26 +546,25 @@ static int event_handler_cb(struct widget_buffer *handler, struct widget_buffer_
 
 static void *alloc_fb(void *data, int size)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
        void *buffer;
-       int width = 0;
-       int height = 0;
 
-       if (info->ee == NULL) {
-               width = 1;
-               height = 1;
-       } else {
-               ecore_evas_geometry_get(info->ee, NULL, NULL, &width, &height);
+       if (info->ee) {
+               ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
+               DbgPrint("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
        }
 
-       /*!
-        * Acquire a buffer for canvas.
-        */
-       info->handle = widget_viewer_acquire_buffer(info->id, info->is_gbar,
-                       width, height,
-                       event_handler_cb, info);
+       if (!info->handle) {
+               ErrPrint("Failed to create a buffer\n");
+               return NULL;
+       }
 
-       /*!
+       if (widget_viewer_acquire_buffer(info->handle, WIDGET_PRIMARY_BUFFER, info->w, info->h, sizeof(int)) < 0) {
+               ErrPrint("Failed to acquire buffer\n");
+               return NULL;
+       }
+
+       /**
         * If it supports the H/W accelerated buffer,
         * Use it.
         */
@@ -314,78 +572,213 @@ static void *alloc_fb(void *data, int size)
                if (widget_create_hw_buffer(info->handle) == 0) {
                        buffer = widget_buffer_hw_buffer(info->handle);
                        if (buffer) {
-                               LOGD("HW Accelerated buffer is created\n");
-                               info->is_hw = 1;
+                               DbgPrint("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
+                               info->type = VWIN_GEM;
                                return buffer;
                        }
                }
 
-               LOGE("Failed to allocate HW Accelerated buffer\n");
+               ErrPrint("Failed to allocate HW Accelerated buffer\n");
        }
 
-       /*!
+       /**
         * Or use the buffer of a S/W backend.
         */
        buffer = widget_ref_buffer(info->handle);
-       LOGD("SW buffer is created\n");
-       info->is_hw = 0;
+       DbgPrint("SW buffer is created (%dx%d)\n", info->w, info->h);
+       info->type = VWIN_SW_BUF;
        return buffer;
 }
 
 static void free_fb(void *data, void *ptr)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
 
        if (!info->handle) {
                return;
        }
 
-       if (info->is_hw) {
+       if (info->type == VWIN_GEM) {
                if (widget_destroy_hw_buffer(info->handle) == 0) {
-                       LOGD("HW Accelerated buffer is destroyed\n");
-                       goto out;
+                       DbgPrint("HW Accelerated buffer is destroyed\n");
                }
+       } else if (info->type == VWIN_SW_BUF) {
+               DbgPrint("SW buffer is destroyed, %p\n", info);
+               widget_unref_buffer(ptr);
+       } else if (info->type == VWIN_PIXMAP) {
+               ErrPrint("Unable to reach to here\n");
+       }
+
+       if (widget_viewer_release_buffer(info->handle, WIDGET_PRIMARY_BUFFER) < 0) {
+               ErrPrint("Failed to release buffer\n");
        }
 
-       widget_unref_buffer(ptr);
-       LOGD("SW buffer is destroyed\n");
-out:
-       widget_viewer_release_buffer(info->handle);
-       info->handle = NULL;
+       if (info->deleted) {
+               widget_destroy_buffer(info->handle);
+               free(info->resource_array);
+               free(info->id);
+               free(info);
+       }
 }
 
 static void pre_render_cb(void *data, Evas *e, void *event_info)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
 
        if (!info->handle) {
                return;
        }
 
-       if (info->is_hw) {
+       if (widget_conf_premultiplied_alpha()) {
+               Evas_Coord w;
+               Evas_Coord h;
+
+               ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
+               evas_damage_rectangle_add(e, 0, 0, w, h);
+       }
+
+       if (info->type == VWIN_GEM) {
                widget_buffer_pre_render(info->handle);
+       } else if (info->type == VWIN_PIXMAP) {
+               /**
+                * Only the pixmap type Ecore_Evas uses this variable
+                */
+       } else if (info->type == VWIN_SW_BUF) {
+               /* Do nothing */
        }
 }
 
 static void post_render_cb(void *data, Evas *e, void *event_info)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
 
        if (!info->handle) {
                return;
        }
 
-       if (info->is_hw) {
+       if (widget_conf_premultiplied_alpha()) {
+               void *canvas;
+               int x, y, w, h;
+
+               // Get a pointer of a buffer of the virtual canvas
+               canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
+               if (!canvas) {
+                       ErrPrint("Failed to get pixel canvas\n");
+                       return;
+               }
+
+               ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
+               evas_data_argb_unpremul(canvas, w * h);
+       }
+
+       if (info->type == VWIN_GEM) {
                widget_buffer_post_render(info->handle);
-       } else {
+       } else if (info->type == VWIN_PIXMAP) {
+               int idx;
+               unsigned int front_resource_id;
+
+               front_resource_id = ecore_evas_gl_x11_pixmap_get(info->ee);
+
+               for (idx = 0; idx < WIDGET_CONF_EXTRA_BUFFER_COUNT; idx++) {
+                       if (front_resource_id == info->resource_array[idx]) {
+                               /**
+                                */
+                               widget_send_updated_by_idx(info->handle, idx);
+                               break;
+                       }
+               }
+
+               if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
+                       /* Send updated event for PRIMARY BUFFER */
+                       if (front_resource_id == widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER)) {
+                               widget_send_updated_by_idx(info->handle, WIDGET_PRIMARY_BUFFER);
+                       } else {
+                               DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, WIDGET_PRIMARY_BUFFER));
+                       }
+               }
+       } else if (info->type == VWIN_SW_BUF) {
                widget_viewer_sync_buffer(info->handle);
        }
 }
 
+static void pre_destroy_cb(const char *id, void *data)
+{
+       vwin_info_t info = data;
+
+       if (id && strcmp(info->id, widget_util_uri_to_path(id))) {
+               /* Skip */
+               DbgPrint("SKIP: Pre destroy event callback is called [%s], %s\n", id, info->id);
+               return;
+       }
+
+       DbgPrint("Pre destroy event callback is called [%s]\n", id);
+
+       if (info->ee) {
+               DbgPrint("Toggle manual render mode to prevent from unwanted rendering");
+               ecore_evas_manual_render_set(info->ee, EINA_TRUE);
+       }
+}
+
+static void ecore_evas_free_cb(Ecore_Evas *ee)
+{
+       vwin_info_t info;
+
+       info = ecore_evas_data_get(ee, "dynamic,box,info");
+       if (!info) {
+               DbgPrint("Info is not valid\n");
+               return;
+       }
+
+       widget_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
+
+       if (info->e) {
+               evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb);
+               evas_event_callback_del(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb);
+       }
+
+       info->deleted = 1;
+       info->ee = NULL;
+}
+
+#ifdef WIDGET_FEATURE_GBAR_SUPPORTED
 PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
+#else /* WIDGET_FEATURE_GBAR_SUPPORTED */
+PUBLIC Evas *widget_get_evas(const char *id)
+#endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
 {
-       struct info *info;
+       vwin_info_t info;
        Evas_Object *rect;
+       const char *engine;
+
+       /**
+        * @TODO
+        * If the evas object is already created,
+        * this function should returns ERROR.
+        */
+
+       if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride && !s_info.alloc_canvas_with_pixmap) {
+               /*
+               s_info.alloc_canvas_with_pixmap = dlsym(RTLD_DEFAULT, "ecore_evas_gl_x11_pixmap_allocfunc_new");
+               if (!s_info.alloc_canvas_with_pixmap) {
+                       DbgPrint("pixmap_allocfunc_new is not found\n");
+               }
+               */
+
+               s_info.alloc_canvas_with_stride = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_with_stride_new");
+               if (!s_info.alloc_canvas_with_stride) {
+                       DbgPrint("allocfunc_with_stirde_new is not found\n");
+               }
+
+               s_info.alloc_canvas = dlsym(RTLD_DEFAULT, "ecore_evas_buffer_allocfunc_new");
+               if (!s_info.alloc_canvas) {
+                       ErrPrint("allocfunc_new is not found\n");
+               }
+
+               if (!s_info.alloc_canvas_with_stride && !s_info.alloc_canvas && !s_info.alloc_canvas_with_pixmap) {
+                       ErrPrint("No way to allocate canvas\n");
+                       return NULL;
+               }
+       }
 
        if (!id) {
                ErrPrint("Invalid parameter\n");
@@ -405,24 +798,66 @@ PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
                return NULL;
        }
 
+#ifdef WIDGET_FEATURE_GBAR_SUPPORTED
        info->is_gbar = is_gbar;
+#else
+       info->is_gbar = 0;
+#endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
 
-       info->ee = ecore_evas_buffer_allocfunc_new(1, 1, alloc_fb, free_fb, info);
-       if (!info->ee) {
-               ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
+       /**
+        * Acquire a buffer for canvas.
+        */
+       info->handle = widget_create_buffer(info->id, info->is_gbar,
+                       (widget_conf_auto_align() || !s_info.alloc_canvas_with_stride),
+                       event_handler_cb, info);
+
+       if (!info->handle) {
+               ErrPrint("Failed to create a widget buffer\n");
                free(info->id);
                free(info);
                return NULL;
        }
 
-       pre_render_cb(info, NULL, NULL);
-       ecore_evas_alpha_set(info->ee, EINA_TRUE);
-       post_render_cb(info, NULL, NULL);
+       /**
+        * Size information must be initialized before call the ecore_evas_buffer_new.
+        */
+       info->w = WIDGET_DEFAULT_WIDTH;
+       info->h = WIDGET_DEFAULT_HEIGHT;
+
+       engine = elm_config_preferred_engine_get();
+       DbgPrint("Preferred engine: %s (%s)\n", engine, GL_ENGINE);
+       if (engine && !strcmp(engine, GL_ENGINE)) {
+               if (s_info.alloc_canvas_with_pixmap) {
+                       info->ee = s_info.alloc_canvas_with_pixmap(NULL, 0u, 0, 0, info->w, info->h, alloc_pixmap_cb, free_pixmap_cb, info);
+                       if (!info->ee) {
+                               ErrPrint("Unable to create a ee for pixmap\n");
+                       }
+               }
+       }
+
+       if (!info->ee) {
+               if (!widget_conf_auto_align() && s_info.alloc_canvas_with_stride) {
+                       info->ee = s_info.alloc_canvas_with_stride(info->w, info->h, alloc_stride_fb, free_fb, info);
+               } else if (s_info.alloc_canvas) {
+                       info->ee = s_info.alloc_canvas(info->w, info->h, alloc_fb, free_fb, info);
+               }
+       }
+
+       if (!info->ee) {
+               ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
+               widget_destroy_buffer(info->handle);
+               free(info->id);
+               free(info);
+               return NULL;
+       }
 
        ecore_evas_data_set(info->ee, "dynamic,box,info", info);
 
-       ecore_evas_manual_render_set(info->ee, EINA_FALSE);
-       ecore_evas_resize(info->ee, 1, 1);
+       /**
+        * @note
+        * Free callback must be prepared before use the ecore_evas_free()
+        */
+       ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
 
        info->e = ecore_evas_get(info->ee);
        if (!info->e) {
@@ -431,9 +866,18 @@ PUBLIC Evas *widget_get_evas(const char *id, int is_gbar)
                return NULL;
        }
 
+       pre_render_cb(info, NULL, NULL);
+       ecore_evas_alpha_set(info->ee, EINA_TRUE);
+       post_render_cb(info, NULL, NULL);
+
+       ecore_evas_manual_render_set(info->ee, EINA_FALSE);
+       ecore_evas_resize(info->ee, info->w, info->h);
+
        evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_POST, post_render_cb, info);
        evas_event_callback_add(info->e, EVAS_CALLBACK_RENDER_PRE, pre_render_cb, info);
 
+       widget_add_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
+
        return info->e;
 }