Sync with the latest tizen 2.x
[apps/native/widget/widget.git] / src / virtual_window.c
index 696ea07..1d91878 100644 (file)
 #include <Ecore_X.h>
 #include <Evas.h>
 #include <dlfcn.h>
+#include <Eina.h>
+#include <math.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
 
 #include <X11/Xlib.h>
 
 #include <dlog.h>
-#include <livebox-errno.h>
-#include <livebox-service.h>
-
-#include "livebox.h"
-#include "livebox_product.h"
+#include <widget_errno.h>
+#include <widget_service.h>
+#include <widget_service_internal.h>
+#include <widget_conf.h>
+#include <widget_buffer.h>
+#include <widget_provider.h>
+#include <widget_provider_buffer.h>
+#include <widget_util.h>
+#include <libgen.h>
+
+#include "widget.h"
+#include "widget_internal.h"
 #include "debug.h"
+#include "binder.h"
 
-#define IS_PD 1
+#define IS_GBAR 1
 
 #define PUBLIC __attribute__((visibility("default")))
+#define WIDGET_WIN_TAG "dynamic,box,win"
+#define WIN_INFO_TAG "dynamic,box,info"
+
+#define WIDGET_DEFAULT_WIDTH 1
+#define WIDGET_DEFAULT_HEIGHT 1
+
+#define MOUSE_BUTTON_LEFT 1
+
+/**
+ * @note
+ * Supported touch devices are limited to 32.
+ * Because of count of bits of integer type. (32 bits)
+ */
+#define MAX_DEVICE 32
+
+#define IS_PRESSED(info, device)       (((device) < MAX_DEVICE) ? (((info)->pressed & (0x01 << (device))) == (0x01 << (device))) : 0)
 
-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);
-} s_info = {
-       .alloc_canvas = NULL,
-       .alloc_canvas_with_stride = NULL,
-};
-
-/*!
- * \brief
- * Abstracted Data Type of Virtual Window
+/**
+ * @note
+ * Short-Circuit
  */
-struct info {
-       char *id; /*!< Identification */
-       struct livebox_buffer *handle; /*!< Livebox buffer handle */
-       int is_hw; /*!< 1 if a buffer is created on the H/W accelerated place or 0 */
-       Ecore_Evas *ee;
-       Evas *e;
-       int is_pd;
-       int deleted;
-       int w;
-       int h;
-};
+#define SET_PRESSED(info, device)      ((void)(((device) < MAX_DEVICE) && (((info)->pressed |= (0x01 << (device))))))
+#define SET_RELEASED(info, device)     ((void)(((device) < MAX_DEVICE) && (((info)->pressed &= (~(0x01 << (device)))))))
 
 static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
 {
@@ -72,222 +85,434 @@ static inline Evas_Object *get_highlighted_object(Evas_Object *obj)
        return ho;
 }
 
-/*!
- * \note
- * Every user event (mouse) on the buffer will be passed via this event callback
- */
-static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_data *event_info, void *data)
+static inline void apply_orientation(int degree, int *x, int *y, int width, int height, input_event_source_e source)
+{
+       int _x;
+       int _y;
+       int _angle;
+
+       if (source == INPUT_EVENT_SOURCE_VIEWER) {
+               /* Already rotated */
+               return;
+       }
+
+       _x = *x;
+       _y = *y;
+
+       switch (degree) {
+       case 0:
+               return;
+       case 90:
+               *x = _y;
+               *y = width - _x;
+               return;
+       case 180:
+               *x = width - _x;
+               *y = height - _y;
+               return;
+       case 270:
+               *x = height - _y;
+               *y = _x;
+               return;
+       default:
+               /**
+                * @FIXME
+                * This rotation formular is not work correctly.
+                * The pointer should be rotated by other way.
+                * This is not what we want.
+                */
+               _angle = degree;
+
+               *x = (double)_x * cos((double)_angle) - (double)_y * sin((double)_angle);
+               *y = (double)_x * sin((double)_angle) + (double)_y * cos((double)_angle);
+               return;
+       }
+}
+
+static inline int processing_events(vwin_info_t info, widget_buffer_event_data_t event_info, double timestamp)
 {
-       struct info *info = data;
        Elm_Access_Action_Info action_info;
        Elm_Access_Action_Type action_type;
-       int ret = 0;
        Evas_Object *parent_elm;
        KeySym *key_symbol;
        unsigned int flags = 0;
-
-       if (!info->handle) {
-               /* Just ignore this event */
-               return 0;
-       }
-
-       /*!
-        * \note
+       int ret = 0;
+       /**
+        * @note
         * Feed up events
         */
        switch (event_info->type) {
-       case BUFFER_EVENT_ON_HOLD:
+       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);
+               if (info->pressed == 0) {
+                       info->flags.field.on_hold_before_down = 1;
+               }
                break;
-       case BUFFER_EVENT_OFF_HOLD:
+       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 BUFFER_EVENT_ON_SCROLL:
+       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);
+               if (info->pressed == 0) {
+                       info->flags.field.on_scroll_before_down = 1;
+               }
                break;
