+}
+
+static Eina_Bool pended_event_consumer_cb(void *data)
+{
+ vwin_info_t info = data;
+ widget_buffer_event_data_t event_info;
+
+ event_info = eina_list_nth(info->pended_events_list, 0);
+ if (!event_info) {
+ info->pended_events_consumer = NULL;
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ DbgPrint("Consuming delayed events\n");
+ (void)processing_events(info, event_info, event_info->timestamp);
+
+ info->pended_events_list = eina_list_remove(info->pended_events_list, event_info);
+ free(event_info);
+ return ECORE_CALLBACK_RENEW;
+}
+
+/**
+ * @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)
+{
+ 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.
+ */
+
+ if (!info || info->state != VWIN_INFO_CREATED || !info->handle || info->deleted) {
+ /* Just ignore this event */
+ return 0;
+ }
+
+ 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");
+ }
+ }
+
+ return;
+ }
+
+ 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: %d\n", 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;
+ }
+
+ 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);