-       case BUFFER_EVENT_OFF_SCROLL:
+       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 BUFFER_EVENT_ENTER:
-               evas_event_feed_mouse_in(info->e, event_info->timestamp * 1000, NULL);
+       case WIDGET_BUFFER_EVENT_ENTER:
+               evas_event_feed_mouse_in(info->e, timestamp, NULL);
                break;
-       case BUFFER_EVENT_LEAVE:
-               evas_event_feed_mouse_out(info->e, event_info->timestamp * 1000, NULL);
+       case WIDGET_BUFFER_EVENT_LEAVE:
+               evas_event_feed_mouse_out(info->e, timestamp, NULL);
                break;
-       case BUFFER_EVENT_DOWN:
-               /*!
-                * \note
+       case WIDGET_BUFFER_EVENT_DOWN:
+               apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, info->w, info->h, event_info->info.pointer.source);
+
+               if (IS_PRESSED(info, event_info->info.pointer.device)) {
+                       ErrPrint("MOUSE UP is not called\n");
+                       ErrPrint("UP[%s] %dx%d - %lf (%d)\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, event_info->info.pointer.device);
+                       if (event_info->info.pointer.device > 0) {
+                               /**
+                                * @multi touch up
+                                */
+                               evas_event_feed_multi_up(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
+                                                                                       0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
+                                                                                       0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
+                                                                                       EVAS_BUTTON_NONE, timestamp, NULL); /* button_flags, timestamp, ... */
+                       } else {
+                               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, MOUSE_BUTTON_LEFT, 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.
+                * However if those events are occurred right before DOWN,
+                * Do not clear it.
+                * Some speicific cases, the ON_HOLD(ON_SCROLL) event can be delievered
+                * before MOUSE_DOWN event.
+                */
+               flags = evas_event_default_flags_get(info->e);
+               if (!info->flags.field.on_hold_before_down) {
+                       flags &= ~EVAS_EVENT_FLAG_ON_HOLD;
+               }
+               if (!info->flags.field.on_scroll_before_down) {
+                       flags &= ~EVAS_EVENT_FLAG_ON_SCROLL;
+               }
+               evas_event_default_flags_set(info->e, flags);
+
+               /**
+                * @note
+                * Reset flags after dealing with the ON_HOLD/ON_SCROLL event
+                */
+               info->flags.field.on_scroll_before_down = 0;
+               info->flags.field.on_hold_before_down = 0;
+               /**
+                * @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_down(info->e, 1, EVAS_BUTTON_NONE, event_info->timestamp * 1000, NULL); /* + 0.2f just for fake event */
+               if (event_info->info.pointer.device > 0) {
+                       evas_event_feed_multi_down(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
+                                                                                       0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
+                                                                                       0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
+                                                                                       EVAS_BUTTON_NONE, timestamp, NULL); /* button_flags, timestamp, ... */
+               } else {
+                       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, MOUSE_BUTTON_LEFT, EVAS_BUTTON_NONE, timestamp, NULL); /* + 0.2f just for fake event */
+               }
+
+               SET_PRESSED(info, event_info->info.pointer.device);
+               ErrPrint("DOWN[%s] %dx%d - %lf (%d)\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, event_info->info.pointer.device);
                break;
-       case BUFFER_EVENT_MOVE:
-               /*!
-                * \note
+       case WIDGET_BUFFER_EVENT_MOVE:
+               apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, info->w, info->h, event_info->info.pointer.source);
+               /**
+                * @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);
+               if (event_info->info.pointer.device > 0) {
+                       evas_event_feed_multi_move(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
+                                                                                       0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
+                                                                                       0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
+                                                                                       timestamp, NULL); /* timestamp, ... */
+               } else {
+                       evas_event_feed_mouse_move(info->e, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, NULL);
+               }
                break;
-       case 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 * 1000, NULL);
-
-               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);
+       case WIDGET_BUFFER_EVENT_UP:
+               apply_orientation(info->orientation, &event_info->info.pointer.x, &event_info->info.pointer.y, info->w, info->h, event_info->info.pointer.source);
+
+               if (event_info->info.pointer.device > 0) {
+                       evas_event_feed_multi_up(info->e, event_info->info.pointer.device, event_info->info.pointer.x, event_info->info.pointer.y,
+                                                                                       0.0f, 0.0f, 0.0f, /* radius, radius_x, radius_y */
+                                                                                       0.0f, 0.0f, 0.0f, 0.0f, /* pressure, angle, fx, fy */
+                                                                                       EVAS_BUTTON_NONE, timestamp, NULL); /* button_flags, timestamp, ... */
+               } else {
+                       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, MOUSE_BUTTON_LEFT, EVAS_BUTTON_NONE, timestamp, NULL);
+               }
+               SET_RELEASED(info, event_info->info.pointer.device);
+               /**
+                * @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 (%d)\n", info->id, event_info->info.pointer.x, event_info->info.pointer.y, timestamp, event_info->info.pointer.device);
                break;
-       case BUFFER_EVENT_HIGHLIGHT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
-               action_type = ELM_ACCESS_ACTION_HIGHLIGHT;
-               /*!
-                * \note
+               action_type = 0; //ELM_ACCESS_ACTION_HIGHLIGHT;
+               /**
+                * @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");
-                               ret = LB_ACCESS_STATUS_ERROR;
+                               ErrPrint("Highlighted object is not found\n");
+                               ret = WIDGET_ACCESS_STATUS_ERROR;
                        } else {
-                               LOGD("Highlighted object is found\n");
-                               ret = LB_ACCESS_STATUS_DONE;
+                               DbgPrint("Highlighted object is found\n");
+                               ret = WIDGET_ACCESS_STATUS_DONE;
                        }
                } else {
-                       LOGE("Action error\n");
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ErrPrint("Action error\n");
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                }
                break;
-       case BUFFER_EVENT_HIGHLIGHT_NEXT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_NEXT:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
-               action_type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+               action_type = 0; //ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
                action_info.highlight_cycle = EINA_FALSE;
                ret = elm_access_action(parent_elm, action_type, &action_info);
-               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_LAST : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_LAST : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_HIGHLIGHT_PREV:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_HIGHLIGHT_PREV:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
-               action_type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+               action_type = 0; //ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
                action_info.highlight_cycle = EINA_FALSE;
                ret = elm_access_action(parent_elm, action_type, &action_info);
-               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_FIRST : LB_ACCESS_STATUS_DONE;
+               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, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = 0; //ELM_ACCESS_ACTION_ACTIVATE;
+               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_ACTION_UP:
+               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 = 0; //ELM_ACCESS_ACTION_UP;
+               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_ACTION_DOWN:
+               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 = 0; //ELM_ACCESS_ACTION_DOWN;
+               ret = elm_access_action(parent_elm, action_type, &action_info);
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_ACTIVATE:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_UP:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
-               action_type = ELM_ACCESS_ACTION_ACTIVATE;
+               action_type = 0; //ELM_ACCESS_ACTION_SCROLL;
+               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) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_ACTION_UP:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_MOVE:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
-               action_type = ELM_ACCESS_ACTION_UP;
+               action_type = 0; //ELM_ACCESS_ACTION_SCROLL;
+               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) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_ACTION_DOWN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_SCROLL_DOWN:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
-               action_type = ELM_ACCESS_ACTION_DOWN;
+               action_type = 0; //ELM_ACCESS_ACTION_SCROLL;
+               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) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_SCROLL_UP:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_UNHIGHLIGHT:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       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_type = 0; //ELM_ACCESS_ACTION_UNHIGHLIGHT;
                ret = elm_access_action(parent_elm, action_type, &action_info);
-               ret = (ret == EINA_FALSE) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_SCROLL_MOVE:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_VALUE_CHANGE:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       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_type = 0; //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) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_SCROLL_DOWN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_MOUSE:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       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_type = 0; //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) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_UNHIGHLIGHT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_BACK:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
                memset(&action_info, 0, sizeof(action_info));
-               action_type = ELM_ACCESS_ACTION_UNHIGHLIGHT;
+               action_type = 0; //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) ? LB_ACCESS_STATUS_ERROR : LB_ACCESS_STATUS_DONE;
+               ret = (ret == EINA_FALSE) ? WIDGET_ACCESS_STATUS_ERROR : WIDGET_ACCESS_STATUS_DONE;
                break;
-       case BUFFER_EVENT_KEY_DOWN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_ACCESS_OVER:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
+                       break;
+               }
+               memset(&action_info, 0, sizeof(action_info));
+               action_type = 0; //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 = 0; //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 = 0; //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 = 0; //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, WIDGET_WIN_TAG);
+               if (!parent_elm) {
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
@@ -301,13 +526,14 @@ static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_
                        DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
                        XFree(key_symbol);
                        XFree(key_name);
+                       XFree(key_string);
                }
-               ret = LB_KEY_STATUS_ERROR;
+               ret = WIDGET_KEY_STATUS_ERROR;
                break;
-       case BUFFER_EVENT_KEY_UP:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_KEY_UP:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
@@ -321,13 +547,14 @@ static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_
                        DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
                        XFree(key_symbol);
                        XFree(key_name);
+                       XFree(key_string);
                }
-               ret = LB_KEY_STATUS_ERROR;
+               ret = WIDGET_KEY_STATUS_ERROR;
                break;
-       case BUFFER_EVENT_KEY_FOCUS_IN:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_KEY_FOCUS_IN:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
@@ -341,13 +568,14 @@ static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_
                        DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
                        XFree(key_symbol);
                        XFree(key_name);
+                       XFree(key_string);
                }
-               ret = LB_KEY_STATUS_ERROR;
+               ret = WIDGET_KEY_STATUS_ERROR;
                break;
-       case BUFFER_EVENT_KEY_FOCUS_OUT:
-               parent_elm = ecore_evas_data_get(info->ee, "dynamic,box,win");
+       case WIDGET_BUFFER_EVENT_KEY_FOCUS_OUT:
+               parent_elm = ecore_evas_data_get(info->ee, WIDGET_WIN_TAG);
                if (!parent_elm) {
-                       ret = LB_ACCESS_STATUS_ERROR;
+                       ret = WIDGET_ACCESS_STATUS_ERROR;
                        break;
                }
 
@@ -361,120 +589,142 @@ static int event_handler_cb(struct livebox_buffer *handler, struct buffer_event_
                        DbgPrint("Key symbol: %s, name: %s\n", key_string, key_name);
                        XFree(key_symbol);
                        XFree(key_name);
+                       XFree(key_string);
                }
-               ret = LB_KEY_STATUS_ERROR;
+               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;
        }
 
        return ret;
 }
 
-static void *alloc_fb(void *data, int size)
+static Eina_Bool pended_event_consumer_cb(void *data)
 {
-       struct info *info = data;
-       void *buffer;
+       vwin_info_t info = data;
+       widget_buffer_event_data_t event_info;
 
-       if (info->ee) {
-               ecore_evas_geometry_get(info->ee, NULL, NULL, &info->w, &info->h);
-               LOGD("Size of ee is updated: %dx%d (info: %p)\n", info->w, info->h, info);
+       event_info = eina_list_nth(info->pended_events_list, 0);
+       if (!event_info) {
+               info->pended_events_consumer = NULL;
+               return ECORE_CALLBACK_CANCEL;
        }
 
-       /*!
-        * Acquire a buffer for canvas.
-        */
-       info->handle = livebox_acquire_buffer_NEW(info->id, info->is_pd,
-                                       info->w, info->h, sizeof(int), (livebox_conf_auto_align() || !s_info.alloc_canvas_with_stride),
-                                       event_handler_cb, info);
-
-       /*!
-        * If it supports the H/W accelerated buffer,
-        * Use it.
-        */
-       if (livebox_support_hw_buffer(info->handle)) {
-               if (livebox_create_hw_buffer(info->handle) == 0) {
-                       buffer = livebox_buffer_hw_buffer(info->handle);
-                       if (buffer) {
-                               LOGD("HW Accelerated buffer is created %p, (%dx%d)\n", info, info->w, info->h);
-                               info->is_hw = 1;
-                               return buffer;
-                       }
-               }
-
-               LOGE("Failed to allocate HW Accelerated buffer\n");
-       }
+       DbgPrint("Consuming delayed events\n");
+       (void)processing_events(info, event_info, event_info->timestamp);
 
-       /*!
-        * Or use the buffer of a S/W backend.
-        */
-       buffer = livebox_ref_buffer(info->handle);
-       LOGD("SW buffer is created (%dx%d)\n", info->w, info->h);
-       info->is_hw = 0;
-       return buffer;
+       info->pended_events_list = eina_list_remove(info->pended_events_list, event_info);
+       free(event_info);
+       return ECORE_CALLBACK_RENEW;
 }
 
-static void *alloc_stride_fb(void *data, int size, int *stride, int *bpp)
+/**
+ * @note
+ * Every user event (mouse) on the buffer will be passed via this event callback
+ */
+static int event_handler_cb(widget_buffer_h handler, widget_buffer_event_data_t event_info, void *data)
 {
-       void *buffer;
+       vwin_info_t info = data;
+       double timestamp;
+
+       /**
+        * @note
+        * If the feeds event is accessibility or key event,
+        * "return 0" will confusing the viewer,
+        * because it will waiting result of event processing to do handles state properly.
+        */
 
-       buffer = alloc_fb(data, size);
-       if (buffer) {
-               struct info *info = data;
-               int _stride;
+       if (!info || info->state != VWIN_INFO_CREATED || !info->handle || info->flags.field.deleted) {
+               /* Just ignore this event */
+               return 0;
+       }
 
-               *bpp = sizeof(int);
-               _stride = livebox_buffer_stride(info->handle);
-               if (_stride < 0) {
-                       _stride = info->w * *bpp;
+       if (event_info->type == WIDGET_BUFFER_EVENT_FRAME_SKIP_CLEARED) {
+               /**
+                * Increase the count_of_rendering only if it meets conditions.
+                * Or do not increase it to prevent from overflow problem.
+                * If we trying to increase the count_of_rendering variable, it could be overflowed.
+                * These conditions will prevents count_of_rendering from overflow issue.
+                */
+               if (info->pended_events_list && !info->pended_events_consumer) {
+                       info->pended_events_consumer = ecore_timer_add(0.0001f, pended_event_consumer_cb, info);
+                       if (info->pended_events_consumer) {
+                               ErrPrint("Failed to create a pended event consumer\n");
+                       }
                }
 
-               *stride = _stride;
-               *bpp <<= 3;
-               DbgPrint("bpp: %d, stride: %d\n", *bpp, *stride);
+               return 0;
        }
 
-       return buffer;
-}
+       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;
 
-static void free_fb(void *data, void *ptr)
-{
-       struct info *info = data;
-
-       if (!info->handle) {
-               return;
-       }
+                       if (gettimeofday(&tv, NULL) < 0) {
+                               ErrPrint("gettimeofday: %d\n", errno);
+                       } else {
+                               timestamp = (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0f;
+                               timestamp -= event_info->timestamp;
 
-       if (info->is_hw) {
-               if (livebox_destroy_hw_buffer(info->handle) == 0) {
-                       LOGD("HW Accelerated buffer is destroyed\n");
+                               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 {
-               LOGD("SW buffer is destroyed, %p\n", info);
-               livebox_unref_buffer(ptr);
-       }
+               if (WIDGET_CONF_EVENT_FILTER > 0.0f && (info->pressed == 0 || event_info->type == WIDGET_BUFFER_EVENT_MOVE)) {
+                       timestamp = ecore_time_get();
 
-       livebox_release_buffer_NEW(info->handle);
-       info->handle = NULL;
+                       timestamp -= event_info->timestamp;
+                       if (timestamp > WIDGET_CONF_EVENT_FILTER) {
+                               DbgPrint("Dropped %lf\n", timestamp);
+                               return 0;
+                       }
+               }
 
-       if (info->deleted) {
-               free(info->id);
-               info->id = NULL;
+               timestamp = event_info->timestamp * 1000.0f;
+       }
 
-               free(info);
+       if ((info->w <= 1 && info->h <= 1) || widget_provider_buffer_frame_skip(info->handle) > 0 || info->pended_events_list) {
+               widget_buffer_event_data_t _ev_info;
+               _ev_info = malloc(sizeof(*_ev_info));
+               if (_ev_info) {
+                       memcpy(_ev_info, event_info, sizeof(*_ev_info));
+                       info->pended_events_list = eina_list_append(info->pended_events_list, _ev_info);
+                       _ev_info->timestamp = timestamp;
+                       /**
+                        * @note
+                        * Push events to pending list,.
+                        * Consuming it first.
+                        */
+                       DbgPrint("Canvas is not prepared. pending the events (%dx%d)\n", info->w, info->h);
+                       return 0;
+               } else {
+                       ErrPrint("malloc: %d\n", errno);
+               }
        }
+
+       return processing_events(info, event_info, timestamp);
 }
 
 static void pre_render_cb(void *data, Evas *e, void *event_info)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
 
-       if (!info->handle) {
+       if (!info || info->state != VWIN_INFO_CREATED || !info->handle) {
                return;
        }
 
-       if (livebox_conf_premultiplied_alpha()) {
+       if (WIDGET_CONF_PREMULTIPLIED_COLOR) {
                Evas_Coord w;
                Evas_Coord h;
 
@@ -482,81 +732,274 @@ static void pre_render_cb(void *data, Evas *e, void *event_info)
                evas_damage_rectangle_add(e, 0, 0, w, h);
        }
 
-       if (info->is_hw) {
-               livebox_buffer_pre_render(info->handle);
+       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 inline void dump_to_file(void *buffer, int size, const char *fname)
+{
+       int fd;
+
+       fd = open(fname, O_WRONLY | O_CREAT, 0644);
+       if (fd >= 0) {
+               if (write(fd, buffer, size) != size) {
+                       ErrPrint("write: %d\n", errno);
+               }
+
+               if (close(fd) < 0) {
+                       ErrPrint("close: %d\n", errno);
+               }
        }
 }
 
 static void post_render_cb(void *data, Evas *e, void *event_info)
 {
-       struct info *info = data;
+       vwin_info_t info = data;
+       const char *ee_key;
 
-       if (!info->handle) {
+       if (!info || info->state != VWIN_INFO_CREATED || !info->handle) {
                return;
        }
 
-       if (livebox_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");
+       ee_key = WIDGET_CONF_EE_KEY_FOR_UPDATE;
+       if (ee_key) {
+               const char *value;
+               value = ecore_evas_data_get(info->ee, ee_key);
+               if (value && strcmp(value, "true")) {
+                       DbgPrint("Frame skipped[%s]\n", value);
                        return;
                }
+               ecore_evas_data_set(info->ee, ee_key, "false");
+       }
+
+       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]) {
+                               break;
+                       }
+               }
+
+               if (idx == WIDGET_CONF_EXTRA_BUFFER_COUNT) {
+                       idx = WIDGET_PRIMARY_BUFFER;
+               }
+
+               /* Send updated event for PRIMARY BUFFER */
+               if (front_resource_id == widget_viewer_get_resource_id(info->handle, idx)) {
+                       if (info->ctrl_mode.dump_to_file) {
+                               char fname[512];
+                               void *canvas;
+
+                               snprintf(fname, sizeof(fname) - 1, "/tmp/%s.%u.%lf.raw", widget_util_basename(info->id), front_resource_id, ecore_time_get());
+                               canvas = widget_provider_buffer_dump_frame(info->handle, idx);
+                               if (canvas) {
+                                       int w, h;
+                                       int size;
+
+                                       ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
+                                       size = w * h * sizeof(int);
+
+                                       dump_to_file(canvas, size, fname);
+                                       free(canvas);
+                               }
+                       }
+                       widget_send_updated_by_idx(info->handle, idx);
+               } else {
+                       DbgPrint("Unable to send updated: %u (%u)\n", front_resource_id, widget_viewer_get_resource_id(info->handle, idx));
+               }
+       } else {
+               if (WIDGET_CONF_PREMULTIPLIED_COLOR) {
+                       void *canvas;
+                       int 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, NULL, NULL, &w, &h);
+                       evas_data_argb_unpremul(canvas, w * h);
+               }
+
+               if (info->ctrl_mode.dump_to_file) {
+                       void *canvas;
+                       char fname[512];
+                       int size;
+                       int w, h;
+
+                       canvas = (void *)ecore_evas_buffer_pixels_get(info->ee);
+                       if (!canvas) {
+                               ErrPrint("Failed to get pixel canvas\n");
+                               return;
+                       }
+
+                       /**
+                        * TODO
+                        * Save to a file
+                        */
+                       ecore_evas_geometry_get(info->ee, NULL, NULL, &w, &h);
+                       size = w * h * sizeof(int);
+
+                       snprintf(fname, sizeof(fname) - 1, "/tmp/%s.%lf.raw", widget_util_basename(info->id), ecore_time_get());
+                       dump_to_file(canvas, size, fname);
+               }
+
+               if (info->type == VWIN_GEM) {
+                       widget_buffer_post_render(info->handle);
+               } else if (info->type == VWIN_SW_BUF) {
+                       widget_viewer_sync_buffer(info->handle);
+               }
+       }
+}
+
+static int pre_ctrl_mode_cb(const char *id, void *data)
+{
+       vwin_info_t info = data;
+       const char *path;
+       int cmd;
+       int value;
+
+       /* Try provider_app first */
+       if (!info || info->state != VWIN_INFO_CREATED || !id || !info->id) {
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
 
-               ecore_evas_geometry_get(info->ee, &x, &y, &w, &h);
-               evas_data_argb_unpremul(canvas, w * h);
+       path = widget_util_uri_to_path(id);
+       if (path && strcmp(info->id, path)) {
+               /* Skip */
+               DbgPrint("SKIP: Pre orientation event callback is called [%s], %s\n", id, info->id);
+               return WIDGET_ERROR_INVALID_PARAMETER;
        }
 
-       if (info->is_hw) {
-               livebox_buffer_post_render(info->handle);
+       widget_get_last_ctrl_mode(path, &cmd, &value);
+
+       if (cmd == WIDGET_CTRL_MODE_DUMP_FRAME) {
+               info->ctrl_mode.dump_to_file = !!value;
+               DbgPrint("CtrlMode: DumpToFile: %d\n", info->ctrl_mode.dump_to_file);
+       }
+
+       return WIDGET_ERROR_NONE;
+}
+
+static int pre_orientation_cb(const char *id, void *data)
+{
+       vwin_info_t info = data;
+       const char *path;
+       int orientation;
+
+       /* Try provider_app first */
+       if (!info || info->state != VWIN_INFO_CREATED || !id || !info->id) {
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
+       path = widget_util_uri_to_path(id);
+       if (path && strcmp(info->id, path)) {
+               /* Skip */
+               DbgPrint("SKIP: Pre orientation event callback is called [%s], %s\n", id, info->id);
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
+       DbgPrint("Pre orientation event callback is called [%s]\n", id);
+       orientation = widget_get_orientation(path);
+       if (orientation < 0) {
+               ErrPrint("Failed to get orientation: %X\n", orientation);
        } else {
-               livebox_sync_buffer(info->handle);
+               info->orientation = orientation;
+       }
+
+       return WIDGET_ERROR_NONE;
+}
+
+static int pre_destroy_cb(const char *id, void *data)
+{
+       vwin_info_t info = data;
+       const char *path = NULL;
+
+       if (!info || info->state != VWIN_INFO_CREATED) {
+               return WIDGET_ERROR_INVALID_PARAMETER;
+       }
+
+       if (id) {
+               path = widget_util_uri_to_path(id);
+
+               if (path && strcmp(info->id, path)) {
+                       /* Skip */
+                       DbgPrint("SKIP: Pre destroy event callback is called [%s], %s\n", id, info->id);
+                       return WIDGET_ERROR_INVALID_PARAMETER;
+               }
        }
+
+       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);
+       }
+
+       return WIDGET_ERROR_NONE;
 }
 
 static void ecore_evas_free_cb(Ecore_Evas *ee)
 {
-       struct info *info;
+       vwin_info_t info;
 
-       info = ecore_evas_data_get(ee, "dynamic,box,info");
+       info = ecore_evas_data_get(ee, WIN_INFO_TAG);
        if (!info) {
-               LOGD("Info is not valid\n");
+               DbgPrint("Info is not valid\n");
                return;
        }
 
+       if (info->pended_events_consumer) {
+               widget_buffer_event_data_t event_info;
+
+               DbgPrint("Clearing pended event consumer\n");
+               ecore_timer_del(info->pended_events_consumer);
+               info->pended_events_consumer = NULL;
+
+               EINA_LIST_FREE(info->pended_events_list, event_info) {
+                       free(event_info);
+               }
+       }
+
+       widget_del_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
+       widget_del_pre_callback(WIDGET_PRE_CTRL_MODE_CALLBACK, pre_ctrl_mode_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->flags.field.deleted = 1;
        info->ee = NULL;
 }
 
-PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
+#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;
-       Evas_Object *rect;
-
-       if (!s_info.alloc_canvas && !s_info.alloc_canvas_with_stride) {
-               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");
-               }
+       vwin_info_t info;
+       int orientation;
 
-               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) {
-                       ErrPrint("No way to allocate canvas\n");
-                       return NULL;
-               }
-       }
+       /**
+        * @TODO
+        * If the evas object is already created,
+        * this function should returns ERROR.
+        */
 
        if (!id) {
                ErrPrint("Invalid parameter\n");
@@ -565,38 +1008,65 @@ PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
 
        info = calloc(1, sizeof(*info));
        if (!info) {
-               ErrPrint("Heap: %s\n", strerror(errno));
+               ErrPrint("Heap: %d\n", errno);
                return NULL;
        }
 
+       info->state = VWIN_INFO_CREATED;
+
        info->id = strdup(id);
        if (!info->id) {
-               ErrPrint("Heap: %s\n", strerror(errno));
+               ErrPrint("Heap: %d\n", errno);
+               info->state = VWIN_INFO_DESTROYED;
                free(info);
                return NULL;
        }
 
-       info->is_pd = is_pd;
+#ifdef WIDGET_FEATURE_GBAR_SUPPORTED
+       info->flags.field.is_gbar = is_gbar;
+#else
+       info->flags.field.is_gbar = 0;
+#endif /* WIDGET_FEATURE_GBAR_SUPPORTED */
 
-       /*!
-        * Size information must be initialized before call the ecore_evas_buffer_new.
+       /**
+        * Acquire a buffer for canvas.
         */
-       info->w = 1;
-       info->h = 1;
+       info->handle = widget_create_buffer(info->id, info->flags.field.is_gbar,
+                       binder_widget_auto_align(),
+                       event_handler_cb, info);
 
-       if (!livebox_conf_auto_align() && s_info.alloc_canvas_with_stride) {
-               info->ee = s_info.alloc_canvas_with_stride(1, 1, alloc_stride_fb, free_fb, info);
-       } else {
-               info->ee = s_info.alloc_canvas(1, 1, alloc_fb, free_fb, info);
+       if (!info->handle) {
+               ErrPrint("Failed to create a widget buffer\n");
+               info->state = VWIN_INFO_DESTROYED;
+               free(info->id);
+               free(info);
+               return NULL;
        }
 
+       /**
+        * Size information must be initialized before call the ecore_evas_buffer_new.
+        */
+       info->w = WIDGET_DEFAULT_WIDTH;
+       info->h = WIDGET_DEFAULT_HEIGHT;
+
+       info->ee = binder_ecore_evas_new(info);
        if (!info->ee) {
-               ErrPrint("Failed to create ecore_evas (%dx%d)\n", 1, 1);
+               ErrPrint("Failed to create ecore_evas (%dx%d)\n", info->w, info->h);
+               widget_destroy_buffer(info->handle);
+               info->state = VWIN_INFO_DESTROYED;
                free(info->id);
                free(info);
                return NULL;
        }
 
+       ecore_evas_data_set(info->ee, WIN_INFO_TAG, info);
+
+       /**
+        * @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) {
                ErrPrint("Failed to get evas\n");
@@ -604,29 +1074,28 @@ PUBLIC Evas_Object *livebox_get_evas_object(const char *id, int is_pd)
                return NULL;
        }
 
-       ecore_evas_data_set(info->ee, "dynamic,box,info", info);
-
        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, 1, 1);
+       ecore_evas_resize(info->ee, info->w, info->h);
 
-       ecore_evas_callback_pre_free_set(info->ee, ecore_evas_free_cb);
        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);
 
-       rect = evas_object_rectangle_add(info->e);
-       if (!rect) {
-               ErrPrint("Failed to create evas_object\n");
-               ecore_evas_free(info->ee);
-               return NULL;
+       widget_add_pre_callback(WIDGET_PRE_DESTROY_CALLBACK, pre_destroy_cb, info);
+       widget_add_pre_callback(WIDGET_PRE_ORIENTATION_CALLBACK, pre_orientation_cb, info);
+       widget_add_pre_callback(WIDGET_PRE_CTRL_MODE_CALLBACK, pre_ctrl_mode_cb, info);
+
+       orientation = widget_get_orientation(info->id);
+       if (orientation < 0) {
+               ErrPrint("Failed to get orientation[%s]: %X\n", info->id, orientation);
+       } else {
+               info->orientation = orientation;
        }
 
-       evas_object_resize(rect, 1, 1);
-       evas_object_color_set(rect, 0, 0, 0, 0);
-       return rect;
+       return info->e;
 }
 
 /* End of a file */