Extract some functions out of sclcontroller.cpp 14/316414/3
authorJi-hoon Lee <dalton.lee@samsung.com>
Wed, 21 Aug 2024 05:16:22 +0000 (14:16 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Wed, 21 Aug 2024 09:07:52 +0000 (18:07 +0900)
Change-Id: Id7e6b18dddbb1832bd31cd5a8af22fa38a447681

CMakeLists.txt
scl/sclcontroller.cpp
scl/sclcontroller.h
scl/sclcontroller_button.cpp [new file with mode: 0644]
scl/sclcontroller_button.h [new file with mode: 0644]
scl/sclcontroller_mouse.cpp [new file with mode: 0644]
scl/sclcontroller_mouse.h [new file with mode: 0644]
scl/sclevents-efl.cpp
scl/sclevents.cpp
scl/sclwindows.cpp

index 0b4c74a..20ebdc2 100644 (file)
@@ -34,6 +34,8 @@ SET(SRCS
     scl/scldebug.cpp
     scl/sclutils.cpp
     scl/sclcontroller.cpp
+    scl/sclcontroller_button.cpp
+    scl/sclcontroller_mouse.cpp
     scl/sclgwes.cpp
     scl/sclevents.cpp
     scl/sclwindows-efl.cpp
index e7ff6d0..ef62cf3 100644 (file)
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include "sclcontroller.h"
+#include "sclcontroller_button.h"
 #include "scldebug.h"
 #include "sclresourcecache.h"
 #include "sclactionstate.h"
@@ -387,3024 +388,6 @@ CSCLController::check_magnifier_available(sclwindow window, sclbyte key_index, s
     return ret;
 }
 
-sclboolean
-CSCLController::process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
-                                             scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-
-    sclboolean ret = FALSE;
-    sclboolean redraw = FALSE;
-
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLEvents *events = CSCLEvents::get_instance();
-    CSCLUtils *utils = CSCLUtils::get_instance();
-    CSCLFeedback *feedback = CSCLFeedback::get_instance();
-    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
-    if (!sclres_manager) return FALSE;
-
-    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
-    PSclLayout sclres_layout = sclres_manager->get_layout_table();
-    if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
-
-    SclButtonContext *button_context = NULL;
-    const SclLayoutKeyCoordinate *coordinate = NULL;
-
-    if (context && cache) {
-        button_context = cache->get_cur_button_context(window, key_index);
-        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
-    }
-
-    if (context && cache && windows && events && utils && feedback && handler && button_context && coordinate) {
-        /* First check if this button is enabled in current active sublayout */
-        sclboolean sub_layout_match = TRUE;
-        if (coordinate->sub_layout && context->get_cur_sublayout()) {
-            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
-                sub_layout_match = FALSE;
-            }
-        }
-
-        /* If this button is pressed */
-        if ( x >= coordinate->x - coordinate->add_hit_left &&
-                x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
-                y >= coordinate->y - coordinate->add_hit_top &&
-                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
-                /* Process the event only if the this item's sublayout id is active one */
-                sub_layout_match ) {
-            /* If currently shift mode is ON, and the last key was multitap, this means the shift did not
-               turned off because of multitap button. So we need to turn it off here forcibly */
-            sclwindow last_win = context->get_last_event_fired_window();
-            scl8 last_key = context->get_last_event_fired_key();
-            LOGD("last_win : %p last_key : :%d", last_win, last_key);
-            const SclLayoutKeyCoordinate *last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
-            if (last_coordinate) {
-                LOGD("last_coordinate->button_type : %d", last_coordinate->button_type);
-                if (last_coordinate->button_type == BUTTON_TYPE_MULTITAP && context->get_shift_state() == SCL_SHIFT_STATE_ON) {
-                    /* And if the multitap button was different from the one we are dealing with... */
-                    LOGD("last_win %p window %p last_key %d key_index %d", last_win, window, last_key, key_index);
-                    if (last_win != window || last_key != key_index) {
-                        SclNotiShiftStateChangeDesc desc;
-                        desc.ui_event_desc = NULL;
-                        desc.shift_state = SCL_SHIFT_STATE_OFF;
-
-                        SCLEventReturnType ret = handler->on_event_notification(SCL_UINOTITYPE_SHIFT_STATE_CHANGE, &desc);
-                        if (ret == SCL_EVENT_PASS_ON) {
-                            context->set_shift_state(SCL_SHIFT_STATE_OFF);
-                            windows->update_window(windows->get_base_window());
-                        }
-                    }
-                }
-            }
-
-            /* If newly pressed key has type MULTI_TOUCH_TYPE_EXCLUSIVE, release all existing pressed events */
-            if (actual_event) {
-                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_EXCLUSIVE) {
-                    /* When calling mouse_release, the seq order of current multitouch events will be changed,
-                    so we put all the multitouch events into a vector and use them afterwards forreleasing */
-                    sclint loop = 0;
-                    sclint multi_touch_context_num = context->get_multi_touch_context_num();
-                    std::vector<SclUIEventDesc> multi_touch_events;
-                    for (loop = 0;loop < multi_touch_context_num;loop++) {
-                        SclUIEventDesc desc;
-                        context->get_multi_touch_event(loop, &desc);
-                        multi_touch_events.push_back(desc);
-                    }
-                    for (loop = 0;loop < multi_touch_context_num;loop++) {
-                        SclUIEventDesc desc = multi_touch_events[loop];
-                        if (desc.touch_id != touch_id) {
-                            mouse_release(context->get_cur_moving_window(desc.touch_id),
-                                context->get_cur_moving_point(desc.touch_id).x,
-                                context->get_cur_moving_point(desc.touch_id).y,
-                                desc.touch_id, FALSE);
-                        }
-                    }
-                }
-            }
-
-            /* Make an unique ID for timer */
-            const scl16 uniqId = utils->get_unique_id();
-
-            context->set_cur_pressed_event_id(touch_id, uniqId);
-            context->set_cur_pressed_key(touch_id, key_index);
-            context->set_cur_pressed_window(touch_id, window);
-
-            button_context->state = BUTTON_STATE_PRESSED;
-
-            if (context->get_highlight_ui_enabled()) {
-                CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
-                if (focus_handler) {
-                    sclwindow prev_window = focus_handler->get_current_focus_window();
-                    scl8 prev_key = focus_handler->get_current_focus_key();
-                    const SclLayoutKeyCoordinate *prev_coordinate =
-                        cache->get_cur_layout_key_coordinate(prev_window, prev_key);
-
-                    focus_handler->set_current_focus(window, key_index);
-
-                    if (prev_coordinate) {
-                        windows->update_window(prev_window,
-                            prev_coordinate->x, prev_coordinate->y, prev_coordinate->width, prev_coordinate->height);
-                    }
-                }
-            }
-
-            redraw = TRUE;
-            ret = TRUE;
-
-#ifndef DIRECTLY_DRAW_ON_EVENTS
-            /* If the window doesn't get exposed before corresponding release event,
-             * the inverted state of a button will never be drawn onto screen.
-             * To prevent such a case, we draw the inverted state of button forcefully and directly,
-             * without waiting for expose event */
-            /*CSCLGraphics *grps = CSCLGraphics::get_instance();
-            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
-            scldrawctx draw_ctx = grps->begin_paint(window, TRUE);
-            builder->draw_button(window, draw_ctx, key_index, button_context->state, TRUE);
-            grps->end_paint(window, draw_ctx);*/
-#endif
-
-            /* for feedback */
-            feedback->button_pressed(window, key_index);
-
-            /* Special routine for autopopup */
-            if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
-                events->create_timer(SCL_TIMER_AUTOPOPUP, m_autopopup_key_duration, uniqId);
-            } else {
-                /* for long key & repeat key */
-                events->create_timer(SCL_TIMER_LONGKEY, m_long_key_duration, uniqId);
-            }
-
-            SCLShiftState shift_index = context->get_shift_state();
-            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-            if (context->get_caps_lock_mode()) {
-                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-            }
-
-            SclUIEventDesc key_event_desc;
-            key_event_desc.key_value = coordinate->key_value[shift_index][0];
-            key_event_desc.key_event = coordinate->key_event[shift_index][0];
-            key_event_desc.key_type = coordinate->key_type;
-            key_event_desc.key_modifier = KEY_MODIFIER_NONE;
-            key_event_desc.event_type = EVENT_TYPE_PRESS;
-
-            SclPoint curpoint = {x, y};
-            key_event_desc.touch_id = touch_id;
-            key_event_desc.mouse_pressed_point = curpoint;
-            key_event_desc.mouse_current_point = curpoint;
-            key_event_desc.mouse_farthest_point = curpoint;
-
-            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-            SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
-
-            /* Only if the handler didn't return SCL_EVENT_DONE */
-            if (processed == SCL_EVENT_PASS_ON) {
-                /* Now process normal behaviours of each button type */
-                switch (coordinate->button_type) {
-                case BUTTON_TYPE_NORMAL:
-                case BUTTON_TYPE_GRAB:
-                case BUTTON_TYPE_SELFISH:
-                case BUTTON_TYPE_DIRECTION:
-                case BUTTON_TYPE_RELATIVE_DIRECTION: {
-                    /* Send click event right away if this button uses repeat key */
-                    if (coordinate->use_repeat_key) {
-                        handler->on_event_key_clicked(key_event_desc);
-                    }
-                }
-                break;
-                case BUTTON_TYPE_MULTITAP: {
-                }
-                break;
-                case BUTTON_TYPE_ROTATION: {
-                }
-                break;
-                case BUTTON_TYPE_DRAG: {
-                    /* Drag buttons fires click event immediately when they are pressed */
-                    handler->on_event_key_clicked(key_event_desc);
-                }
-                break;
-                case BUTTON_TYPE_UIITEM: break;
-                case MAX_BUTTON_TYPE: break;
-                default: break;
-                }
-                switch (coordinate->popup_type) {
-                case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: {
-                    SclNotiPopupOpeningDesc desc;
-                    desc.ui_event_desc = &key_event_desc;
-                    desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
-                    if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
-                        sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
-                        SCLDisplayMode display_mode = context->get_display_mode();
-                        /* FIXME */
-                        //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
-                        if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
-                            scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
-                            sclshort popupLayoutId =
-                                sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
-                            SclRectangle popupRect;
-                            SclRectangle baseWndRect;
-                            SclLayout *layout = NULL;
-                            /* FIXME */
-                            //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
-                            if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
-                                layout = &sclres_layout[popupLayoutId];
-                            }
-                            if (layout) {
-                                windows->get_window_rect(windows->get_base_window(), &baseWndRect);
-                                popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
-                                popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
-                                //popupRect.width = utils->get_scale_x(layout->width);
-                                //popupRect.height= utils->get_scale_y(layout->height);
-                                if (!(sclres_manager->loaded(popupLayoutId))) {
-                                    sclres_manager->load(popupLayoutId);
-                                }
-                                popupRect.width = layout->width;
-                                popupRect.height = layout->height;
-                                windows->close_all_popups();
-
-                                SclWindowOpener opener;
-                                opener.window = window;
-                                opener.key = key_index;
-
-                                sclwindow popup_window = windows->open_popup(opener,
-                                    popupRect,
-                                    popup_input_mode,
-                                    popupLayoutId,
-                                    coordinate->popup_type,
-                                    sclres_input_mode_configure[popup_input_mode].use_virtual_window,
-                                    sclres_input_mode_configure[popup_input_mode].use_dim_window,
-                                    coordinate->extract_offset_x,
-                                    coordinate->extract_offset_y,
-                                    sclres_input_mode_configure[popup_input_mode].timeout);
-
-                                SclNotiPopupOpenedDesc opened_desc;
-                                opened_desc.ui_event_desc = &key_event_desc;
-                                opened_desc.input_mode = desc.input_mode;
-                                opened_desc.window = popup_window;
-                                handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
-
-                                windows->hide_window(windows->get_magnifier_window());
-                                /* FIXME : The parent key should be turned back to NORMAL state when RELEASED,
-                                    in case of POPUP_TYPE_BTN_PRESS_POPUP_DRAG type. Temporarily setting NORMAL here. */
-                                button_context->state = BUTTON_STATE_NORMAL;
-                                _play_tts_for_input_mode_name(popup_input_mode);
-                            }
-                        }
-                    }
-                }
-                break;
-                case POPUP_TYPE_BTN_RELEASE_POPUP:
-                case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
-                case POPUP_TYPE_BTN_LONGPRESS_POPUP:
-                case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
-                case POPUP_TYPE_AUTO_POPUP:
-                case POPUP_TYPE_NONE:
-                case MAX_POPUP_TYPE:
-                default:
-                    /* Nothing to do in here */
-                    break;
-                }
-            }
-
-            /* Shows the magnifier window(the magnifier window will display when a kind of button type is character) */
-            //if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
-            if (coordinate->use_magnifier) {
-                sclboolean showMagnifier = check_magnifier_available(window, key_index, touch_id);
-
-                PSclMagnifierWndConfigure magnifier_configure = NULL;
-                if (sclres_manager) {
-                    magnifier_configure = sclres_manager->get_magnifier_configure();
-                }
-                if (showMagnifier && magnifier_configure) {
-                    SclPoint pos = {0, 0};
-                    /* calculates x position to be set */
-                    pos.x = (coordinate->x + (coordinate->width / 2)) -
-                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
-                    /* calculates y position to be set */
-                    sclint scnWidth, scnHeight;
-                    utils->get_screen_resolution(&scnWidth, &scnHeight);
-
-                    pos.y = coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
-
-                    /* FIXME : Temporary way of clearing magnifier window */
-                    /*SclWindowContext *window_context = windows->get_window_context(windows->get_magnifier_window(), FALSE);
-                    sclboolean clearmagwin = FALSE;
-                    if (window_context) {
-                        clearmagwin = !(window_context->hidden);
-                    }
-                    static int clearnum = 0;
-                    if (key_index == prevkey && window == prevwin) {
-                        clearmagwin = FALSE;
-                    }
-                    if (clearmagwin) {
-                        if (++clearnum > 1) {
-                            clearmagwin = FALSE;
-                        }
-                    } else {
-                        clearnum = 0;
-                    }
-
-                    if (clearmagwin) {
-                        CSCLGraphics *graphics = CSCLGraphics::get_instance();
-                        CSCLUtils *utils = CSCLUtils::get_instance();
-                        sclchar composed_path[_POSIX_PATH_MAX] = {0,};
-                        scldrawctx draw_ctx = graphics->begin_paint(windows->get_magnifier_window());
-                        utils->get_composed_path(composed_path, scl_magnifier_configure.bg_image_path);
-                        graphics->draw_image(windows->get_magnifier_window(), draw_ctx, composed_path, 0, 0);
-                        graphics->end_paint(windows->get_magnifier_window(), draw_ctx);
-                    }
-                    */
-                    windows->hide_window(windows->get_magnifier_window());
-
-                    SclWindowContext *window_context = windows->get_window_context(window);
-                    if (window_context) {
-                        pos.x += window_context->geometry.x;
-                        pos.y += window_context->geometry.y;
-                    }
-
-                    if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
-                        pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
-                    }
-                    if (pos.x > scnWidth +
-                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                        magnifier_configure->width * utils->get_custom_scale_rate_x()) {
-                        pos.x = scnWidth + magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                            magnifier_configure->width * utils->get_custom_scale_rate_x();
-                    }
-                    pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
-                    pos.x += coordinate->magnifier_offset_x;
-                    pos.y += coordinate->magnifier_offset_y;
-                    windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
-                    //windows->resize_window(windows->get_magnifier_window(), utils->get_scale_x(scl_magnifier_configure.width), utils->get_scale_y(scl_magnifier_configure.height));
-                    /*If we use transient_for them the ISE will occur some crash. It needs to check X11 */
-                    /*windows->set_parent(windows->get_base_window(), windows->get_magnifier_window());*/
-
-                    windows->show_window(windows->get_magnifier_window(), TRUE);
-                    //windows->update_window(windows->get_magnifier_window());
-                }
-#if 0
-                static int fFirst = true;
-                if (fFirst) {
-                    windows->show_window(windows->get_magnifier_window());
-                    fFirst = false;
-                } else {
-                    windows->update_window(windows->get_magnifier_window());
-                }
-#endif
-                /* We cannot use move_resize_window. It had occured some wrong behavior */
-                /*windows->move_resize_window(windows->get_magnifier_window(), pos.x, pos.y, scl_magnifier_configure.width, scl_magnifier_configure.height);*/
-                if (!showMagnifier) {
-                    windows->hide_window(windows->get_magnifier_window());
-                }
-            }
-        } else {
-            /* COMMENTED OUT FOR TESTING MULTITOUCH!! */
-            ///* In case the current button is not the given key index */
-            //if (button_context->state == BUTTON_STATE_PRESSED) {
-            //    /* Even if the press event occurs outside of this button's physical area, reset its context */
-            //    button_context->state = BUTTON_STATE_NORMAL;
-            //    redraw = TRUE;
-            //}
-            /* BUTTON_TYPE_MULTITAP type button should restore its multikey index when another button is clicked */
-            if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
-                button_context->multitap_index = 0;
-            }
-        }
-
-        /* If there is any need for redrawing */
-        if (redraw) {
-#ifdef DIRECTLY_DRAW_ON_EVENTS
-            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
-            if (builder) {
-                builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
-            }
-#else
-            if (windows) {
-                windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
-            }
-#endif
-        }
-    }
-
-    return ret;
-}
-
-sclboolean
-CSCLController::process_button_long_pressed_event(sclwindow window, sclbyte key_index,
-                                                  scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-
-    sclboolean ret = FALSE;
-
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLActionState *state = CSCLActionState::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
-    if (!sclres_manager) return FALSE;
-
-    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
-    PSclLayout sclres_layout = sclres_manager->get_layout_table();
-
-    if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
-
-    if (context && cache && handler && windows && state) {
-        const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
-        SclButtonContext *button_context = cache->get_cur_button_context(window, key_index);
-
-        /* Should return FALSE if this key does not have any longkey related property */
-        if (coordinate) {
-            if (actual_event) {
-                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
-                    /* When calling mouse_release, the seq order of current multitouch events will be changed,
-                       so we put all the multitouch events into a vector and use them afterwards for releasing */
-                    sclboolean finished = FALSE;
-                    sclint loop = 0;
-                    sclint multi_touch_context_num = context->get_multi_touch_context_num();
-                    std::vector<SclUIEventDesc> multitouch_events;
-                    for (loop = 0;loop < multi_touch_context_num;loop++) {
-                        SclUIEventDesc desc;
-                        context->get_multi_touch_event(loop, &desc);
-                        multitouch_events.push_back(desc);
-                    }
-                    for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
-                        SclUIEventDesc desc = multitouch_events[loop];
-                        if (desc.touch_id != touch_id) {
-                            sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
-                            scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
-                            const SclLayoutKeyCoordinate *cur_pressed_coordinate =
-                                cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
-                            if (cur_pressed_coordinate) {
-                                if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
-                                    mouse_release(context->get_cur_moving_window(desc.touch_id),
-                                        context->get_cur_moving_point(desc.touch_id).x,
-                                        context->get_cur_moving_point(desc.touch_id).y,
-                                        desc.touch_id, FALSE);
-                                }
-                            }
-                        } else {
-                            finished = TRUE;
-                        }
-                    }
-                }
-            }
-        }
-
-        /* Should return FALSE if this key does not have any longkey related property */
-        if (coordinate) {
-            if (coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP ||
-                coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE ) {
-                    SclUIEventDesc key_event_desc;
-                    key_event_desc.key_type = coordinate->long_key_type;
-                    if (coordinate->long_key_value == NULL && coordinate->long_key_event == 0) {
-                        SCLShiftState shift_index = context->get_shift_state();
-                        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-                        if (context->get_caps_lock_mode()) {
-                            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-                        }
-
-                        key_event_desc.key_value = coordinate->key_value[shift_index][0];
-                        key_event_desc.key_event = coordinate->key_event[shift_index][0];
-                    } else {
-                        key_event_desc.key_value = coordinate->long_key_value;
-                        key_event_desc.key_event = coordinate->long_key_event;
-                    }
-                    key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
-
-                    key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
-                    key_event_desc.touch_id = touch_id;
-                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                    SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
-
-                    /* Only if the handler didn't return SCL_EVENT_DONE */
-                    if (processed == SCL_EVENT_PASS_ON) {
-                        SclRectangle popupRect;
-                        SclRectangle baseWndRect;
-                        windows->get_window_rect(windows->get_base_window(), &baseWndRect);
-                        popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
-                        popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
-
-                        SclNotiPopupOpeningDesc desc;
-                        desc.ui_event_desc = &key_event_desc;
-                        desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
-                        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
-                            sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
-                            SCLDisplayMode display_mode = context->get_display_mode();
-                            /* FIXME */
-                            //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
-                            if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
-                                scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
-                                SclLayout *layout = NULL;
-                                sclshort popupLayoutId =
-                                    sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
-                                /* FIXME */
-                                //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
-                                if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
-                                    layout = &sclres_layout[popupLayoutId];
-                                }
-                                if (layout) {
-                                    //popupRect.width = utils->get_scale_x(layout->width);
-                                    //popupRect.height= utils->get_scale_y(layout->height);
-                                    if (!(sclres_manager->loaded(popupLayoutId))) {
-                                        sclres_manager->load(popupLayoutId);
-                                    }
-                                    popupRect.width = layout->width;
-                                    popupRect.height = layout->height;
-
-                                    SclWindowOpener opener;
-                                    opener.window = window;
-                                    opener.key = key_index;
-
-                                    sclwindow popup_window = windows->open_popup(
-                                        opener,
-                                        popupRect,
-                                        popup_input_mode,
-                                        popupLayoutId,
-                                        coordinate->popup_type,
-                                        sclres_input_mode_configure[popup_input_mode].use_virtual_window,
-                                        sclres_input_mode_configure[popup_input_mode].use_dim_window,
-                                        coordinate->extract_offset_x,
-                                        coordinate->extract_offset_y,
-                                        sclres_input_mode_configure[popup_input_mode].timeout);
-
-                                    SclNotiPopupOpenedDesc opened_desc;
-                                    opened_desc.ui_event_desc = &key_event_desc;
-                                    opened_desc.input_mode = desc.input_mode;
-                                    opened_desc.window = popup_window;
-                                    handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
-
-                                    windows->hide_window(windows->get_magnifier_window());
-                                    _play_tts_for_input_mode_name(popup_input_mode);
-                                    ret = TRUE;
-                                }
-                            }
-                        }
-                    }
-            } else if (coordinate->long_key_value) {
-                if (strlen(coordinate->long_key_value) > 0) {
-                        if (windows->is_base_window(window)) {
-                            state->set_cur_action_state(ACTION_STATE_BASE_LONGKEY);
-                        } else {
-                            state->set_cur_action_state(ACTION_STATE_POPUP_LONGKEY);
-                        }
-                        ret = TRUE;
-
-                        PSclMagnifierWndConfigure magnifier_configure = NULL;
-                        if (sclres_manager) {
-                            magnifier_configure = sclres_manager->get_magnifier_configure();
-                        }
-                        if (coordinate->use_long_key_magnifier && magnifier_configure) {
-                            CSCLUtils *utils = CSCLUtils::get_instance();
-                            SclPoint pos = {0, 0};
-
-                            const SclLayout* layout = cache->get_cur_layout(window);
-                            if (utils && layout) {
-                                sclint scnWidth, scnHeight;
-                                utils->get_screen_resolution(&scnWidth, &scnHeight);
-
-                                //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
-                                SclWindowContext *window_context = windows->get_window_context(window);
-                                if (window_context) {
-                                    pos.x = window_context->geometry.x + (coordinate->x + (coordinate->width / 2)) -
-                                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-                                    pos.y = window_context->geometry.y + coordinate->y -
-                                        magnifier_configure->height * utils->get_custom_scale_rate_y();
-                                }
-                                if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
-                                    pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
-                                }
-                                if (pos.x > scnWidth +
-                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                                    magnifier_configure->width * utils->get_custom_scale_rate_x()) {
-                                    pos.x = scnWidth +
-                                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                                        magnifier_configure->width * utils->get_custom_scale_rate_x();
-                                }
-                                pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
-                                pos.x += coordinate->magnifier_offset_x;
-                                pos.y += coordinate->magnifier_offset_y;
-                                windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
-                                windows->update_window(windows->get_magnifier_window());
-                                windows->show_window(windows->get_magnifier_window(), TRUE);
-                            }
-                        }
-
-                        SclUIEventDesc key_event_desc;
-                        key_event_desc.key_type = coordinate->long_key_type;
-                        key_event_desc.key_value = coordinate->long_key_value;
-                        key_event_desc.key_event = coordinate->long_key_event;
-                        key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
-
-                        key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
-                        key_event_desc.touch_id = touch_id;
-                        key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                        key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                        key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                        key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                        handler->on_event_key_clicked(key_event_desc);
-                    //}
-                }
-            }
-        }
-        if (ret) {
-            context->set_cur_key_modifier(touch_id, KEY_MODIFIER_LONGKEY);
-            if (coordinate && button_context) {
-                if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
-                    button_context->multitap_index = 0;
-                }
-            }
-        }
-    }
-    /* Longkey processing in here */
-    return ret;
-}
-
-sclboolean
-CSCLController::process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
-                                                    scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-
-    if (context && cache && windows && handler) {
-        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
-
-        SCLShiftState shift_index = context->get_shift_state();
-        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-        if (context->get_caps_lock_mode()) {
-            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-        }
-
-        if (coordinate) {
-            switch (coordinate->button_type) {
-                case BUTTON_TYPE_NORMAL:
-                case BUTTON_TYPE_GRAB:
-                case BUTTON_TYPE_SELFISH:
-                case BUTTON_TYPE_DIRECTION:
-                case BUTTON_TYPE_RELATIVE_DIRECTION: {
-                    /* This is for enabling backspace key in search layout*/
-                    //if (coordinate->key_type != KEY_TYPE_MODECHANGE && coordinate->key_type != KEY_TYPE_COMPOSITION) {
-                    //if (coordinate->key_type != KEY_TYPE_MODECHANGE || coordinate->key_event[0][0] == MVK_BackSpace) {
-                    if (coordinate->key_type != KEY_TYPE_MODECHANGE) {
-                        sclulong repeatKeyEvent = coordinate->key_event[shift_index][0];
-
-                        /* In case of Delete key, Change from Char deletion to Word deletion
-                           when the input acceleration speed is reached to Max */
-                        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-                        PSclDefaultConfigure default_configure = NULL;
-                        if (sclres_manager) {
-                            default_configure = sclres_manager->get_default_configure();
-                        }
-                        if (default_configure) {
-                            if (default_configure->use_word_deletion) {
-                                scllong interval = m_repeat_key_duration - (m_key_repeated_num * SCL_REPEATKEY_ACCELERATION);
-                                if (repeatKeyEvent == MVK_BackSpace &&
-                                    interval <= SCL_REPEATKEY_WORD_DELETION_START_DURATION) {
-                                    repeatKeyEvent = MVK_3270_DeleteWord;
-                                }
-                            }
-                        }
-
-                        SclUIEventDesc key_event_desc;
-                        key_event_desc.key_value = coordinate->key_value[shift_index][0];
-                        key_event_desc.key_event = repeatKeyEvent;
-                        key_event_desc.key_type = coordinate->key_type;
-                        key_event_desc.key_modifier = KEY_MODIFIER_NONE;
-
-                        key_event_desc.event_type = EVENT_TYPE_REPEAT;
-                        key_event_desc.touch_id = touch_id;
-                        key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                        key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                        key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                        key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                        handler->on_event_key_clicked(key_event_desc);
-                    }
-                }
-                break;
-                case BUTTON_TYPE_UIITEM: break;
-                case MAX_BUTTON_TYPE: break;
-                default: break;
-            }
-        }
-    }
-
-    /* Longkey processing in here */
-    return TRUE;
-}
-
-sclboolean
-CSCLController::process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
-                                          scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-
-    sclboolean ret = FALSE;
-
-    CSCLUtils *utils = CSCLUtils::get_instance();
-    CSCLEvents *events = CSCLEvents::get_instance();
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLFeedback *feedback = CSCLFeedback::get_instance();
-    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-
-    SclButtonContext *button_context = NULL;
-
-    const SclLayoutKeyCoordinate *coordinate = NULL;
-
-    if (cache) {
-        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
-        button_context = cache->get_cur_button_context(window, key_index);
-    }
-
-    if (button_context && coordinate && feedback && utils && context && handler && cache && events && windows) {
-        /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
-        sclint thresholdX = 0;
-        sclint thresholdY = 0;
-        if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
-            thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
-            thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
-        }
-
-        /* First check if this button is enabled in current active sublayout */
-        sclboolean subLayoutMatch = TRUE;
-        if (coordinate->sub_layout && context->get_cur_sublayout()) {
-            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
-                subLayoutMatch = FALSE;
-            }
-        }
-        if ( x >= coordinate->x - coordinate->add_hit_left  - thresholdX &&
-            x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX&&
-                y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
-                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
-                subLayoutMatch ) {
-            ret = TRUE;
-
-            SCLShiftState shift_index = context->get_shift_state();
-            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-            if (context->get_caps_lock_mode()) {
-                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-            }
-
-            const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
-
-            sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
-            scl8 pressed_key = context->get_cur_pressed_key(touch_id);
-            SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
-            const SclLayoutKeyCoordinate *pressed_coordinate =
-                cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
-            if (pressed_context == NULL || pressed_coordinate == NULL) {
-                return FALSE;
-            }
-
-            if (key_index != pressed_key || window != pressed_window) {
-                /* When the focus has moved to another button, destroy all the timers */
-                events->destroy_all_timer();
-
-                if (check_event_transition_enabled(pressed_coordinate, coordinate)) {
-                    if (layout) {
-                        const scl16 uniqId = utils->get_unique_id();
-                        context->set_cur_pressed_event_id(touch_id, uniqId);
-                        /* Special routine for autopopup */
-                        if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
-                            events->create_timer(SCL_TIMER_AUTOPOPUP, m_autopopup_key_duration, uniqId);
-                        } else {
-                            /* for long key & repeat key */
-                            events->create_timer(SCL_TIMER_LONGKEY, m_long_key_duration, uniqId);
-                        }
-
-                        context->set_cur_pressed_window(touch_id, window);
-                        context->set_cur_pressed_key(touch_id, key_index);
-
-                        sclboolean showMagnifier = check_magnifier_available(window, key_index, touch_id);
-
-                        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-                        PSclMagnifierWndConfigure magnifier_configure = NULL;
-                        if (sclres_manager) {
-                            magnifier_configure = sclres_manager->get_magnifier_configure();
-                        }
-
-                        SclWindowContext *window_context = windows->get_window_context(window);
-                        if (showMagnifier && magnifier_configure && window_context) {
-                            SclPoint pos = {0, 0};
-                            /* calculates x position to be set */
-                            pos.x = window_context->geometry.x;
-                            pos.x += (coordinate->x + (coordinate->width / 2)) -
-                                (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
-                            /* calculates y position to be set */
-                            pos.y = window_context->geometry.y;
-                            pos.y += coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
-
-                            if (pos.x < window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
-                                pos.x = window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
-                            }
-                            if (pos.x > window_context->geometry.x + window_context->geometry.width +
-                                magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                                magnifier_configure->width * utils->get_custom_scale_rate_x()) {
-                                pos.x = window_context->geometry.x + window_context->geometry.width +
-                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                                    magnifier_configure->width * utils->get_custom_scale_rate_x();
-                            }
-                            pos.x += coordinate->magnifier_offset_x;
-                            pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
-                            pos.y += coordinate->magnifier_offset_y;
-                            if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
-                                windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
-                                windows->update_window(windows->get_magnifier_window());
-                            }
-                        }
-
-                        /* for feedback */
-                        feedback->button_moved(window, key_index);
-
-                        button_context->state = BUTTON_STATE_PRESSED;
-                        if (pressed_context) {
-                            /* But, if this button should be in pressed state in other multitouch id, do not initialize it */
-                            sclboolean found = FALSE;
-                            for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
-                                SclUIEventDesc desc;
-                                context->get_multi_touch_event(loop, &desc);
-                                if (desc.touch_id != touch_id) {
-                                    MultiTouchContext *multi_touch_context =
-                                        context->find_multi_touch_context(desc.touch_id);
-                                    if (multi_touch_context) {
-                                        if (multi_touch_context->cur_pressed_window == pressed_window &&
-                                            multi_touch_context->cur_pressed_key == pressed_key) {
-                                            found = TRUE;
-                                        }
-                                    }
-                                }
-                            }
-                            if (!found) {
-                                pressed_context->state = BUTTON_STATE_NORMAL;
-                            }
-                        }
-                        /* If the window doesn't get exposed before corresponding release event,
-                        * the inverted state of a button will never be drawn onto screen.
-                        * To prevent such a case, we draw the inverted state of button forcefully and directly,
-                        * without waiting for expose event */
-                        /* Redrawing pressed button does not work properly, commented out */
-                        /*
-                        CSCLGraphics *grps = CSCLGraphics::get_instance();
-                        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
-                        scldrawctx draw_ctx;
-                        if (pressed_window != SCLWINDOW_INVALID && pressed_key != NOT_USED) {
-                            draw_ctx = grps->begin_paint(pressed_window, TRUE);
-                            builder->draw_button(pressed_window, draw_ctx, pressed_key, FALSE);
-                            grps->end_paint(pressed_window, draw_ctx);
-                        }
-                        draw_ctx = grps->begin_paint(window, TRUE);
-                        builder->draw_button(window, draw_ctx, key_index, TRUE);
-                        grps->end_paint(window, draw_ctx);
-                        */
-
-                        switch (coordinate->button_type) {
-                        case BUTTON_TYPE_DRAG: {
-                            SclUIEventDesc key_event_desc;
-                            key_event_desc.key_value = coordinate->key_value[shift_index][0];
-                            key_event_desc.key_event = coordinate->key_event[shift_index][0];
-                            key_event_desc.key_type = coordinate->key_type;
-                            key_event_desc.key_modifier = KEY_MODIFIER_NONE;
-
-                            key_event_desc.event_type = EVENT_TYPE_MOVE;
-                            key_event_desc.touch_id = touch_id;
-                            key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                            key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                            key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                            if (sclres_manager) {
-                                magnifier_configure = sclres_manager->get_magnifier_configure();
-                            }
-                            sclboolean processed = handler->on_event_drag_state_changed(key_event_desc);
-                            if (processed && context->get_magnifier_enabled() && magnifier_configure) {
-                                SclPoint zoomwinpos = {0, 0};
-                                /* calculates x position to be set */
-                                zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
-                                    (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
-                                /* calculates y position to be set */
-                                sclint scnWidth, scnHeight;
-                                utils->get_screen_resolution(&scnWidth, &scnHeight);
-
-                                zoomwinpos.y = coordinate->y -
-                                    magnifier_configure->height * utils->get_custom_scale_rate_y();
-                                SclWindowContext *window_context = windows->get_window_context(window);
-                                if (window_context) {
-                                    zoomwinpos.x += window_context->geometry.x;
-                                    zoomwinpos.y += window_context->geometry.y;
-                                }
-                                if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
-                                    zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
-                                }
-                                if (zoomwinpos.x > scnWidth +
-                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                                    magnifier_configure->width * utils->get_custom_scale_rate_x()) {
-                                        zoomwinpos.x = scnWidth +
-                                            magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                                            magnifier_configure->width * utils->get_custom_scale_rate_x();
-                                }
-                                zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
-                                zoomwinpos.x += coordinate->magnifier_offset_x;
-                                zoomwinpos.y += coordinate->magnifier_offset_y;
-                                windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
-                                windows->show_window(windows->get_magnifier_window(), 0);
-                            }
-
-                            handler->on_event_key_clicked(key_event_desc);
-                            if (!(windows->is_base_window(window))) {
-                                /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
-                                //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
-                                SclWindowContext *window_context = windows->get_window_context(window);
-                                if (window_context) {
-                                    if (window_context->timeout > 0) {
-                                        events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
-                                        events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
-                                    }
-                                }
-                            }
-                        }
-                        break;
-                        case BUTTON_TYPE_NORMAL: break;
-                        case BUTTON_TYPE_GRAB: break;
-                        case BUTTON_TYPE_SELFISH: break;
-                        case BUTTON_TYPE_MULTITAP: break;
-                        case BUTTON_TYPE_ROTATION: break;
-                        case BUTTON_TYPE_DIRECTION: break;
-                        case BUTTON_TYPE_RELATIVE_DIRECTION: break;
-                        case BUTTON_TYPE_UIITEM: break;
-                        case MAX_BUTTON_TYPE: break;
-                        default:
-                            break;
-                        }
-
-#ifdef DIRECTLY_DRAW_ON_EVENTS
-                        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
-                        if (builder) {
-                            if (button_context) {
-                                builder->draw_button(window, NULL, key_index, button_context->state);
-                            }
-                            if (pressedContext) {
-                                builder->draw_button(pressed_window, NULL, pressed_key, pressedContext->state, TRUE);
-                            }
-                        }
-#else
-                        windows->update_window(window,
-                                coordinate->x, coordinate->y, coordinate->width, coordinate->height);
-                        if (pressed_coordinate) {
-                            windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
-                                    pressed_coordinate->width, pressed_coordinate->height);
-                        }
-#endif
-                    }
-
-                    //utils->log("Now Moving : %d %d\n", pos.x, pos.y);
-                } else {
-                    /* If the focus went out from our SELFISH button */
-                    if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH) {
-                        pressed_context->state = BUTTON_STATE_NORMAL;
-                        windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
-                            pressed_coordinate->width, pressed_coordinate->height);
-                        /* And if this SELFISH button was the last button pressed */
-                        if (touch_id == context->get_last_touch_device_id()) {
-                            windows->hide_window(windows->get_magnifier_window());
-                        }
-                    }
-                }
-            } else {
-                /* If the focus came back into our SELFISH button */
-                if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH && pressed_context->state != BUTTON_STATE_PRESSED) {
-                    pressed_context->state = BUTTON_STATE_PRESSED;
-                    windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
-                        pressed_coordinate->width, pressed_coordinate->height);
-                    /* And if this SELFISH button was the last button pressed */
-                    if (touch_id == context->get_last_touch_device_id()) {
-                        sclboolean showMagnifier = check_magnifier_available(pressed_window, pressed_key, touch_id);
-
-                        if (showMagnifier) {
-                            windows->show_window(windows->get_magnifier_window());
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    return ret;
-}
-
-sclboolean
-CSCLController::process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index)
-{
-    SCL_DEBUG();
-
-    sclboolean ret = FALSE;
-
-    CSCLUtils *utils = CSCLUtils::get_instance();
-    CSCLEvents *events = CSCLEvents::get_instance();
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLFeedback *feedback = CSCLFeedback::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-
-    SclButtonContext *button_context = NULL;
-
-    const SclLayoutKeyCoordinate *coordinate = NULL;
-    if (cache) {
-        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
-        button_context = cache->get_cur_button_context(window, key_index);
-    }
-
-    if (button_context && coordinate && feedback && utils && context && cache && events && windows) {
-       /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
-        sclboolean subLayoutMatch = TRUE;
-        if (coordinate->sub_layout && context->get_cur_sublayout()) {
-            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
-                subLayoutMatch = FALSE;
-            }
-        }
-        if ( x >= coordinate->x - coordinate->add_hit_left &&
-            x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
-                y >= coordinate->y - coordinate->add_hit_top &&
-                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
-                subLayoutMatch ) {
-            ret = TRUE;
-
-            SCLShiftState shift_index = context->get_shift_state();
-            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-            if (context->get_caps_lock_mode()) {
-                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-            }
-
-            const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
-
-            sclwindow highlighted_window = context->get_cur_highlighted_window();
-            scl8 highlighted_key = context->get_cur_highlighted_key();
-            SclButtonContext *cur_context = cache->get_cur_button_context(window, key_index);
-
-            if (cur_context == NULL) {
-                return FALSE;
-            }
-            if (key_index != highlighted_key || window != highlighted_window) {
-                SECURE_LOGD("%d != %d || %p != %p", key_index, highlighted_key, window, highlighted_window);
-                if (layout) {
-                    if (coordinate->key_type != KEY_TYPE_NONE) {
-                        if (context->get_tts_enabled()) {
-                            const sclchar *targetstr = coordinate->hint_string[shift_index][button_context->multitap_index];
-                            if (targetstr == NULL) {
-                                targetstr = coordinate->label[shift_index][0];
-                            }
-                            if (targetstr == NULL) {
-                                targetstr = coordinate->key_value[shift_index][button_context->multitap_index];
-                            }
-                            /*if(state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
-                                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ) {
-                                    targetstr = coordinate->long_key_value;
-                            }*/
-                            const sclchar *sayit = cache->find_substituted_string(targetstr);
-                            utils->play_tts(sayit);
-                        }
-                    }
-                }
-
-                context->set_cur_highlighted_window(window);
-                context->set_cur_highlighted_key(key_index);
-            }
-        }
-    }
-
-    return ret;
-}
-SCLKeyModifier
-CSCLController::get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist, sclboolean check_farthest,
-                                      scltouchdevice touch_id, sclbyte extra_option) {
-    typedef struct {
-        double lowerbound;
-        double upperbound;
-        SCLKeyModifier modifier;
-    } DIRECTIONINFO;
-
-    CSCLContext *context = CSCLContext::get_instance();
-    SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
-
-    if (context) {
-        double theta = atan2(deltay , (deltax ? deltax : 1)); /* Avoid divide by 0 exception */
-        sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
-        SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
-        if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS ||
-            extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
-            extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN) { /* 8 directions */
-                /* If the theta is below 0, the direction is upward since the y coordinate grows downward */
-                /* The below angle values are customized for MoAKey, need to provide customizing API */
-                DIRECTIONINFO info[] = {
-                    {-8 * (M_PI / 8), -7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
-                    {-7 * (M_PI / 8), -5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_LEFT},
-                    {-5 * (M_PI / 8), -2.7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP},
-                    {-2.7 * (M_PI / 8), -1.5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_RIGHT},
-                    {-1.5 * (M_PI / 8),  1 * (M_PI / 8), KEY_MODIFIER_DIRECTION_RIGHT},
-                    { 1 * (M_PI / 8),  3 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_RIGHT},
-                    { 3 * (M_PI / 8),  5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN},
-                    { 5 * (M_PI / 8),  7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_LEFT},
-                    { 7 * (M_PI / 8),  8 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
-                };
-                for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
-                    if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
-                        key_modifier = info[loop].modifier;
-                    }
-                }
-        } else { /* 4 directions */
-            /* If the state was dragging to one of 4 directions and the final release point is
-            * far enough from inital press point, and the angle is in between out predefined angle value */
-            if (extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE &&
-                cur_drag_state != SCL_DRAG_STATE_NONE && cur_drag_state != SCL_DRAG_STATE_INVALID &&
-                dist > SCL_DRAG_CURVE_RECOG_DIST &&
-                ratio > (1 / SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) &&
-                ratio < SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) {
-                    if (cur_drag_state == SCL_DRAG_STATE_DOWN) {
-                        if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_RIGHT;
-                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_LEFT;
-                    }
-                    if (cur_drag_state == SCL_DRAG_STATE_UP) {
-                        if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_RIGHT;
-                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_LEFT;
-                    }
-                    if (cur_drag_state == SCL_DRAG_STATE_LEFT) {
-                        if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_DOWN;
-                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_UP;
-                    }
-                    if (cur_drag_state == SCL_DRAG_STATE_RIGHT) {
-                        if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_DOWN;
-                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_UP;
-                    }
-            } else {
-                DIRECTIONINFO info[] = {
-                    {-4 * (M_PI / 4), -3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
-                    {-3 * (M_PI / 4), -1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_UP},
-                    {-1 * (M_PI / 4),  1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_RIGHT},
-                    { 1 * (M_PI / 4),  3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_DOWN},
-                    { 3 * (M_PI / 4),  4 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
-                };
-                for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
-                    if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
-                        key_modifier = info[loop].modifier;
-                    }
-                }
-            }
-        }
-
-        if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
-            extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG) {
-                if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
-                    key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
-                        key_modifier = (SCLKeyModifier)(key_modifier + 8); // Add LONG attribute;
-                }
-        }
-        if (check_farthest || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
-            if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
-                key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
-                    key_modifier = (SCLKeyModifier)(key_modifier + 16); // Add RETURN attribute;
-            }
-        }
-    }
-
-    return key_modifier;
-}
-
-sclboolean
-CSCLController::process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
-                                             scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-
-    sclboolean ret = FALSE;
-    sclboolean redraw = FALSE;
-    sclboolean fire_event = FALSE;
-    SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
-
-    CSCLUtils *utils = CSCLUtils::get_instance();
-    CSCLFeedback *feedback = CSCLFeedback::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLActionState *state = CSCLActionState::get_instance();
-    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-
-    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-    if (!sclres_manager) return FALSE;
-
-    PSclLayout sclres_layout = sclres_manager->get_layout_table();
-    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
-    if (!sclres_layout || !sclres_input_mode_configure) return FALSE;
-
-    SclButtonContext *button_context = NULL;
-    const SclLayoutKeyCoordinate *coordinate = NULL;
-
-    if (cache) {
-        button_context = cache->get_cur_button_context(window, key_index);
-        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
-    }
-
-    const SclLayoutKeyCoordinate *targetCoordinate = NULL;
-
-    if (utils && feedback && windows && context && state && handler && cache && button_context && coordinate) {
-        scl8 savedInputMode = context->get_input_mode();
-
-        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
-        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
-
-        if (actual_event) {
-             if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
-                 /* When calling mouse_release, the seq order of current multitouch events will be changed,
-                    so we put all the multitouch events into a vector and use them afterwards for releasing */
-                 sclboolean finished = FALSE;
-                 sclint loop = 0;
-                 sclint multi_touch_context_num = context->get_multi_touch_context_num();
-                 std::vector<SclUIEventDesc> multi_touch_events;
-                 for (loop = 0;loop < multi_touch_context_num;loop++) {
-                     SclUIEventDesc desc;
-                     context->get_multi_touch_event(loop, &desc);
-                     multi_touch_events.push_back(desc);
-                 }
-                 for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
-                     SclUIEventDesc desc = multi_touch_events[loop];
-                     if (desc.touch_id != touch_id) {
-                         sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
-                         scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
-                         const SclLayoutKeyCoordinate *cur_pressed_coordinate =
-                             cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
-                         if (cur_pressed_coordinate) {
-                             if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
-                                 mouse_release(context->get_cur_moving_window(desc.touch_id),
-                                     context->get_cur_moving_point(desc.touch_id).x,
-                                     context->get_cur_moving_point(desc.touch_id).y,
-                                     desc.touch_id, FALSE);
-                             }
-                         }
-                     } else {
-                         finished = TRUE;
-                     }
-                 }
-             }
-         }
-
-        /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
-        sclint thresholdX = 0;
-        sclint thresholdY = 0;
-        if (context) {
-            if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
-                thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
-                thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
-            }
-        }
-
-        /* Check if the pressed button's type is directional button */
-        if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
-            if (context) {
-                if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
-                    ret = TRUE;
-                    sclboolean check_farthest = FALSE;
-
-                    sclint startx = x;
-                    sclint starty = y;
-
-                    /* If the buttontype is RELATIVE_DIRECTION, get the distance from last move point */
-                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
-                        startx = context->get_prev_moving_point(touch_id).x;
-                        starty = context->get_prev_moving_point(touch_id).y;
-                    } else {
-                        startx = context->get_cur_pressed_point(touch_id).x;
-                        starty = context->get_cur_pressed_point(touch_id).y;
-                    }
-
-                    sclint deltax = x - startx;
-                    sclint deltay = y - starty;
-
-                    sclfloat dist = utils->get_distance(x, y, startx, starty);
-                    sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
-                    if (coordinate->is_side_button) {
-                        direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
-                    };
-                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
-                        direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
-                    }
-                    if (context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN &&
-                        coordinate->button_type != BUTTON_TYPE_RELATIVE_DIRECTION) {
-                        if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
-                            coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
-                            coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
-                                deltax = context->get_farthest_move_point(touch_id).x - context->get_cur_pressed_point(touch_id).x;
-                                deltay = context->get_farthest_move_point(touch_id).y - context->get_cur_pressed_point(touch_id).y;
-                                dist = utils->get_distance(context->get_farthest_move_point(touch_id), context->get_cur_pressed_point(touch_id));
-                                check_farthest = TRUE;
-                        }
-                    }
-                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
-                        key_modifier = context->get_cur_key_modifier(touch_id);
-                    } else if (dist > direction_recog_dist) {
-                        key_modifier = get_drag_key_modifier(deltax, deltay, dist, check_farthest, touch_id, coordinate->extra_option);
-                    }
-                }
-            }
-        }
-
-        /* First check if this button is enabled in current active sublayout */
-        sclboolean subLayoutMatch = TRUE;
-        if (coordinate->sub_layout && context->get_cur_sublayout()) {
-            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
-                subLayoutMatch = FALSE;
-            }
-        }
-        /* Check if the event occured inside this button's rectangle */
-        if ( x >= coordinate->x - coordinate->add_hit_left  - thresholdX &&
-                x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX &&
-                y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
-                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
-                subLayoutMatch ) {
-            ret = TRUE;
-        }
-
-        if (ret) {
-            /* for feedback */
-            feedback->button_released(window, key_index);
-
-            /* If this button's index is the same as the one initially pressed */
-            if (pressed_window == window && pressed_key == key_index) {
-                fire_event = TRUE;
-                targetCoordinate = coordinate;
-            } else {
-                const SclLayoutKeyCoordinate *pressed_coordinate =
-                    cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
-                if (pressed_coordinate) {
-                    if (check_event_transition_enabled(pressed_coordinate, coordinate)) {
-                        fire_event = TRUE;
-                        targetCoordinate = pressed_coordinate;
-                    } else {
-                        ret = FALSE;
-                    }
-                }
-            }
-        }
-
-        /* In case of mode change buttons, event should be fired only when it was pressed lastly */
-        if (fire_event) {
-            if (coordinate->key_type == KEY_TYPE_MODECHANGE) {
-                if (touch_id != context->get_last_touch_device_id()) {
-                    fire_event = FALSE;
-                }
-            }
-        }
-
-        /* If this key's modifier is LONGKEY, this means the event is already fired so skip this one */
-        if (context->get_cur_key_modifier(touch_id) == KEY_MODIFIER_LONGKEY) {
-            fire_event = FALSE;
-        }
-
-        /* Don't fire any events if we're in longkey state */
-        if (state->get_cur_action_state() != ACTION_STATE_BASE_LONGKEY &&
-                state->get_cur_action_state() != ACTION_STATE_BASE_REPEATKEY &&
-                state->get_cur_action_state() != ACTION_STATE_POPUP_LONGKEY &&
-                state->get_cur_action_state() != ACTION_STATE_POPUP_REPEATKEY) {
-            if (ret) {
-                SCLShiftState shift_index = context->get_shift_state();
-                if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-                if (context->get_caps_lock_mode()) {
-                    shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-                }
-
-                SclUIEventDesc key_event_desc;
-                if (targetCoordinate) {
-                    key_event_desc.key_type = targetCoordinate->key_type;
-
-                    key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
-                    key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
-                }
-                key_event_desc.key_modifier = key_modifier;
-
-                key_event_desc.event_type = EVENT_TYPE_RELEASE;
-                key_event_desc.touch_id = touch_id;
-                key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                if (handler->on_event_drag_state_changed(key_event_desc) != SCL_EVENT_PASS_ON) {
-                    fire_event = FALSE;
-                }
-            }
-            if (fire_event) {
-                if (targetCoordinate) {
-                    SCLShiftState shift_index = context->get_shift_state();
-                    if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-                    if (context->get_caps_lock_mode()) {
-                        shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-                    }
-
-                    SclUIEventDesc key_event_desc;
-                    key_event_desc.key_type = targetCoordinate->key_type;
-
-                    key_event_desc.event_type = EVENT_TYPE_RELEASE;
-                    key_event_desc.touch_id = touch_id;
-                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                    switch (targetCoordinate->button_type) {
-                    case BUTTON_TYPE_NORMAL:
-                    case BUTTON_TYPE_GRAB :
-                    case BUTTON_TYPE_SELFISH:
-                    case BUTTON_TYPE_DIRECTION :
-                    case BUTTON_TYPE_RELATIVE_DIRECTION: {
-                        SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
-                        if (pressed_context) {
-                            if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
-                                key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
-                                key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
-                                key_event_desc.key_modifier = key_modifier;
-                                handler->on_event_key_clicked(key_event_desc);
-                            }
-                        }
-                    }
-                    break;
-                    case BUTTON_TYPE_MULTITAP:
-                    case BUTTON_TYPE_ROTATION: {
-                        if (targetCoordinate->button_type == BUTTON_TYPE_MULTITAP) {
-                            if (window == context->get_last_event_fired_window() &&
-                                key_index == context->get_last_event_fired_key()) {
-                                key_modifier = KEY_MODIFIER_MULTITAP_REPEAT;
-                            } else {
-                                key_modifier = KEY_MODIFIER_MULTITAP_START;
-                            }
-                        } else {
-                            key_modifier = KEY_MODIFIER_NONE;
-                        }
-                        if (button_context->multitap_index < MAX_SIZE_OF_MULTITAP_CHAR) {
-                            key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
-                            key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
-                            key_event_desc.key_modifier = key_modifier;
-                            if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
-                                CSCLEvents *events = CSCLEvents::get_instance();
-                                events->destroy_timer(SCL_TIMER_MULTITAP);
-                                events->create_timer(SCL_TIMER_MULTITAP, m_multitap_delay_duration, 0);
-                            }
-                        }
-                        /* Check if the multikey index is in valid range, and increase by one */
-                        if (button_context->multitap_index >= MAX_SIZE_OF_MULTITAP_CHAR - 1) {
-                            button_context->multitap_index = 0;
-                        } else {
-                            sclbyte orgindex = button_context->multitap_index;
-                            button_context->multitap_index = 0;
-                            if (targetCoordinate->key_value[shift_index][orgindex + 1]) {
-                                if (strlen(targetCoordinate->key_value[shift_index][orgindex + 1]) > 0) {
-                                    button_context->multitap_index = orgindex + 1;
-                                }
-                            }
-                        }
-                    }
-                    break;
-                    case BUTTON_TYPE_DRAG : {
-                    }
-                    break;
-                    case BUTTON_TYPE_TOGGLE : {
-                        SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
-                        if (pressed_context) {
-                            if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
-                                key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
-                                key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
-                                if (pressed_context->toggled) {
-                                    key_event_desc.key_modifier = KEY_MODIFIER_NONE;
-                                } else {
-                                    key_event_desc.key_modifier = KEY_MODIFIER_TOGGLED;
-                                }
-                                if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
-                                    pressed_context->toggled = !(pressed_context->toggled);
-                                }
-                            }
-                        }
-                    }
-                    case BUTTON_TYPE_UIITEM: break;
-                    case MAX_BUTTON_TYPE: break;
-                    default: break;
-                    }
-                    switch (coordinate->popup_type) {
-                    case POPUP_TYPE_BTN_RELEASE_POPUP:
-                    case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE: {
-                        SCLDragState dragstate = context->get_cur_drag_state(touch_id);
-                        sclint popup_input_mode = NOT_USED;
-
-                        SclNotiPopupOpeningDesc desc;
-                        desc.ui_event_desc = &key_event_desc;
-
-                        if (scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) {
-                            desc.input_mode = coordinate->popup_input_mode[dragstate];
-                            popup_input_mode = sclres_manager->get_inputmode_id(coordinate->popup_input_mode[dragstate]);
-                            /* FIXME */
-                            //if (!scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP)) {
-                            if (!scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE)) {
-                                desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
-                            }
-                        }
-                        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
-                            popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
-                            SCLDisplayMode display_mode = context->get_display_mode();
-                            /* FIXME */
-                            //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
-                            if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
-                                scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
-                                sclshort popupLayoutId =
-                                    sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
-                                if (popupLayoutId == NOT_USED) {
-                                    // deal with NOT_USED
-                                    LOGD("popupLayoutID is not used.");
-                                }
-                                SclLayout *layout = NULL;
-                                /* FIXME */
-                                //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
-                                if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
-                                    layout = &sclres_layout[popupLayoutId];
-                                }
-                                if (layout) {
-                                    SclRectangle popupRect;
-                                    SclRectangle baseWndRect;
-                                    windows->get_window_rect(windows->get_base_window(), &baseWndRect);
-                                    popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
-                                    popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
-
-                                    //popupRect.width = utils->get_scale_x(layout->width);
-                                    //popupRect.height= utils->get_scale_y(layout->height);
-                                    if (!(sclres_manager->loaded(popupLayoutId))) {
-                                        sclres_manager->load(popupLayoutId);
-                                    }
-                                    popupRect.width = layout->width;
-                                    popupRect.height = layout->height;
-
-                                    /* Let's make sure this popup window does not go beyond the screen area */
-                                    sclint scr_w, scr_h;
-                                    utils->get_screen_resolution(&scr_w, &scr_h);
-
-                                    if (popupRect.x + popupRect.width > scr_w) {
-                                        popupRect.x = scr_w - popupRect.width;
-                                    }
-                                    if (popupRect.y + popupRect.height > scr_h) {
-                                        popupRect.y = scr_h - popupRect.height;
-                                    }
-
-                                    SclWindowOpener opener;
-                                    opener.window = window;
-                                    opener.key = key_index;
-
-                                    sclwindow popup_window = windows->open_popup(
-                                        opener,
-                                        popupRect,
-                                        popup_input_mode,
-                                        popupLayoutId,
-                                        coordinate->popup_type,
-                                        sclres_input_mode_configure[popup_input_mode].use_virtual_window,
-                                        sclres_input_mode_configure[popup_input_mode].use_dim_window,
-                                        coordinate->extract_offset_x,
-                                        coordinate->extract_offset_y,
-                                        sclres_input_mode_configure[popup_input_mode].timeout);
-
-                                    SclNotiPopupOpenedDesc opened_desc;
-                                    opened_desc.ui_event_desc = &key_event_desc;
-                                    opened_desc.input_mode = desc.input_mode;
-                                    opened_desc.window = popup_window;
-                                    handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
-
-                                    windows->hide_window(windows->get_magnifier_window());
-                                    _play_tts_for_input_mode_name(popup_input_mode);
-                                }
-                            }
-                        }
-                    }
-                    break;
-                    case POPUP_TYPE_AUTO_POPUP:
-                    case POPUP_TYPE_BTN_PRESS_POPUP_DRAG:
-                    case POPUP_TYPE_NONE:
-                        /* Nothing to do in here */
-                        break;
-                    case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE: break;
-                    case POPUP_TYPE_BTN_LONGPRESS_POPUP: break;
-                    case MAX_POPUP_TYPE: break;
-                    default: break;
-                    }
-                }
-
-                context->set_last_event_fired_window(window);
-                context->set_last_event_fired_key(key_index);
-            }
-        } else {
-            if (targetCoordinate) {
-                SCLShiftState shift_index = context->get_shift_state();
-                if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-                if (context->get_caps_lock_mode()) {
-                    shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-                }
-
-                SclUIEventDesc key_event_desc;
-                key_event_desc.key_type = targetCoordinate->key_type;
-
-                key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
-                key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
-                key_event_desc.key_modifier = key_modifier;
-
-                key_event_desc.event_type = EVENT_TYPE_RELEASE;
-                key_event_desc.touch_id = touch_id;
-                key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                handler->on_event_drag_state_changed(key_event_desc);
-            }
-        }
-
-        /* If this button was pressed, initialize the button context regardless of event  */
-        if (button_context->state == BUTTON_STATE_PRESSED) {
-            /* But, if this button should be in pressed state in other multitouch id, do not initialize */
-            sclboolean found = FALSE;
-            for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
-                SclUIEventDesc desc;
-                context->get_multi_touch_event(loop, &desc);
-                if (desc.touch_id != touch_id) {
-                    MultiTouchContext *multi_touch_context = context->find_multi_touch_context(desc.touch_id);
-                    if (multi_touch_context) {
-                        if (multi_touch_context->cur_pressed_window == window &&
-                            multi_touch_context->cur_pressed_key == key_index) {
-                            found = TRUE;
-                        }
-                    }
-                }
-            }
-            if (!found) {
-                button_context->state = BUTTON_STATE_NORMAL;
-                redraw = TRUE;
-            }
-        }
-
-        /* If this button needs to be redrawn */
-        if (redraw) {
-#ifdef DIRECTLY_DRAW_ON_EVENTS
-            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
-            if (builder) {
-                builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
-            }
-#else
-            if (savedInputMode == context->get_input_mode()) {
-                windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
-            }
-
-#endif
-        }
-    }
-
-    return ret;
-}
-
-sclboolean
-CSCLController::mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-    sclboolean ret = FALSE;
-
-    if (m_input_events_disabled) return FALSE;
-
-    //utils->log("Controller::mouse_press : %d %d\n", x, y);
-
-    /* Adjust x,y coordinate by touch offset */
-    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
-
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-    CSCLActionState *state = CSCLActionState::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLUtils *utils = CSCLUtils::get_instance();
-
-    sclint button_index = NOT_USED;
-    SclWindowContext *window_context = NULL;
-    if (windows && cache) {
-        const SclLayout *layout = cache->get_cur_layout(window);
-        if (layout) {
-            x += layout->mouse_manipulate_x;
-            y += layout->mouse_manipulate_y;
-        }
-        window_context = windows->get_window_context(window);
-        /* If the dim window is virtual and currently active, let's just skip this event */
-        if (windows->is_base_window(window)) {
-            SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
-            if (dim_window_context) {
-                LOGD("dim window is_virtual:%d, hidden:%d", dim_window_context->is_virtual, dim_window_context->hidden);
-                if (/*dim_window_context->is_virtual &&*/ !(dim_window_context->hidden)) {
-                    window = windows->get_dim_window();
-                    window_context = dim_window_context;
-                }
-            }
-        }
-    }
-
-    if (cache && state && windows && context && window_context) {
-        SCLDisplayMode display_mode = context->get_display_mode();
-        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-        PSclDefaultConfigure default_configure = NULL;
-        if (sclres_manager) {
-            default_configure = sclres_manager->get_default_configure();
-        }
-        if (default_configure) {
-            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
-        }
-
-        sclboolean isSubEvent = FALSE;
-        if (context->get_multi_touch_context_num() > 0) {
-            SclUIEventDesc desc;
-            context->get_multi_touch_event(0, &desc);
-            sclwindow pressed_window = context->get_cur_pressed_window(desc.touch_id);
-            scl8 pressed_key = context->get_cur_pressed_key(desc.touch_id);
-            SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-            if (coordinate) {
-                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_GRAB_SUB_EVENTS) {
-                    isSubEvent = TRUE;
-                    if (utils)
-                        utils->play_vibration(DEFAULT_VIBRATION_STYLE, DEFAULT_VIBRATION_DURATION);
-                }
-            }
-        }
-        context->create_multi_touch_context(touch_id, isSubEvent);
-        context->set_cur_pressed_window(touch_id, window);
-        context->set_cur_pressed_point(touch_id, x, y);
-        context->set_cur_pressed_time(touch_id);
-        context->set_cur_moving_window(touch_id, window);
-        context->set_cur_moving_point(touch_id, x, y);
-        context->set_last_touch_device_id(touch_id);
-        context->set_cur_drag_state(touch_id, SCL_DRAG_STATE_NONE);
-        context->set_cur_key_modifier(touch_id, KEY_MODIFIER_NONE);
-        for (sclint labelidx = 0;labelidx < MAX_SIZE_OF_LABEL_FOR_ONE;labelidx++) {
-            context->set_custom_magnifier_label(touch_id, labelidx, NULL);
-        }
-
-        /* If there is postponed update of button, update it now */
-        CSCLEvents *events = CSCLEvents::get_instance();
-        sclwindow last_win = context->get_last_pressed_window();
-        scl8 last_key = context->get_last_pressed_key();
-        if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
-            const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
-            if (coords) {
-                windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
-            }
-        }
-        context->set_prev_pressed_window(touch_id, SCLWINDOW_INVALID);
-        context->set_prev_pressed_key(touch_id, NOT_USED);
-        context->set_prev_drag_state(touch_id, SCL_DRAG_STATE_NONE);
-        context->set_prev_moving_point(touch_id, x, y);
-
-        /* Destroy key related timers */
-        events->destroy_timer(SCL_TIMER_BUTTON_DELAY);
-        events->destroy_timer(SCL_TIMER_AUTOPOPUP);
-        events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
-        events->destroy_timer(SCL_TIMER_LONGKEY);
-        events->destroy_timer(SCL_TIMER_REPEATKEY);
-        events->destroy_timer(SCL_TIMER_MULTITAP);
-
-        /* Do what has to be done when mouse gets pressed */
-        handle_engine_signal(SCL_SIG_MOUSE_PRESS, window);
-
-        /* Adjust event x and y positions as relative position to the virtual window */
-        if (window_context) {
-            /*if (window_context->isVirtual) {
-                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
-                if (base_window_context) {
-                    x -= (window_context->x - base_window_context->x);
-                    y -= (window_context->y - base_window_context->y);
-                }
-            }*/
-        }
-
-        if (!isSubEvent) {
-            sclboolean process_finished = FALSE;
-            do {
-                /* Iterate all the buttons and inform the event */
-                sclboolean ended = FALSE;
-                for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
-                    SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
-                    const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
-                    if (button_context && coordinate) {
-                        if (!(button_context->used)) {
-                            ended = TRUE;
-                        } else if (button_context->state != BUTTON_STATE_DISABLED &&
-                                    coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                            if (process_button_pressed_event(window, x, y, loop, touch_id, actual_event)) {
-                                if (windows->is_base_window(window)) {
-                                    state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
-                                } else {
-                                    state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
-                                }
-                                button_index = loop;
-                                ret = TRUE;
-                            }
-                        }
-                    }
-                }
-
-                /* For covering a missing area about 1 pixel */
-                if (!ret) {
-                    for (int loop = 0;loop < MAX_KEY;loop++) {
-                        SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
-                        const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, loop);
-                        if (button_context && coordinate) {
-                            if (!(button_context->used)) {
-                                break;
-                            } else if (button_context->state != BUTTON_STATE_DISABLED &&
-                                        coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                                if (process_button_pressed_event(window, x+1, y+1, loop, touch_id, actual_event)) {
-                                    if (windows->is_base_window(window)) {
-                                        state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
-                                    } else {
-                                        state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
-                                    }
-                                    button_index = loop;
-                                    break;
-                                }
-                            }
-                        } else {
-                            break;
-                        }
-                    }
-                }
-
-                if (windows->is_base_window(window)) {
-                    process_finished = TRUE;
-                } else if (button_index != NOT_USED) {
-                    process_finished = TRUE;
-                } else {
-                    const SclLayout *layout = cache->get_cur_layout(window);
-                    if (layout) {
-                        if (layout->use_sw_background && layout->bg_color.a == 0) {
-                            /* If we could not find appropriate button in this popup window and the popup is transparent */
-                            SclWindowContext *base_window_context =
-                                windows->get_window_context(windows->get_base_window());
-                            if (base_window_context) {
-                                x = (window_context->geometry.x + x - base_window_context->geometry.x);
-                                y = (window_context->geometry.y + y - base_window_context->geometry.y);
-                            }
-                            window = windows->get_base_window();
-                        } else {
-                            process_finished = TRUE;
-                        }
-                    } else {
-                        process_finished = TRUE;
-                    }
-                }
-            } while (!process_finished);
-        }
-
-        sclwindow skip_window = window;
-        if (ret && button_index != NOT_USED) {
-            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
-            if (coordinate) {
-                sclboolean dont_close_popup = FALSE;
-                if (coordinate->dont_close_popup) {
-                    dont_close_popup = TRUE;
-                }
-                /* If the button's popup type is drag type, the opened popup could be the one opened by this press event */
-                if (coordinate->popup_type == POPUP_TYPE_BTN_PRESS_POPUP_DRAG) {
-                    /* Check the opened popup was opened by this button */
-                    sclwindow popupwin = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
-                    SclWindowContext *popup_window_context = windows->get_window_context(popupwin);
-                    if (popup_window_context) {
-                        SclWindowOpener opener = popup_window_context->opener;
-                        if (opener.window == window && opener.key == button_index) {
-                            dont_close_popup = TRUE;
-                        }
-                    }
-                }
-                if (dont_close_popup) {
-                    skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
-                }
-            }
-        } else {
-            SclUIEventDesc key_event_desc;
-            key_event_desc.event_type = EVENT_TYPE_PRESS;
-
-            SclPoint curpoint = {x, y};
-            key_event_desc.touch_id = touch_id;
-            key_event_desc.mouse_pressed_point = curpoint;
-            key_event_desc.mouse_current_point = curpoint;
-            key_event_desc.mouse_farthest_point = curpoint;
-
-            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-            CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-            if (handler) {
-                handler->on_event_drag_state_changed(key_event_desc);
-            }
-        }
-        windows->close_all_popups(skip_window);
-
-        /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
-        if (!(windows->is_base_window(window))) {
-            if (window_context->timeout > 0) {
-                events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
-                events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
-            }
-        } else if (skip_window != window) { /* Or the pressed button has dont_close_popup property, reset POPUP_TIMEOUT timer */
-            //SclWindowContext *skip_window_context = windows->get_window_context(skip_window, FALSE);
-            SclWindowContext *skip_window_context = windows->get_window_context(skip_window);
-            if (skip_window_context) {
-                if (skip_window_context->timeout > 0) {
-                    events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
-                    events->create_timer(SCL_TIMER_POPUP_TIMEOUT, skip_window_context->timeout, 0, TRUE);
-                }
-            }
-        }
-    }
-
-    return TRUE;
-}
-
-sclboolean
-CSCLController::mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-    sclboolean ret = FALSE;
-
-    //if (m_input_events_disabled) return FALSE;
-
-    //utils->log("Controller::mouse_release : %d %d\n", x, y);
-    /* Adjust x,y coordinate by touch offset */
-    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
-
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-    CSCLActionState *state = CSCLActionState::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLUtils *utils = CSCLUtils::get_instance();
-    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-    CSCLEvents *events = CSCLEvents::get_instance();
-
-    sclint button_index = NOT_USED;
-
-    if (cache && state && windows && context && utils && handler && events &&
-        context->find_multi_touch_context(touch_id)) {
-        const SclLayout *layout = cache->get_cur_layout(window);
-        if (layout) {
-            x += layout->mouse_manipulate_x;
-            y += layout->mouse_manipulate_y;
-        }
-
-        sclwindow skip_window = SCLWINDOW_INVALID;
-        SCLDisplayMode display_mode = context->get_display_mode();
-
-        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-        PSclDefaultConfigure default_configure = NULL;
-        if (sclres_manager) {
-            default_configure = sclres_manager->get_default_configure();
-        }
-        if (default_configure) {
-            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
-        }
-
-        context->set_cur_moving_window(touch_id, SCLWINDOW_INVALID);
-
-        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
-        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
-        //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
-        SclWindowContext *window_context = windows->get_window_context(window);
-        /* Adjust event x and y positions as relative position to the virtual window */
-        if (window_context) {
-            /*if (window_context->isVirtual) {
-                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
-                if (base_window_context) {
-                    x -= (window_context->x - base_window_context->x);
-                    y -= (window_context->y - base_window_context->y);
-                }
-            }*/
-            /* If the dim window is virtual and currently active, consider base window's event is occured in dim window */
-            if (windows->is_base_window(window)) {
-                SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
-                if (dim_window_context) {
-                    if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
-                        window = windows->get_dim_window();
-                        window_context = dim_window_context;
-                    }
-                }
-            }
-        }
-
-        /* Iterate all the buttons and inform the event */
-        sclboolean ended = FALSE;
-
-        /* FIXME : The routine below seems to be removed, which was originally requested by Vodafone,
-         * to slow down the speed of repeat key right before stopping repeatkey event */
-        /* if (state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY) {
-            if (m_key_repeated_num > 10) {
-                utils->sleep(100);
-                process_button_repeat_pressed_event(pressed_window, pressed_key, touch_id);
-            }
-            ended = TRUE;
-        }*/
-
-        if (context->get_cur_pressed_window(touch_id) == window) {
-            if (abs(context->get_cur_pressed_point(touch_id).x - x) > utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD) ||
-                abs(context->get_cur_pressed_point(touch_id).y - y) > utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD) )
-            {
-                struct timeval t0 = context->get_cur_pressed_time(touch_id);
-                struct timeval t1;
-                gettimeofday(&t1, NULL);
-                float etime;
-                etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000.0;
-                if (etime < SCL_FLICK_GESTURE_RECOG_TIME) {
-                    SCLDragType drag_type = DRAG_NONE;
-                    if (x > context->get_cur_pressed_point(touch_id).x + utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
-                        drag_type = DRAG_RIGHT;
-                    }
-                    if (x < context->get_cur_pressed_point(touch_id).x - utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
-                        drag_type = DRAG_LEFT;
-                    }
-                    if (y > context->get_cur_pressed_point(touch_id).y + utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
-                        drag_type = DRAG_DOWN;
-                    }
-                    if (y < context->get_cur_pressed_point(touch_id).y - utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
-                        drag_type = DRAG_UP;
-                    }
-                    SclNotiGestureFlickDesc desc;
-                    SclUIEventDesc ui_event_desc;
-                    ui_event_desc.key_value = NULL;
-                    ui_event_desc.key_event = NOT_USED;
-                    ui_event_desc.key_modifier = KEY_MODIFIER_NONE;
-                    ui_event_desc.event_type = EVENT_TYPE_RELEASE;
-                    ui_event_desc.touch_id = touch_id;
-                    ui_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                    ui_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                    ui_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-                    ui_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-                    desc.ui_event_desc = &ui_event_desc;
-                    desc.drag_type = drag_type;
-                    if (handler->on_event_notification(SCL_UINOTITYPE_GESTURE_FLICK, &desc)) {
-                        ended = TRUE;
-                    }
-                }
-            }
-        }
-
-        /* FIXME : We should consider this kind of action in general manner, not only specific to autopopup */
-        /* And also, this kind of implementation only selects button that was highlighted at least once. */
-        // {
-        //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
-        SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
-        if (pressed_window_context) {
-            utils->log("PRESSED CTX : %p %d %d\n", pressed_window,
-                pressed_window_context->geometry.x, pressed_window_context->geometry.y);
-            //if (pressedCtx->popuptype == POPUP_TYPE_AUTO_POPUP) {
-            sclboolean grab_event = FALSE;
-            const SclLayout *pressed_layout = cache->get_cur_layout(pressed_window);
-            if (pressed_layout) {
-                if (pressed_layout->style == LAYOUT_STYLE_POPUP_GRAB) {
-                    grab_event = TRUE;
-                }
-                /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
-                if (grab_event) {
-                    /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
-                    sclboolean in_grab_area = TRUE;
-                    if (pressed_layout->add_grab_left != NOT_USED &&
-                        x < (pressed_window_context->geometry.x - pressed_layout->add_grab_left)) {
-                        in_grab_area = FALSE;
-                    }
-                    if (pressed_layout->add_grab_right != NOT_USED &&
-                        x > (pressed_window_context->geometry.x + pressed_window_context->geometry.width
-                        + pressed_layout->add_grab_right)) {
-                        in_grab_area = FALSE;
-                    }
-                    if (pressed_layout->add_grab_top != NOT_USED &&
-                        y < (pressed_window_context->geometry.y - pressed_layout->add_grab_top)) {
-                        in_grab_area = FALSE;
-                    }
-                    if (pressed_layout->add_grab_bottom != NOT_USED &&
-                        y > (pressed_window_context->geometry.y + pressed_window_context->geometry.height
-                        + pressed_layout->add_grab_bottom)) {
-                        in_grab_area = FALSE;
-                    }
-                    if (in_grab_area) {
-                        SclLayoutKeyCoordinate *coord = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-                        if (coord) {
-                            x = coord->x + (coord->width / 2);
-                            y = coord->y + (coord->height / 2);
-
-                            for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
-                                SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, loop);
-                                const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, loop);
-                                if (button_context && coordinate) {
-                                    if (!(button_context->used)) {
-                                        ended = TRUE;
-                                    } else if (button_context->state != BUTTON_STATE_DISABLED &&
-                                                coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                                        if (process_button_release_event(pressed_window, x, y, loop, touch_id, actual_event)) {
-                                            ret = TRUE;
-                                            ended = TRUE;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        // }
-
-        SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
-        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
-        /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
-        /* Ignore base window's release event if a popup window is opened */
-        if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
-            if (windows->is_base_window(window)) {
-                ended = TRUE;
-                /* In case of direction button, the release event on other window should be processed */
-                if (coordinate && window_context && pressed_window_context) {
-                    if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
-                        sclint relx = (window_context->geometry.x + x) - pressed_window_context->geometry.x;
-                        sclint rely = (window_context->geometry.y + y) - pressed_window_context->geometry.y;
-                        if (process_button_release_event(pressed_window, relx, rely, pressed_key, touch_id, actual_event)) {
-                            button_index = pressed_key;
-                            ret = TRUE;
-                            x = coordinate->x + (coordinate->width / 2);
-                            y = coordinate->y + (coordinate->height / 2);
-                            skip_window = pressed_window;
-                        }
-                    }
-                }
-            }
-        }
-
-        sclboolean process_finished = FALSE;
-        do {
-            MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
-            if (multi_touch_context) {
-                if (!(multi_touch_context->is_sub_event)) {
-                    /* First check if the event occured in pressed key's threshold area */
-                    if (button_context && coordinate && !ended) {
-                        if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
-                            if (process_button_release_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
-                                button_index = pressed_key;
-                                ret = TRUE;
-                                x = coordinate->x + (coordinate->width / 2);
-                                y = coordinate->y + (coordinate->height / 2);
-                            }
-                        }
-                    }
-                    for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
-                        SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
-                        const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
-                        if (cur_context && cur_coordinate) {
-                            if (!(cur_context->used)) {
-                                ended = TRUE;
-                            } else if (cur_context->state != BUTTON_STATE_DISABLED &&
-                                        cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                                if (window != pressed_window || loop != pressed_key) {
-                                    if (process_button_release_event(window, x, y, loop, touch_id, actual_event)) {
-                                        button_index = loop;
-                                        ret = TRUE;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                } else {
-                    process_finished = TRUE;
-
-                    SclUIEventDesc key_event_desc;
-                    key_event_desc.key_value = NULL;
-                    key_event_desc.key_event = NOT_USED;
-                    key_event_desc.key_modifier = KEY_MODIFIER_NONE;
-                    key_event_desc.event_type = EVENT_TYPE_NONE;
-                    key_event_desc.touch_id = touch_id;
-                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-                    handler->on_event_key_clicked(key_event_desc);
-                }
-            }
-
-            /* For covering a missing area about 1 pixel */
-            if (!ret) {
-                ended = FALSE;
-
-                if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
-                        state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
-                        state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
-                        state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
-                        state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
-                        state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
-                    if (windows->is_base_window(window)) {
-                        ended = TRUE;
-                    }
-                }
-
-                for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
-                    SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
-                    if (cur_context && coordinate) {
-                        if (!(cur_context->used)) {
-                            ended = TRUE;
-                            break;
-                        } else if (cur_context->state != BUTTON_STATE_DISABLED &&
-                                    coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                            if (process_button_release_event(window, x+1, y+1, loop, touch_id)) {
-                                button_index = loop;
-                                ret = TRUE;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-            if (windows->is_base_window(window)) {
-                process_finished = TRUE;
-            } else if (button_index != NOT_USED) {
-                process_finished = TRUE;
-            } else {
-                if (layout && layout->use_sw_background && layout->bg_color.a == 0) {
-                    /* If we could not find appropriate button in this popup window and the popup is transparent */
-                    SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
-                    if (base_window_context && window_context) {
-                        x = (window_context->geometry.x + x - base_window_context->geometry.x);
-                        y = (window_context->geometry.y + y - base_window_context->geometry.y);
-                    }
-                    window = windows->get_base_window();
-                } else {
-                    process_finished = TRUE;
-                }
-            }
-        } while (!process_finished);
-
-        if (!ret) {
-            SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
-            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
-            SCLShiftState shift_index = context->get_shift_state();
-            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
-            if (context->get_caps_lock_mode()) {
-                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-            }
-
-            SclUIEventDesc key_event_desc;
-            if (coordinate && button_context) {
-                key_event_desc.key_type = coordinate->key_type;
-
-                key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
-                key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
-            }
-            key_event_desc.key_modifier = context->get_cur_key_modifier(touch_id);;
-
-            key_event_desc.event_type = EVENT_TYPE_RELEASE;
-            key_event_desc.touch_id = touch_id;
-            key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-            key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-            key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
-
-            handler->on_event_drag_state_changed(key_event_desc);
-        }
-
-        if (windows->is_base_window(window)) {
-            state->set_cur_action_state(ACTION_STATE_BASE_INIT);
-        } else {
-            state->set_cur_action_state(ACTION_STATE_POPUP_INIT);
-        }
-
-        /* Restore previously pressed button's context and redraw it */
-        if (button_context && coordinate) {
-            button_context->state = BUTTON_STATE_NORMAL;
-            /* Commented below line to postpone some of the feedback for releasing */
-            //windows->update_window(pressed_window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
-        }
-
-        /* If there is postponed update of button, update it now */
-        sclwindow last_win = context->get_last_pressed_window();
-        scl8 last_key = context->get_last_pressed_key();
-        if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
-            const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
-            if (coords) {
-                windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
-            }
-        }
-
-        /* To postpone some of the feedback for releasing */
-        context->set_last_pressed_key(context->get_cur_pressed_key(touch_id));
-        context->set_last_pressed_window(context->get_cur_pressed_window(touch_id));
-
-        /* Do what has to be done when mouse gets released */
-        sclboolean signaled = FALSE;
-        if (coordinate) {
-            switch (coordinate->popup_type) {
-                case POPUP_TYPE_BTN_RELEASE_POPUP:
-                case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
-                case POPUP_TYPE_BTN_LONGPRESS_POPUP:
-                case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
-                    {
-                        /* Fix me : We should consider z-order */
-                        skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
-                        handle_engine_signal(SCL_SIG_MOUSE_RELEASE, skip_window);
-                        signaled = TRUE;
-                    }
-                    break;
-                case POPUP_TYPE_NONE: break;
-                case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: break;
-                case POPUP_TYPE_AUTO_POPUP: break;
-                case MAX_POPUP_TYPE: break;
-                default: break;
-            }
-        }
-        if (!signaled) {
-            //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
-            window_context = windows->get_window_context(window);
-            if (window_context) {
-                if (window_context->popup_type == POPUP_TYPE_BTN_RELEASE_POPUP ||
-                    window_context->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP) {
-                    /* Don't close window if the clicked button is a child of ReleasePopup window */
-                    skip_window = window;
-                    handle_engine_signal(SCL_SIG_MOUSE_RELEASE, window);
-                    signaled = TRUE;
-                }
-            }
-            if (!signaled) {
-                handle_engine_signal(SCL_SIG_MOUSE_RELEASE);
-            }
-        }
-
-        context->set_cur_pressed_key(touch_id, NOT_USED);
-        context->set_cur_pressed_window(touch_id, SCLWINDOW_INVALID);
-
-        if (ret && button_index != NOT_USED) {
-            const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
-            if (cur_coordinate) {
-                if (cur_coordinate->dont_close_popup) {
-                    skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
-                }
-            }
-        } else {
-            if (pressed_window == windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP)) {
-                if (pressed_window_context) {
-                    if (pressed_window_context->popup_type != POPUP_TYPE_BTN_RELEASE_POPUP_ONCE &&
-                        pressed_window_context->popup_type != POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE &&
-                        pressed_window_context->popup_type != POPUP_TYPE_AUTO_POPUP &&
-                        pressed_window_context->popup_type != POPUP_TYPE_BTN_PRESS_POPUP_DRAG)
-                    {
-                        skip_window = pressed_window;
-                    }
-                }
-            }
-        }
-        windows->close_all_popups(skip_window);
-
-        /* Destroy key related timers */
-        events->destroy_timer(SCL_TIMER_AUTOPOPUP);
-        events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
-        events->destroy_timer(SCL_TIMER_LONGKEY);
-        events->destroy_timer(SCL_TIMER_REPEATKEY);
-
-        /* If there are more than 1 active multitouch ids, don't play button_delay trick */
-        if (context->get_multi_touch_context_num() == 1) {
-            /* To postpone some of the feedback for releasing */
-            events->create_timer(SCL_TIMER_BUTTON_DELAY, m_button_delay_duration, 0);
-        } else {
-            last_win = context->get_last_pressed_window();
-            last_key = context->get_last_pressed_key();
-
-            if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
-                const SclLayoutKeyCoordinate* last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
-                if (last_coordinate) {
-                    windows->update_window(last_win,
-                        last_coordinate->x, last_coordinate->y, last_coordinate->width, last_coordinate->height);
-                }
-            }
-
-            windows->hide_window(windows->get_magnifier_window());
-            context->set_last_pressed_window(SCLWINDOW_INVALID);
-            context->set_last_pressed_key(NOT_USED);
-        }
-    }
-
-    if (context) {
-        if (touch_id == context->get_last_touch_device_id()) {
-            context->set_last_touch_device_id(SCLTOUCHDEVICE_INVALID);
-        }
-        context->destroy_multi_touch_context(touch_id);
-    }
-
-    return ret;
-}
-
-SCLDragState get_drag_state(sclint deltax, sclint deltay)
-{
-    SCLDragState ret = SCL_DRAG_STATE_MAX;
-
-    sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
-    /* If tan(theta) is smaller than our predefined value */
-    if (ratio <= (1 / SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE)) {
-        if (deltax > 0) {
-            ret = SCL_DRAG_STATE_RIGHT;
-        } else {
-            ret = SCL_DRAG_STATE_LEFT;
-        }
-    } else if (ratio >= SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE) {
-        /* If tan(theta) is bigger than our predefined value */
-        if (deltay > 0) {
-            ret = SCL_DRAG_STATE_DOWN;
-        } else {
-            ret = SCL_DRAG_STATE_UP;
-        }
-    } else {
-        ret = SCL_DRAG_STATE_INVALID;
-    }
-
-    return ret;
-}
-
-sclboolean
-CSCLController::mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
-{
-    SCL_DEBUG();
-    sclboolean ret = FALSE;
-
-    if (m_input_events_disabled) return FALSE;
-
-    //utils->log("Controller::mouse_move : %d %d\n", x, y);
-
-    /* Adjust x,y coordinate by touch offset */
-    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
-
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-    CSCLActionState *state = CSCLActionState::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLEvents *events = CSCLEvents::get_instance();
-    CSCLUtils *utils = CSCLUtils::get_instance();
-    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
-    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
-    if (!sclres_manager) return FALSE;
-
-    PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
-    if (!sclres_modifier_decoration) return FALSE;
-
-    if (cache && state && windows && context && utils && adjustment && sclres_manager) {
-        const SclLayout *layout = cache->get_cur_layout(window);
-        if (layout) {
-            x += layout->mouse_manipulate_x;
-            y += layout->mouse_manipulate_y;
-        }
-
-        if (!(context->find_multi_touch_context(touch_id))) return FALSE;
-
-        PSclDefaultConfigure default_configure = sclres_manager->get_default_configure();
-        if (default_configure) {
-            SCLDisplayMode display_mode = context->get_display_mode();
-            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
-        }
-
-        //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
-        SclWindowContext *window_context = windows->get_window_context(window);
-        /* Adjust event x and y positions as relative position to the virtual window */
-        if (window_context) {
-            /*if (window_context->isVirtual) {
-                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
-                if (base_window_context) {
-                    x -= (window_context->x - base_window_context->x);
-                    y -= (window_context->y - base_window_context->y);
-                }
-            }*/
-            /* If the dim window is virtual and currently active, let's just skip this event */
-            if (windows->is_base_window(window)) {
-                SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
-                if (dim_window_context) {
-                    if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
-                        return FALSE;
-                    }
-                }
-            }
-            /* If the pressed event was occured in dim window, let's just skip this move event */
-            if (context->get_last_pressed_window() == windows->get_dim_window()) {
-                return FALSE;
-            }
-        }
-
-        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
-        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
-        SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
-        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
-
-        /* If the multitouch type is SETTLE_PREVIOUS and is not the last touch device, let's ignore move events */
-        if (coordinate) {
-            if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
-                if (context->get_last_touch_device_id() != touch_id) {
-                    return FALSE;
-                }
-            }
-        }
-
-        context->set_cur_moving_point(touch_id, x, y);
-        context->set_cur_moving_window(touch_id, window);
-
-        /* If in longkey state, do not process, just return */
-        if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
-                state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY) {
-            return FALSE;
-        }
-        /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
-        /* And if the event occured in popup window, don't come back to base window */
-        if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
-                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
-            if (windows->is_base_window(window)) {
-                return FALSE;
-            }
-        }
-
-        SclUIEventDesc desc;
-        SCLShiftState shift_index = context->get_shift_state();
-        if (context->get_caps_lock_mode()) {
-            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
-        }
-        if (coordinate) {
-            desc.key_type = coordinate->key_type;
-            desc.key_value = coordinate->key_value[shift_index][0];
-            desc.key_event = coordinate->key_event[shift_index][0];
-        }
-        desc.event_type = EVENT_TYPE_MOVE;
-        desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
-        desc.mouse_current_point = context->get_cur_moving_point(touch_id);
-        desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
-
-        if (handler && handler->on_event_drag_state_changed(desc) != SCL_EVENT_PASS_ON) {
-            return FALSE;
-        }
-
-        /* FIXME : Add a condition to skip this code if longkey timer is not active */
-        /* If the mouse has moved out of threshold value of longkey keypress area, destroy longkey timer */
-        if (m_long_key_cancel_distance > 0) {
-            sclfloat dist = utils->get_distance(x, y,
-                context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
-            if (m_long_key_cancel_distance < dist) {
-                events->destroy_timer(SCL_TIMER_LONGKEY);
-            }
-        }
-
-        if (windows->is_base_window(window)) {
-            state->set_cur_action_state(ACTION_STATE_BASE_MOVING);
-        } else {
-            state->set_cur_action_state(ACTION_STATE_POPUP_MOVING);
-        }
-
-        /* Iterate all the buttons and inform the event */
-        sclboolean ended = FALSE;
-
-        /* Check farthest move point and update it */
-        sclint originx = x;
-        sclint originy = y;
-        if (pressed_window != window) {
-            //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
-            SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
-            if (window_context && pressed_window_context) {
-                originx = (window_context->geometry.x - pressed_window_context->geometry.x) + x;
-                originy = (window_context->geometry.y - pressed_window_context->geometry.y) + y;
-            }
-        }
-        sclint startx = originx;
-        sclint starty = originy;
-
-        /* Check if we should recognize drag curve */
-        if (coordinate) {
-            startx = context->get_cur_pressed_point(touch_id).x;
-            starty = context->get_cur_pressed_point(touch_id).y;
-            sclint deltax = originx - startx;
-            sclint deltay = originy - starty;
-            sclfloat approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
-
-            sclboolean update_magnifier = FALSE;
-            sclboolean drag_state_changed = FALSE;
-            SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
-            SCLDragState next_drag_state = SCL_DRAG_STATE_NONE;
-            sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
-            if (coordinate->is_side_button) {
-                direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
-            };
-
-            if (coordinate->button_type == BUTTON_TYPE_DIRECTION) {
-                /* Do not check farthest move point if current drag state is SCL_DRAG_STATE_RETURN */
-                if (context->get_cur_drag_state(touch_id) != SCL_DRAG_STATE_RETURN) {
-                    if (approximate_dist > context->get_farthest_move_dist(touch_id)) {
-                        context->set_farthest_move_point(touch_id, originx, originy);
-                    }
-                }
-
-                if (cur_drag_state == SCL_DRAG_STATE_RETURN) {
-                    direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_RETURN;
-                } else if (cur_drag_state != SCL_DRAG_STATE_NONE) {
-                    direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_OTHER;
-                }
-                if (approximate_dist > direction_recog_dist) {
-                    next_drag_state = get_drag_state(deltax, deltay);
-                    /* Disable longkey if dragging is recognized */
-                    events->destroy_timer(SCL_TIMER_LONGKEY);
-                }
-                if (cur_drag_state != next_drag_state) {
-                    drag_state_changed = TRUE;
-                }
-                if (cur_drag_state == SCL_DRAG_STATE_NONE) {
-                    //if (nextDragState != SCL_DRAG_STATE_INVALID) {
-                        cur_drag_state = next_drag_state;
-                    //}
-                } else if (cur_drag_state != next_drag_state) {
-                    if (next_drag_state == SCL_DRAG_STATE_NONE) {
-                        cur_drag_state = SCL_DRAG_STATE_RETURN;
-                    } else {
-                        cur_drag_state = next_drag_state;
-                    }
-                }
-
-                context->set_cur_drag_state(touch_id, cur_drag_state);
-                sclboolean check_farthest = FALSE;
-                sclshort display = context->get_display_mode();
-                if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
-                sclfloat dist = utils->get_distance(originx, originy,
-                    context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
-                if (dist < direction_recog_dist && context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
-                    if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
-                        coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
-                        coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
-                            deltax = context->get_farthest_move_point(touch_id).x -
-                                context->get_cur_pressed_point(touch_id).x;
-                            deltay = context->get_farthest_move_point(touch_id).y -
-                                context->get_cur_pressed_point(touch_id).y;
-                            dist = utils->get_distance(context->get_farthest_move_point(touch_id),
-                                context->get_cur_pressed_point(touch_id));
-                            check_farthest = TRUE;
-                    }
-                }
-                SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist,
-                    check_farthest, touch_id, coordinate->extra_option);
-                if (dist > direction_recog_dist) {
-                    context->set_cur_key_modifier(touch_id, key_modifier);
-                }
-                /* If this button needs to be decorated when dragged */
-                if (coordinate->modifier_decorator) {
-                    const SclModifierDecoration *decoration = NULL;
-                    /* FIXME */
-                    /*if (scl_check_arrindex(coordinate->modifier_decorator,
-                        sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
-                    scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
-                    if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
-                        if (sclres_modifier_decoration[decoration_id].valid) {
-                            decoration = &(sclres_modifier_decoration[decoration_id]);
-                        }
-                    }
-                    /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
-                    if (decoration) {
-                        if (decoration->bg_image_path[display][key_modifier]) {
-                            windows->update_window(window,
-                                coordinate->x, coordinate->y, coordinate->width, coordinate->height);
-                        }
-                    }
-                }
-                if (dist > direction_recog_dist) {
-                    if (context->get_magnifier_enabled()) {
-                        update_magnifier = TRUE;
-                    }
-                }
-            } else if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
-                if (cur_drag_state != SCL_DRAG_STATE_NONE) {
-                    startx = context->get_prev_moving_point(touch_id).x;
-                    starty = context->get_prev_moving_point(touch_id).y;
-                    approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
-                    direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
-                }
-                deltax = originx - startx;
-                deltay = originy - starty;
-                //printf("DIST : %f, RECOG : %f\n", dist, direction_recog_dist);
-                if (approximate_dist > direction_recog_dist) {
-                    next_drag_state = get_drag_state(deltax, deltay);
-                    /* Disable longkey if dragging is recognized */
-                    events->destroy_timer(SCL_TIMER_LONGKEY);
-
-                    if (cur_drag_state != next_drag_state) {
-                        drag_state_changed = TRUE;
-                    }
-                    if (next_drag_state != SCL_DRAG_STATE_NONE) {
-                        cur_drag_state = next_drag_state;
-                    }
-                    context->set_cur_drag_state(touch_id, cur_drag_state);
-
-                    startx = context->get_farthest_move_point(touch_id).x;
-                    starty = context->get_farthest_move_point(touch_id).y;
-                    deltax = originx - startx;
-                    deltay = originy - starty;
-                    sclfloat dist_farthest = utils->get_approximate_distance(originx, originy, startx, starty);
-                    //printf("%d %d %d %d %f, %d %d\n", originx, originy, startx, starty, dist_farthest, cur_drag_state, next_drag_state);
-                    /* Let's see how much we are away from the last farthest point */
-                    sclfloat diffdir_recog_dist = SCL_DIRECTION_RELATIVE_DIFFDIR_RECOG_DIST * utils->get_smallest_scale_rate();
-                    /* If we moved certain amount from the point where direction changed, process drag state change routine */
-                    if (dist_farthest > diffdir_recog_dist || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_NONE) {
-                        sclshort display = context->get_display_mode();
-                        SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist_farthest,
-                            FALSE, touch_id, coordinate->extra_option);
-                        context->set_cur_key_modifier(touch_id, key_modifier);
-                        /* If this button needs to be decorated when dragged */
-                        if (coordinate->modifier_decorator) {
-                            const SclModifierDecoration  *decoration = NULL;
-                            /* FIXME */
-                            /*if (scl_check_arrindex(coordinate->modifier_decorator,
-                                sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
-                            scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
-                            if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
-                                if (sclres_modifier_decoration[decoration_id].valid) {
-                                    decoration = &(sclres_modifier_decoration[decoration_id]);
-                                }
-                            }
-                            /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
-                            if (decoration) {
-                                if (decoration->bg_image_path[display][key_modifier]) {
-                                    windows->update_window(window,
-                                        coordinate->x, coordinate->y, coordinate->width, coordinate->height);
-                                }
-                            }
-                        }
-
-                        if (context->get_magnifier_enabled()) {
-                            update_magnifier = TRUE;
-                        }
-                    }
-                    context->set_prev_moving_point(touch_id, originx, originy);
-                }
-                if (drag_state_changed) {
-                    /* When the dragging direction changes, save the current position as farthest point for future comparison */
-                    context->set_farthest_move_point(touch_id, originx, originy);
-                    LOGD("SET_FARTHEST : %d %d %d", originx, originy, context->get_cur_drag_state(touch_id));
-                }
-            }
-
-            if (update_magnifier) {
-                PSclMagnifierWndConfigure magnifier_configure = NULL;
-                if (sclres_manager) {
-                    magnifier_configure = sclres_manager->get_magnifier_configure();
-                }
-
-                const SclLayout *base_layout = cache->get_cur_layout(windows->get_base_window());
-                if (base_layout && magnifier_configure) {
-                    SclPoint zoomwinpos = {0, 0};
-                    /* calculates x position to be set */
-                    zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
-                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
-
-                    /* calculates y position to be set */
-                    sclint scnWidth, scnHeight;
-                    utils->get_screen_resolution(&scnWidth, &scnHeight);
-
-                    zoomwinpos.y =  coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
-                    if (window_context) {
-                        zoomwinpos.x += window_context->geometry.x;
-                        zoomwinpos.y += window_context->geometry.y;
-                    }
-                    if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
-                        zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
-                    }
-                    if (zoomwinpos.x > scnWidth +
-                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                        magnifier_configure->width * utils->get_custom_scale_rate_x()) {
-                        zoomwinpos.x = scnWidth +
-                            magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
-                            magnifier_configure->width * utils->get_custom_scale_rate_x();
-                    }
-                    zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
-
-                    zoomwinpos.x += coordinate->magnifier_offset_x;
-                    zoomwinpos.y += coordinate->magnifier_offset_y;
-                    windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
-                    windows->show_window(windows->get_magnifier_window(), 0);
-                }
-            }
-        }
-
-        sclboolean grab_event = FALSE;
-        if (layout) {
-            if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
-                grab_event = TRUE;
-            }
-            /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
-            if (grab_event && window_context) {
-                /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
-                sclboolean in_grab_area = TRUE;
-                if (layout->add_grab_left != NOT_USED && x < -(layout->add_grab_left)) {
-                    in_grab_area = FALSE;
-                }
-                if (layout->add_grab_right != NOT_USED && x >
-                    (window_context->geometry.width + layout->add_grab_right)) {
-                    in_grab_area = FALSE;
-                }
-                if (layout->add_grab_top != NOT_USED && y < -(layout->add_grab_top)) {
-                    in_grab_area = FALSE;
-                }
-                if (layout->add_grab_bottom != NOT_USED && y >
-                    (window_context->geometry.height + layout->add_grab_bottom)) {
-                    in_grab_area = FALSE;
-                }
-                if (in_grab_area) {
-                    float min_dist = (float)((unsigned int)(-1));
-                    int min_dist_index = NOT_USED;
-                    for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
-                        button_context = cache->get_cur_button_context(window, loop);
-                        const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
-                        if (button_context && cur_coordinate) {
-                            if (!(button_context->used)) {
-                                ended = TRUE;
-                            } else if (button_context->state != BUTTON_STATE_DISABLED &&
-                                cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                                float dist = utils->get_approximate_distance(x, y,
-                                        cur_coordinate->x + (cur_coordinate->width / 2),
-                                        cur_coordinate->y + (cur_coordinate->height / 2));
-                                if (dist < min_dist) {
-                                    min_dist_index = loop;
-                                    min_dist = dist;
-                                }
-                            }
-                        }
-                    }
-                    /* When we found the nearest button, generate this event on the button */
-                    if (min_dist_index != NOT_USED) {
-                        const SclLayoutKeyCoordinate *min_coordinate =
-                            cache->get_cur_layout_key_coordinate(window, min_dist_index);
-                        if (min_coordinate) {
-                            x = min_coordinate->x + (min_coordinate->width / 2);
-                            y = min_coordinate->y + (min_coordinate->height / 2);
-                            if (process_button_move_event(window, x, y, min_dist_index, touch_id, actual_event)) {
-                                ret = TRUE;
-                            }
-                        }
-                    }
-                }
-            } else {
-                MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
-                if (multi_touch_context) {
-                    sclint button_index = NOT_USED;
-                    if (!(multi_touch_context->is_sub_event)) {
-                        sclboolean process_finished = FALSE;
-                        do {
-                            /* First check if the event occured in pressed key's threshold area */
-                            if (button_context && coordinate) {
-                                if (pressed_window == window) { // Check only when the window is the one initally pressed
-                                    if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
-                                        if (process_button_move_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
-                                            ret = TRUE;
-                                            x = coordinate->x + (coordinate->width / 2);
-                                            y = coordinate->y + (coordinate->height / 2);
-                                            button_index = pressed_key;
-                                        }
-                                    }
-                                }
-                            }
-                            for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
-                                button_context = cache->get_cur_button_context(window, loop);
-                                const SclLayoutKeyCoordinate *cur_coordinate =
-                                    cache->get_cur_layout_key_coordinate(window, loop);
-                                if (button_context && cur_coordinate) {
-                                    if (!(button_context->used)) {
-                                        ended = TRUE;
-                                    } else if (button_context->state != BUTTON_STATE_DISABLED &&
-                                                cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                                        if (window != pressed_window || loop != pressed_key) {
-                                            if (process_button_move_event(window, x, y, loop, touch_id, actual_event)) {
-                                                ret = TRUE;
-                                                button_index = loop;
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-
-                            if (windows->is_base_window(window)) {
-                                process_finished = TRUE;
-                            } else if (button_index != NOT_USED) {
-                                process_finished = TRUE;
-                            } else {
-                                const SclLayout *cur_layout = cache->get_cur_layout(window);
-                                if (cur_layout && cur_layout->use_sw_background && cur_layout->bg_color.a == 0) {
-                                    /* If we could not find appropriate button in this popup window and the popup is transparent */
-                                    SclWindowContext *base_window_context =
-                                        windows->get_window_context(windows->get_base_window());
-                                    if (base_window_context && window_context) {
-                                        x = (window_context->geometry.x + x - base_window_context->geometry.x);
-                                        y = (window_context->geometry.y + y - base_window_context->geometry.y);
-                                    }
-                                    window = windows->get_base_window();
-                                } else {
-                                    process_finished = TRUE;
-                                }
-                            }
-                        } while (!process_finished);
-                    }
-                }
-            }
-        }
-    }
-
-    return ret;
-}
-
-sclboolean
-CSCLController::mouse_over(sclwindow window, sclint x, sclint y)
-{
-    SCL_DEBUG();
-    sclboolean ret = FALSE;
-
-    if (m_input_events_disabled)
-        return FALSE;
-
-    /* Adjust x,y coordinate by touch offset */
-    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
-    /* Iterate all the buttons and inform the event */
-
-    CSCLContext *context = CSCLContext::get_instance();
-    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
-    CSCLActionState *state = CSCLActionState::get_instance();
-    CSCLWindows *windows = CSCLWindows::get_instance();
-    CSCLUtils *utils = CSCLUtils::get_instance();
-    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
-
-    if (cache && state && windows && context && utils && adjustment && sclres_manager) {
-        const SclLayout *layout = cache->get_cur_layout(window);
-        if (layout) {
-            x += layout->mouse_manipulate_x;
-            y += layout->mouse_manipulate_y;
-        }
-
-        SCLDisplayMode cur_display_mode = context->get_display_mode();
-
-        const SclDefaultConfigure *default_configure = sclres_manager->get_default_configure();
-        if (default_configure) {
-            adjustment->apply_touch_offset(default_configure->touch_offset_level[cur_display_mode], &x, &y);
-        }
-
-        /* Iterate all the buttons and inform the event */
-        sclboolean ended = FALSE;
-
-        for (int loop = 0; loop < MAX_KEY && !ended && !ret; loop++) {
-            SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
-            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
-            if (button_context && coordinate) {
-                if (!(button_context->used)) {
-                    ended = TRUE;
-                } else if (button_context->state != BUTTON_STATE_DISABLED &&
-                            coordinate->button_type != BUTTON_TYPE_UIITEM) {
-                    if (process_button_over_event(window, x, y, loop)) {
-                        ret = TRUE;
-                    }
-                }
-            }
-        }
-    }
-
-    return ret;
-}
-
-
 /**
  * Processes a timer event
  * If return FALSE, the current timer will be stop
@@ -3539,7 +522,8 @@ CSCLController::timer_event(const scl32 data)
         /* Ignores if the event id is different */
         sclwindow window = context->get_cur_pressed_window(context->get_last_touch_device_id());
         sclbyte key_index = context->get_cur_pressed_key(context->get_last_touch_device_id());
-        if (process_button_long_pressed_event(window, key_index, context->get_last_touch_device_id())) {
+        CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+        if (controller_button->process_button_long_pressed_event(window, key_index, context->get_last_touch_device_id())) {
             /* The button processed long key event, now enter longkey mode not to fire any events before releasing */
             handle_engine_signal(SCL_SIG_MOUSE_LONG_PRESS, window);
             windows->update_window(windows->get_magnifier_window());
@@ -3602,7 +586,8 @@ CSCLController::timer_event(const scl32 data)
         if (interval < SCL_REPEATKEY_MIN_DURATION) {
             interval = SCL_REPEATKEY_MIN_DURATION;
         }
-        process_button_repeat_pressed_event(window, key_index, context->get_last_touch_device_id());
+        CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+        controller_button->process_button_repeat_pressed_event(window, key_index, context->get_last_touch_device_id());
         events->destroy_timer(id);
         events->create_timer(SCL_TIMER_REPEATKEY, interval, value);
         m_key_repeated_num++;
@@ -3876,6 +861,12 @@ CSCLController::set_longkey_duration(scllong msc)
     return ret;
 }
 
+scllong
+CSCLController::get_longkey_duration()
+{
+    return m_long_key_duration;
+}
+
 /**
 * Sets the distance value for cancel longkey
 * If not set, it will use default longkey duration. see sclconfig
@@ -3892,6 +883,12 @@ CSCLController::set_longkey_cancel_dist(sclshort dist)
     return ret;
 }
 
+sclshort
+CSCLController::get_longkey_cancel_dist()
+{
+    return m_long_key_cancel_distance;
+}
+
 /**
 * Sets the duration value for repeatkey
 * If not set, it will use default repeatkey duration. see sclconfig
@@ -3908,6 +905,12 @@ CSCLController::set_repeatkey_duration(scllong msc)
     return ret;
 }
 
+scllong
+CSCLController::get_repeatkey_duration()
+{
+    return m_repeat_key_duration;
+}
+
 /**
  * Sets the duration value for autopopup key
  * If not set, it will use default short longkey duration. see sclconfig
@@ -3924,6 +927,12 @@ CSCLController::set_autopopup_key_duration(scllong msc)
     return ret;
 }
 
+scllong
+CSCLController::get_autopopup_key_duration()
+{
+    return m_autopopup_key_duration;
+}
+
 /**
  * Sets the amount value for button delay
  * If not set, it will use default button delay amount. see sclconfig
@@ -3940,6 +949,24 @@ CSCLController::set_button_delay_duration(scllong msc)
     return ret;
 }
 
+scllong
+CSCLController::get_button_delay_duration()
+{
+    return m_button_delay_duration;
+}
+
+sclint
+CSCLController::get_key_repeated_num()
+{
+    return m_key_repeated_num;
+}
+
+scllong
+CSCLController::get_multitap_delay_duration()
+{
+    return m_multitap_delay_duration;
+}
+
 /**
  * Configures the variables for auto-popup window
  * It will return rectangle area
@@ -4125,3 +1152,9 @@ CSCLController::disable_input_events(sclboolean disabled)
 {
     m_input_events_disabled = disabled;
 }
+
+sclboolean
+CSCLController::get_input_events_disabled()
+{
+    return m_input_events_disabled;
+}
index 0a97612..1b00b14 100644 (file)
@@ -59,49 +59,38 @@ public:
     static CSCLController* get_instance();
     void init();
 
-private:
-    sclboolean process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
-        scltouchdevice touch_id, sclboolean actual_event = TRUE);
-    sclboolean process_button_long_pressed_event(sclwindow window, sclbyte key_index,
-        scltouchdevice touch_id, sclboolean actual_event = TRUE);
-    sclboolean process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
-        scltouchdevice touch_id, sclboolean actual_event = TRUE);
-    sclboolean process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
-        scltouchdevice touch_id, sclboolean actual_event = TRUE);
-    sclboolean process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index);
-    sclboolean process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
-        scltouchdevice touch_id, sclboolean actual_event = TRUE);
-
+public:
     sclboolean configure_autopopup_window(sclwindow window, sclbyte key_index, SclRectangle* rect);
 
     sclboolean check_event_transition_enabled(const SclLayoutKeyCoordinate *btnFrom, const SclLayoutKeyCoordinate *btnTo);
     sclboolean check_magnifier_available(sclwindow window, sclbyte key_index, scltouchdevice touch_id);
 
-    SCLKeyModifier get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist,
-        sclboolean check_farthest, scltouchdevice touch_id, sclbyte extra_option);
-
-public:
     void handle_engine_signal(SclInternalSignal signal, sclwindow skip_window = SCLWINDOW_INVALID);
     sclboolean process_input_mode_change(const sclbyte mode);
     sclboolean process_rotation_change(const SCLRotation rotation);
 
-    sclboolean mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
-    sclboolean mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
-    sclboolean mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
-    sclboolean mouse_over(sclwindow window, sclint x, sclint y);
     sclboolean timer_event(const scl32 id);
 
     sclboolean set_longkey_duration(scllong msc);
+    scllong get_longkey_duration();
     sclboolean set_longkey_cancel_dist(sclshort dist);
+    sclshort get_longkey_cancel_dist();
     sclboolean set_repeatkey_duration(scllong msc);
+    scllong get_repeatkey_duration();
     sclboolean set_autopopup_key_duration(scllong msc);
+    scllong get_autopopup_key_duration();
 
     sclboolean set_button_delay_duration(scllong msc);
+    scllong get_button_delay_duration();
+
+    sclint get_key_repeated_num();
+    scllong get_multitap_delay_duration();
 
     SCLDebugMode get_debug_mode();
     void set_debug_mode(SCLDebugMode mode);
 
     void disable_input_events(sclboolean disabled);
+    sclboolean get_input_events_disabled();
 
 protected:
     /* Interval time(msc) for checking long key event */
diff --git a/scl/sclcontroller_button.cpp b/scl/sclcontroller_button.cpp
new file mode 100644 (file)
index 0000000..4686043
--- /dev/null
@@ -0,0 +1,1700 @@
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <time.h>
+#include <math.h>
+#include <assert.h>
+#include <vector>
+
+#include "sclcontroller.h"
+#include "sclcontroller_button.h"
+#include "sclcontroller_mouse.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclactionstate.h"
+#include "scluibuilder.h"
+#include "sclkeydefines.h"
+#include "sclfeedback.h"
+#include "sclerroradjustment.h"
+#include "sclimageproxy.h"
+#include "sclres_manager.h"
+#include "scleventhandler.h"
+#include "sclanimator.h"
+#include "sclkeyfocushandler.h"
+#include <dlog.h>
+
+//#define DIRECTLY_DRAW_ON_EVENTS
+
+using namespace scl;
+
+static sclboolean
+_play_tts_for_input_mode_name(int mode) {
+    SCL_DEBUG();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    if (context && context->get_tts_enabled() == FALSE) {
+        return FALSE;
+    }
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return FALSE;
+
+    const SclInputModeConfigure *pinput_mode_table = sclres_manager->get_input_mode_configure_table();
+    if (NULL == pinput_mode_table) {
+        return FALSE;
+    }
+
+    const char* name = pinput_mode_table[mode].name;
+    if (NULL == name) {
+        return FALSE;
+    }
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    if (utils)
+        utils->play_tts(name);
+    return TRUE;
+}
+
+CSCLControllerButton*
+CSCLControllerButton::get_instance()
+{
+    static CSCLControllerButton instance;
+    return &instance;
+}
+
+sclboolean
+CSCLControllerButton::process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+                                             scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+    sclboolean redraw = FALSE;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!sclres_manager) return FALSE;
+
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    PSclLayout sclres_layout = sclres_manager->get_layout_table();
+    if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
+
+    SclButtonContext *button_context = NULL;
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (context && cache) {
+        button_context = cache->get_cur_button_context(window, key_index);
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    }
+
+    if (context && cache && windows && events && utils && feedback && handler && button_context && coordinate) {
+        /* First check if this button is enabled in current active sublayout */
+        sclboolean sub_layout_match = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                sub_layout_match = FALSE;
+            }
+        }
+
+        /* If this button is pressed */
+        if ( x >= coordinate->x - coordinate->add_hit_left &&
+                x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
+                y >= coordinate->y - coordinate->add_hit_top &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
+                /* Process the event only if the this item's sublayout id is active one */
+                sub_layout_match ) {
+            /* If currently shift mode is ON, and the last key was multitap, this means the shift did not
+               turned off because of multitap button. So we need to turn it off here forcibly */
+            sclwindow last_win = context->get_last_event_fired_window();
+            scl8 last_key = context->get_last_event_fired_key();
+            LOGD("last_win : %p last_key : :%d", last_win, last_key);
+            const SclLayoutKeyCoordinate *last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
+            if (last_coordinate) {
+                LOGD("last_coordinate->button_type : %d", last_coordinate->button_type);
+                if (last_coordinate->button_type == BUTTON_TYPE_MULTITAP && context->get_shift_state() == SCL_SHIFT_STATE_ON) {
+                    /* And if the multitap button was different from the one we are dealing with... */
+                    LOGD("last_win %p window %p last_key %d key_index %d", last_win, window, last_key, key_index);
+                    if (last_win != window || last_key != key_index) {
+                        SclNotiShiftStateChangeDesc desc;
+                        desc.ui_event_desc = NULL;
+                        desc.shift_state = SCL_SHIFT_STATE_OFF;
+
+                        SCLEventReturnType ret = handler->on_event_notification(SCL_UINOTITYPE_SHIFT_STATE_CHANGE, &desc);
+                        if (ret == SCL_EVENT_PASS_ON) {
+                            context->set_shift_state(SCL_SHIFT_STATE_OFF);
+                            windows->update_window(windows->get_base_window());
+                        }
+                    }
+                }
+            }
+
+            /* If newly pressed key has type MULTI_TOUCH_TYPE_EXCLUSIVE, release all existing pressed events */
+            if (actual_event) {
+                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_EXCLUSIVE) {
+                    /* When calling mouse_release, the seq order of current multitouch events will be changed,
+                    so we put all the multitouch events into a vector and use them afterwards forreleasing */
+                    sclint loop = 0;
+                    sclint multi_touch_context_num = context->get_multi_touch_context_num();
+                    std::vector<SclUIEventDesc> multi_touch_events;
+                    for (loop = 0;loop < multi_touch_context_num;loop++) {
+                        SclUIEventDesc desc;
+                        context->get_multi_touch_event(loop, &desc);
+                        multi_touch_events.push_back(desc);
+                    }
+                    for (loop = 0;loop < multi_touch_context_num;loop++) {
+                        SclUIEventDesc desc = multi_touch_events[loop];
+                        if (desc.touch_id != touch_id) {
+                            CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+                            controller_mouse->mouse_release(context->get_cur_moving_window(desc.touch_id),
+                                context->get_cur_moving_point(desc.touch_id).x,
+                                context->get_cur_moving_point(desc.touch_id).y,
+                                desc.touch_id, FALSE);
+                        }
+                    }
+                }
+            }
+
+            /* Make an unique ID for timer */
+            const scl16 uniqId = utils->get_unique_id();
+
+            context->set_cur_pressed_event_id(touch_id, uniqId);
+            context->set_cur_pressed_key(touch_id, key_index);
+            context->set_cur_pressed_window(touch_id, window);
+
+            button_context->state = BUTTON_STATE_PRESSED;
+
+            if (context->get_highlight_ui_enabled()) {
+                CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
+                if (focus_handler) {
+                    sclwindow prev_window = focus_handler->get_current_focus_window();
+                    scl8 prev_key = focus_handler->get_current_focus_key();
+                    const SclLayoutKeyCoordinate *prev_coordinate =
+                        cache->get_cur_layout_key_coordinate(prev_window, prev_key);
+
+                    focus_handler->set_current_focus(window, key_index);
+
+                    if (prev_coordinate) {
+                        windows->update_window(prev_window,
+                            prev_coordinate->x, prev_coordinate->y, prev_coordinate->width, prev_coordinate->height);
+                    }
+                }
+            }
+
+            redraw = TRUE;
+            ret = TRUE;
+
+#ifndef DIRECTLY_DRAW_ON_EVENTS
+            /* If the window doesn't get exposed before corresponding release event,
+             * the inverted state of a button will never be drawn onto screen.
+             * To prevent such a case, we draw the inverted state of button forcefully and directly,
+             * without waiting for expose event */
+            /*CSCLGraphics *grps = CSCLGraphics::get_instance();
+            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+            scldrawctx draw_ctx = grps->begin_paint(window, TRUE);
+            builder->draw_button(window, draw_ctx, key_index, button_context->state, TRUE);
+            grps->end_paint(window, draw_ctx);*/
+#endif
+
+            /* for feedback */
+            feedback->button_pressed(window, key_index);
+
+            /* Special routine for autopopup */
+            if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
+                CSCLController *controller = CSCLController::get_instance();
+                events->create_timer(SCL_TIMER_AUTOPOPUP, controller->get_autopopup_key_duration(), uniqId);
+            } else {
+                /* for long key & repeat key */
+                CSCLController *controller = CSCLController::get_instance();
+                events->create_timer(SCL_TIMER_LONGKEY, controller->get_longkey_duration(), uniqId);
+            }
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            SclUIEventDesc key_event_desc;
+            key_event_desc.key_value = coordinate->key_value[shift_index][0];
+            key_event_desc.key_event = coordinate->key_event[shift_index][0];
+            key_event_desc.key_type = coordinate->key_type;
+            key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+            key_event_desc.event_type = EVENT_TYPE_PRESS;
+
+            SclPoint curpoint = {x, y};
+            key_event_desc.touch_id = touch_id;
+            key_event_desc.mouse_pressed_point = curpoint;
+            key_event_desc.mouse_current_point = curpoint;
+            key_event_desc.mouse_farthest_point = curpoint;
+
+            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+            SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
+
+            /* Only if the handler didn't return SCL_EVENT_DONE */
+            if (processed == SCL_EVENT_PASS_ON) {
+                /* Now process normal behaviours of each button type */
+                switch (coordinate->button_type) {
+                case BUTTON_TYPE_NORMAL:
+                case BUTTON_TYPE_GRAB:
+                case BUTTON_TYPE_SELFISH:
+                case BUTTON_TYPE_DIRECTION:
+                case BUTTON_TYPE_RELATIVE_DIRECTION: {
+                    /* Send click event right away if this button uses repeat key */
+                    if (coordinate->use_repeat_key) {
+                        handler->on_event_key_clicked(key_event_desc);
+                    }
+                }
+                break;
+                case BUTTON_TYPE_MULTITAP: {
+                }
+                break;
+                case BUTTON_TYPE_ROTATION: {
+                }
+                break;
+                case BUTTON_TYPE_DRAG: {
+                    /* Drag buttons fires click event immediately when they are pressed */
+                    handler->on_event_key_clicked(key_event_desc);
+                }
+                break;
+                case BUTTON_TYPE_UIITEM: break;
+                case MAX_BUTTON_TYPE: break;
+                default: break;
+                }
+                switch (coordinate->popup_type) {
+                case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: {
+                    SclNotiPopupOpeningDesc desc;
+                    desc.ui_event_desc = &key_event_desc;
+                    desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+                    if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+                        sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+                        SCLDisplayMode display_mode = context->get_display_mode();
+                        /* FIXME */
+                        //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+                        if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+                            scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                            sclshort popupLayoutId =
+                                sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+                            SclRectangle popupRect;
+                            SclRectangle baseWndRect;
+                            SclLayout *layout = NULL;
+                            /* FIXME */
+                            //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+                            if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+                                layout = &sclres_layout[popupLayoutId];
+                            }
+                            if (layout) {
+                                windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+                                popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+                                popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+                                //popupRect.width = utils->get_scale_x(layout->width);
+                                //popupRect.height= utils->get_scale_y(layout->height);
+                                if (!(sclres_manager->loaded(popupLayoutId))) {
+                                    sclres_manager->load(popupLayoutId);
+                                }
+                                popupRect.width = layout->width;
+                                popupRect.height = layout->height;
+                                windows->close_all_popups();
+
+                                SclWindowOpener opener;
+                                opener.window = window;
+                                opener.key = key_index;
+
+                                sclwindow popup_window = windows->open_popup(opener,
+                                    popupRect,
+                                    popup_input_mode,
+                                    popupLayoutId,
+                                    coordinate->popup_type,
+                                    sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+                                    sclres_input_mode_configure[popup_input_mode].use_dim_window,
+                                    coordinate->extract_offset_x,
+                                    coordinate->extract_offset_y,
+                                    sclres_input_mode_configure[popup_input_mode].timeout);
+
+                                SclNotiPopupOpenedDesc opened_desc;
+                                opened_desc.ui_event_desc = &key_event_desc;
+                                opened_desc.input_mode = desc.input_mode;
+                                opened_desc.window = popup_window;
+                                handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+                                windows->hide_window(windows->get_magnifier_window());
+                                /* FIXME : The parent key should be turned back to NORMAL state when RELEASED,
+                                    in case of POPUP_TYPE_BTN_PRESS_POPUP_DRAG type. Temporarily setting NORMAL here. */
+                                button_context->state = BUTTON_STATE_NORMAL;
+                                _play_tts_for_input_mode_name(popup_input_mode);
+                            }
+                        }
+                    }
+                }
+                break;
+                case POPUP_TYPE_BTN_RELEASE_POPUP:
+                case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
+                case POPUP_TYPE_AUTO_POPUP:
+                case POPUP_TYPE_NONE:
+                case MAX_POPUP_TYPE:
+                default:
+                    /* Nothing to do in here */
+                    break;
+                }
+            }
+
+            /* Shows the magnifier window(the magnifier window will display when a kind of button type is character) */
+            //if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
+            if (coordinate->use_magnifier) {
+                CSCLController *controller = CSCLController::get_instance();
+                sclboolean showMagnifier = controller->check_magnifier_available(window, key_index, touch_id);
+
+                PSclMagnifierWndConfigure magnifier_configure = NULL;
+                if (sclres_manager) {
+                    magnifier_configure = sclres_manager->get_magnifier_configure();
+                }
+                if (showMagnifier && magnifier_configure) {
+                    SclPoint pos = {0, 0};
+                    /* calculates x position to be set */
+                    pos.x = (coordinate->x + (coordinate->width / 2)) -
+                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                    /* calculates y position to be set */
+                    sclint scnWidth, scnHeight;
+                    utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                    pos.y = coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+
+                    /* FIXME : Temporary way of clearing magnifier window */
+                    /*SclWindowContext *window_context = windows->get_window_context(windows->get_magnifier_window(), FALSE);
+                    sclboolean clearmagwin = FALSE;
+                    if (window_context) {
+                        clearmagwin = !(window_context->hidden);
+                    }
+                    static int clearnum = 0;
+                    if (key_index == prevkey && window == prevwin) {
+                        clearmagwin = FALSE;
+                    }
+                    if (clearmagwin) {
+                        if (++clearnum > 1) {
+                            clearmagwin = FALSE;
+                        }
+                    } else {
+                        clearnum = 0;
+                    }
+
+                    if (clearmagwin) {
+                        CSCLGraphics *graphics = CSCLGraphics::get_instance();
+                        CSCLUtils *utils = CSCLUtils::get_instance();
+                        sclchar composed_path[_POSIX_PATH_MAX] = {0,};
+                        scldrawctx draw_ctx = graphics->begin_paint(windows->get_magnifier_window());
+                        utils->get_composed_path(composed_path, scl_magnifier_configure.bg_image_path);
+                        graphics->draw_image(windows->get_magnifier_window(), draw_ctx, composed_path, 0, 0);
+                        graphics->end_paint(windows->get_magnifier_window(), draw_ctx);
+                    }
+                    */
+                    windows->hide_window(windows->get_magnifier_window());
+
+                    SclWindowContext *window_context = windows->get_window_context(window);
+                    if (window_context) {
+                        pos.x += window_context->geometry.x;
+                        pos.y += window_context->geometry.y;
+                    }
+
+                    if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                        pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                    }
+                    if (pos.x > scnWidth +
+                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                        magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                        pos.x = scnWidth + magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                            magnifier_configure->width * utils->get_custom_scale_rate_x();
+                    }
+                    pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                    pos.x += coordinate->magnifier_offset_x;
+                    pos.y += coordinate->magnifier_offset_y;
+                    windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+                    //windows->resize_window(windows->get_magnifier_window(), utils->get_scale_x(scl_magnifier_configure.width), utils->get_scale_y(scl_magnifier_configure.height));
+                    /*If we use transient_for them the ISE will occur some crash. It needs to check X11 */
+                    /*windows->set_parent(windows->get_base_window(), windows->get_magnifier_window());*/
+
+                    windows->show_window(windows->get_magnifier_window(), TRUE);
+                    //windows->update_window(windows->get_magnifier_window());
+                }
+#if 0
+                static int fFirst = true;
+                if (fFirst) {
+                    windows->show_window(windows->get_magnifier_window());
+                    fFirst = false;
+                } else {
+                    windows->update_window(windows->get_magnifier_window());
+                }
+#endif
+                /* We cannot use move_resize_window. It had occured some wrong behavior */
+                /*windows->move_resize_window(windows->get_magnifier_window(), pos.x, pos.y, scl_magnifier_configure.width, scl_magnifier_configure.height);*/
+                if (!showMagnifier) {
+                    windows->hide_window(windows->get_magnifier_window());
+                }
+            }
+        } else {
+            /* COMMENTED OUT FOR TESTING MULTITOUCH!! */
+            ///* In case the current button is not the given key index */
+            //if (button_context->state == BUTTON_STATE_PRESSED) {
+            //    /* Even if the press event occurs outside of this button's physical area, reset its context */
+            //    button_context->state = BUTTON_STATE_NORMAL;
+            //    redraw = TRUE;
+            //}
+            /* BUTTON_TYPE_MULTITAP type button should restore its multikey index when another button is clicked */
+            if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
+                button_context->multitap_index = 0;
+            }
+        }
+
+        /* If there is any need for redrawing */
+        if (redraw) {
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+            if (builder) {
+                builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
+            }
+#else
+            if (windows) {
+                windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            }
+#endif
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_long_pressed_event(sclwindow window, sclbyte key_index,
+                                                  scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!sclres_manager) return FALSE;
+
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    PSclLayout sclres_layout = sclres_manager->get_layout_table();
+
+    if (!sclres_input_mode_configure || !sclres_layout) return FALSE;
+
+    if (context && cache && handler && windows && state) {
+        const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        SclButtonContext *button_context = cache->get_cur_button_context(window, key_index);
+
+        /* Should return FALSE if this key does not have any longkey related property */
+        if (coordinate) {
+            if (actual_event) {
+                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                    /* When calling mouse_release, the seq order of current multitouch events will be changed,
+                       so we put all the multitouch events into a vector and use them afterwards for releasing */
+                    sclboolean finished = FALSE;
+                    sclint loop = 0;
+                    sclint multi_touch_context_num = context->get_multi_touch_context_num();
+                    std::vector<SclUIEventDesc> multitouch_events;
+                    for (loop = 0;loop < multi_touch_context_num;loop++) {
+                        SclUIEventDesc desc;
+                        context->get_multi_touch_event(loop, &desc);
+                        multitouch_events.push_back(desc);
+                    }
+                    for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
+                        SclUIEventDesc desc = multitouch_events[loop];
+                        if (desc.touch_id != touch_id) {
+                            sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
+                            scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
+                            const SclLayoutKeyCoordinate *cur_pressed_coordinate =
+                                cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
+                            if (cur_pressed_coordinate) {
+                                if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                                    CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+                                    controller_mouse->mouse_release(context->get_cur_moving_window(desc.touch_id),
+                                        context->get_cur_moving_point(desc.touch_id).x,
+                                        context->get_cur_moving_point(desc.touch_id).y,
+                                        desc.touch_id, FALSE);
+                                }
+                            }
+                        } else {
+                            finished = TRUE;
+                        }
+                    }
+                }
+            }
+        }
+
+        /* Should return FALSE if this key does not have any longkey related property */
+        if (coordinate) {
+            if (coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP ||
+                coordinate->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE ) {
+                    SclUIEventDesc key_event_desc;
+                    key_event_desc.key_type = coordinate->long_key_type;
+                    if (coordinate->long_key_value == NULL && coordinate->long_key_event == 0) {
+                        SCLShiftState shift_index = context->get_shift_state();
+                        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                        if (context->get_caps_lock_mode()) {
+                            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                        }
+
+                        key_event_desc.key_value = coordinate->key_value[shift_index][0];
+                        key_event_desc.key_event = coordinate->key_event[shift_index][0];
+                    } else {
+                        key_event_desc.key_value = coordinate->long_key_value;
+                        key_event_desc.key_event = coordinate->long_key_event;
+                    }
+                    key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
+
+                    key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
+                    key_event_desc.touch_id = touch_id;
+                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                    SCLEventReturnType processed = handler->on_event_drag_state_changed(key_event_desc);
+
+                    /* Only if the handler didn't return SCL_EVENT_DONE */
+                    if (processed == SCL_EVENT_PASS_ON) {
+                        SclRectangle popupRect;
+                        SclRectangle baseWndRect;
+                        windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+                        popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+                        popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+
+                        SclNotiPopupOpeningDesc desc;
+                        desc.ui_event_desc = &key_event_desc;
+                        desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+                        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+                            sclint popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+                            SCLDisplayMode display_mode = context->get_display_mode();
+                            /* FIXME */
+                            //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+                            if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+                                scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                                SclLayout *layout = NULL;
+                                sclshort popupLayoutId =
+                                    sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+                                /* FIXME */
+                                //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+                                if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+                                    layout = &sclres_layout[popupLayoutId];
+                                }
+                                if (layout) {
+                                    //popupRect.width = utils->get_scale_x(layout->width);
+                                    //popupRect.height= utils->get_scale_y(layout->height);
+                                    if (!(sclres_manager->loaded(popupLayoutId))) {
+                                        sclres_manager->load(popupLayoutId);
+                                    }
+                                    popupRect.width = layout->width;
+                                    popupRect.height = layout->height;
+
+                                    SclWindowOpener opener;
+                                    opener.window = window;
+                                    opener.key = key_index;
+
+                                    sclwindow popup_window = windows->open_popup(
+                                        opener,
+                                        popupRect,
+                                        popup_input_mode,
+                                        popupLayoutId,
+                                        coordinate->popup_type,
+                                        sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+                                        sclres_input_mode_configure[popup_input_mode].use_dim_window,
+                                        coordinate->extract_offset_x,
+                                        coordinate->extract_offset_y,
+                                        sclres_input_mode_configure[popup_input_mode].timeout);
+
+                                    SclNotiPopupOpenedDesc opened_desc;
+                                    opened_desc.ui_event_desc = &key_event_desc;
+                                    opened_desc.input_mode = desc.input_mode;
+                                    opened_desc.window = popup_window;
+                                    handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+                                    windows->hide_window(windows->get_magnifier_window());
+                                    _play_tts_for_input_mode_name(popup_input_mode);
+                                    ret = TRUE;
+                                }
+                            }
+                        }
+                    }
+            } else if (coordinate->long_key_value) {
+                if (strlen(coordinate->long_key_value) > 0) {
+                        if (windows->is_base_window(window)) {
+                            state->set_cur_action_state(ACTION_STATE_BASE_LONGKEY);
+                        } else {
+                            state->set_cur_action_state(ACTION_STATE_POPUP_LONGKEY);
+                        }
+                        ret = TRUE;
+
+                        PSclMagnifierWndConfigure magnifier_configure = NULL;
+                        if (sclres_manager) {
+                            magnifier_configure = sclres_manager->get_magnifier_configure();
+                        }
+                        if (coordinate->use_long_key_magnifier && magnifier_configure) {
+                            CSCLUtils *utils = CSCLUtils::get_instance();
+                            SclPoint pos = {0, 0};
+
+                            const SclLayout* layout = cache->get_cur_layout(window);
+                            if (utils && layout) {
+                                sclint scnWidth, scnHeight;
+                                utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                                //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
+                                SclWindowContext *window_context = windows->get_window_context(window);
+                                if (window_context) {
+                                    pos.x = window_context->geometry.x + (coordinate->x + (coordinate->width / 2)) -
+                                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+                                    pos.y = window_context->geometry.y + coordinate->y -
+                                        magnifier_configure->height * utils->get_custom_scale_rate_y();
+                                }
+                                if (pos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                                    pos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                                }
+                                if (pos.x > scnWidth +
+                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                    magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                                    pos.x = scnWidth +
+                                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                        magnifier_configure->width * utils->get_custom_scale_rate_x();
+                                }
+                                pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                                pos.x += coordinate->magnifier_offset_x;
+                                pos.y += coordinate->magnifier_offset_y;
+                                windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+                                windows->update_window(windows->get_magnifier_window());
+                                windows->show_window(windows->get_magnifier_window(), TRUE);
+                            }
+                        }
+
+                        SclUIEventDesc key_event_desc;
+                        key_event_desc.key_type = coordinate->long_key_type;
+                        key_event_desc.key_value = coordinate->long_key_value;
+                        key_event_desc.key_event = coordinate->long_key_event;
+                        key_event_desc.key_modifier = KEY_MODIFIER_LONGKEY;
+
+                        key_event_desc.event_type = EVENT_TYPE_LONGPRESS;
+                        key_event_desc.touch_id = touch_id;
+                        key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                        key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                        key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                        key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                        handler->on_event_key_clicked(key_event_desc);
+                    //}
+                }
+            }
+        }
+        if (ret) {
+            context->set_cur_key_modifier(touch_id, KEY_MODIFIER_LONGKEY);
+            if (coordinate && button_context) {
+                if (coordinate->button_type & BUTTON_TYPE_MULTITAP) {
+                    button_context->multitap_index = 0;
+                }
+            }
+        }
+    }
+    /* Longkey processing in here */
+    return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
+                                                    scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+
+    if (context && cache && windows && handler) {
+        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+
+        SCLShiftState shift_index = context->get_shift_state();
+        if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+        if (context->get_caps_lock_mode()) {
+            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+        }
+
+        if (coordinate) {
+            switch (coordinate->button_type) {
+                case BUTTON_TYPE_NORMAL:
+                case BUTTON_TYPE_GRAB:
+                case BUTTON_TYPE_SELFISH:
+                case BUTTON_TYPE_DIRECTION:
+                case BUTTON_TYPE_RELATIVE_DIRECTION: {
+                    /* This is for enabling backspace key in search layout*/
+                    //if (coordinate->key_type != KEY_TYPE_MODECHANGE && coordinate->key_type != KEY_TYPE_COMPOSITION) {
+                    //if (coordinate->key_type != KEY_TYPE_MODECHANGE || coordinate->key_event[0][0] == MVK_BackSpace) {
+                    if (coordinate->key_type != KEY_TYPE_MODECHANGE) {
+                        sclulong repeatKeyEvent = coordinate->key_event[shift_index][0];
+
+                        /* In case of Delete key, Change from Char deletion to Word deletion
+                           when the input acceleration speed is reached to Max */
+                        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                        PSclDefaultConfigure default_configure = NULL;
+                        if (sclres_manager) {
+                            default_configure = sclres_manager->get_default_configure();
+                        }
+                        if (default_configure) {
+                            if (default_configure->use_word_deletion) {
+                                CSCLController *controller = CSCLController::get_instance();
+                                scllong interval = controller->get_repeatkey_duration() -
+                                    (controller->get_key_repeated_num() * SCL_REPEATKEY_ACCELERATION);
+                                if (repeatKeyEvent == MVK_BackSpace &&
+                                    interval <= SCL_REPEATKEY_WORD_DELETION_START_DURATION) {
+                                    repeatKeyEvent = MVK_3270_DeleteWord;
+                                }
+                            }
+                        }
+
+                        SclUIEventDesc key_event_desc;
+                        key_event_desc.key_value = coordinate->key_value[shift_index][0];
+                        key_event_desc.key_event = repeatKeyEvent;
+                        key_event_desc.key_type = coordinate->key_type;
+                        key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+
+                        key_event_desc.event_type = EVENT_TYPE_REPEAT;
+                        key_event_desc.touch_id = touch_id;
+                        key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                        key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                        key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                        key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                        handler->on_event_key_clicked(key_event_desc);
+                    }
+                }
+                break;
+                case BUTTON_TYPE_UIITEM: break;
+                case MAX_BUTTON_TYPE: break;
+                default: break;
+            }
+        }
+    }
+
+    /* Longkey processing in here */
+    return TRUE;
+}
+
+sclboolean
+CSCLControllerButton::process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+                                          scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    SclButtonContext *button_context = NULL;
+
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (cache) {
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        button_context = cache->get_cur_button_context(window, key_index);
+    }
+
+    if (button_context && coordinate && feedback && utils && context && handler && cache && events && windows) {
+        /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+        sclint thresholdX = 0;
+        sclint thresholdY = 0;
+        if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+            thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
+            thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
+        }
+
+        /* First check if this button is enabled in current active sublayout */
+        sclboolean subLayoutMatch = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                subLayoutMatch = FALSE;
+            }
+        }
+        if ( x >= coordinate->x - coordinate->add_hit_left  - thresholdX &&
+            x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX&&
+                y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
+                subLayoutMatch ) {
+            ret = TRUE;
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
+
+            sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+            scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+            SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+            const SclLayoutKeyCoordinate *pressed_coordinate =
+                cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+            if (pressed_context == NULL || pressed_coordinate == NULL) {
+                return FALSE;
+            }
+
+            if (key_index != pressed_key || window != pressed_window) {
+                /* When the focus has moved to another button, destroy all the timers */
+                events->destroy_all_timer();
+
+                CSCLController *controller = CSCLController::get_instance();
+                if (controller->check_event_transition_enabled(pressed_coordinate, coordinate)) {
+                    if (layout) {
+                        const scl16 uniqId = utils->get_unique_id();
+                        context->set_cur_pressed_event_id(touch_id, uniqId);
+                        /* Special routine for autopopup */
+                        if (coordinate->popup_type == POPUP_TYPE_AUTO_POPUP) {
+                            CSCLController *controller = CSCLController::get_instance();
+                            events->create_timer(SCL_TIMER_AUTOPOPUP, controller->get_autopopup_key_duration(), uniqId);
+                        } else {
+                            /* for long key & repeat key */
+                            CSCLController *controller = CSCLController::get_instance();
+                            events->create_timer(SCL_TIMER_LONGKEY, controller->get_longkey_duration(), uniqId);
+                        }
+
+                        context->set_cur_pressed_window(touch_id, window);
+                        context->set_cur_pressed_key(touch_id, key_index);
+
+                        CSCLController *controller = CSCLController::get_instance();
+                        sclboolean showMagnifier = controller->check_magnifier_available(window, key_index, touch_id);
+
+                        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+                        PSclMagnifierWndConfigure magnifier_configure = NULL;
+                        if (sclres_manager) {
+                            magnifier_configure = sclres_manager->get_magnifier_configure();
+                        }
+
+                        SclWindowContext *window_context = windows->get_window_context(window);
+                        if (showMagnifier && magnifier_configure && window_context) {
+                            SclPoint pos = {0, 0};
+                            /* calculates x position to be set */
+                            pos.x = window_context->geometry.x;
+                            pos.x += (coordinate->x + (coordinate->width / 2)) -
+                                (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                            /* calculates y position to be set */
+                            pos.y = window_context->geometry.y;
+                            pos.y += coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+
+                            if (pos.x < window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                                pos.x = window_context->geometry.x - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                            }
+                            if (pos.x > window_context->geometry.x + window_context->geometry.width +
+                                magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                                pos.x = window_context->geometry.x + window_context->geometry.width +
+                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                    magnifier_configure->width * utils->get_custom_scale_rate_x();
+                            }
+                            pos.x += coordinate->magnifier_offset_x;
+                            pos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                            pos.y += coordinate->magnifier_offset_y;
+                            if (windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP) == windows->get_base_window()) {
+                                windows->move_window(windows->get_magnifier_window(), pos.x, pos.y);
+                                windows->update_window(windows->get_magnifier_window());
+                            }
+                        }
+
+                        /* for feedback */
+                        feedback->button_moved(window, key_index);
+
+                        button_context->state = BUTTON_STATE_PRESSED;
+                        if (pressed_context) {
+                            /* But, if this button should be in pressed state in other multitouch id, do not initialize it */
+                            sclboolean found = FALSE;
+                            for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
+                                SclUIEventDesc desc;
+                                context->get_multi_touch_event(loop, &desc);
+                                if (desc.touch_id != touch_id) {
+                                    MultiTouchContext *multi_touch_context =
+                                        context->find_multi_touch_context(desc.touch_id);
+                                    if (multi_touch_context) {
+                                        if (multi_touch_context->cur_pressed_window == pressed_window &&
+                                            multi_touch_context->cur_pressed_key == pressed_key) {
+                                            found = TRUE;
+                                        }
+                                    }
+                                }
+                            }
+                            if (!found) {
+                                pressed_context->state = BUTTON_STATE_NORMAL;
+                            }
+                        }
+                        /* If the window doesn't get exposed before corresponding release event,
+                        * the inverted state of a button will never be drawn onto screen.
+                        * To prevent such a case, we draw the inverted state of button forcefully and directly,
+                        * without waiting for expose event */
+                        /* Redrawing pressed button does not work properly, commented out */
+                        /*
+                        CSCLGraphics *grps = CSCLGraphics::get_instance();
+                        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+                        scldrawctx draw_ctx;
+                        if (pressed_window != SCLWINDOW_INVALID && pressed_key != NOT_USED) {
+                            draw_ctx = grps->begin_paint(pressed_window, TRUE);
+                            builder->draw_button(pressed_window, draw_ctx, pressed_key, FALSE);
+                            grps->end_paint(pressed_window, draw_ctx);
+                        }
+                        draw_ctx = grps->begin_paint(window, TRUE);
+                        builder->draw_button(window, draw_ctx, key_index, TRUE);
+                        grps->end_paint(window, draw_ctx);
+                        */
+
+                        switch (coordinate->button_type) {
+                        case BUTTON_TYPE_DRAG: {
+                            SclUIEventDesc key_event_desc;
+                            key_event_desc.key_value = coordinate->key_value[shift_index][0];
+                            key_event_desc.key_event = coordinate->key_event[shift_index][0];
+                            key_event_desc.key_type = coordinate->key_type;
+                            key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+
+                            key_event_desc.event_type = EVENT_TYPE_MOVE;
+                            key_event_desc.touch_id = touch_id;
+                            key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                            key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                            key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                            if (sclres_manager) {
+                                magnifier_configure = sclres_manager->get_magnifier_configure();
+                            }
+                            sclboolean processed = handler->on_event_drag_state_changed(key_event_desc);
+                            if (processed && context->get_magnifier_enabled() && magnifier_configure) {
+                                SclPoint zoomwinpos = {0, 0};
+                                /* calculates x position to be set */
+                                zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
+                                    (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                                /* calculates y position to be set */
+                                sclint scnWidth, scnHeight;
+                                utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                                zoomwinpos.y = coordinate->y -
+                                    magnifier_configure->height * utils->get_custom_scale_rate_y();
+                                SclWindowContext *window_context = windows->get_window_context(window);
+                                if (window_context) {
+                                    zoomwinpos.x += window_context->geometry.x;
+                                    zoomwinpos.y += window_context->geometry.y;
+                                }
+                                if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                                    zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                                }
+                                if (zoomwinpos.x > scnWidth +
+                                    magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                    magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                                        zoomwinpos.x = scnWidth +
+                                            magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                                            magnifier_configure->width * utils->get_custom_scale_rate_x();
+                                }
+                                zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+                                zoomwinpos.x += coordinate->magnifier_offset_x;
+                                zoomwinpos.y += coordinate->magnifier_offset_y;
+                                windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
+                                windows->show_window(windows->get_magnifier_window(), 0);
+                            }
+
+                            handler->on_event_key_clicked(key_event_desc);
+                            if (!(windows->is_base_window(window))) {
+                                /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
+                                //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+                                SclWindowContext *window_context = windows->get_window_context(window);
+                                if (window_context) {
+                                    if (window_context->timeout > 0) {
+                                        events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+                                        events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
+                                    }
+                                }
+                            }
+                        }
+                        break;
+                        case BUTTON_TYPE_NORMAL: break;
+                        case BUTTON_TYPE_GRAB: break;
+                        case BUTTON_TYPE_SELFISH: break;
+                        case BUTTON_TYPE_MULTITAP: break;
+                        case BUTTON_TYPE_ROTATION: break;
+                        case BUTTON_TYPE_DIRECTION: break;
+                        case BUTTON_TYPE_RELATIVE_DIRECTION: break;
+                        case BUTTON_TYPE_UIITEM: break;
+                        case MAX_BUTTON_TYPE: break;
+                        default:
+                            break;
+                        }
+
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+                        CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+                        if (builder) {
+                            if (button_context) {
+                                builder->draw_button(window, NULL, key_index, button_context->state);
+                            }
+                            if (pressedContext) {
+                                builder->draw_button(pressed_window, NULL, pressed_key, pressedContext->state, TRUE);
+                            }
+                        }
+#else
+                        windows->update_window(window,
+                                coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                        if (pressed_coordinate) {
+                            windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+                                    pressed_coordinate->width, pressed_coordinate->height);
+                        }
+#endif
+                    }
+
+                    //utils->log("Now Moving : %d %d\n", pos.x, pos.y);
+                } else {
+                    /* If the focus went out from our SELFISH button */
+                    if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH) {
+                        pressed_context->state = BUTTON_STATE_NORMAL;
+                        windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+                            pressed_coordinate->width, pressed_coordinate->height);
+                        /* And if this SELFISH button was the last button pressed */
+                        if (touch_id == context->get_last_touch_device_id()) {
+                            windows->hide_window(windows->get_magnifier_window());
+                        }
+                    }
+                }
+            } else {
+                /* If the focus came back into our SELFISH button */
+                if (pressed_coordinate->button_type == BUTTON_TYPE_SELFISH && pressed_context->state != BUTTON_STATE_PRESSED) {
+                    pressed_context->state = BUTTON_STATE_PRESSED;
+                    windows->update_window(pressed_window, pressed_coordinate->x, pressed_coordinate->y,
+                        pressed_coordinate->width, pressed_coordinate->height);
+                    /* And if this SELFISH button was the last button pressed */
+                    if (touch_id == context->get_last_touch_device_id()) {
+                        CSCLController *controller = CSCLController::get_instance();
+                        sclboolean showMagnifier = controller->check_magnifier_available(pressed_window, pressed_key, touch_id);
+
+                        if (showMagnifier) {
+                            windows->show_window(windows->get_magnifier_window());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    SclButtonContext *button_context = NULL;
+
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+    if (cache) {
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+        button_context = cache->get_cur_button_context(window, key_index);
+    }
+
+    if (button_context && coordinate && feedback && utils && context && cache && events && windows) {
+       /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+        sclboolean subLayoutMatch = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                subLayoutMatch = FALSE;
+            }
+        }
+        if ( x >= coordinate->x - coordinate->add_hit_left &&
+            x < coordinate->x + coordinate->width + coordinate->add_hit_right &&
+                y >= coordinate->y - coordinate->add_hit_top &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom &&
+                subLayoutMatch ) {
+            ret = TRUE;
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            const SclLayout* layout = cache->get_cur_layout(windows->get_base_window());
+
+            sclwindow highlighted_window = context->get_cur_highlighted_window();
+            scl8 highlighted_key = context->get_cur_highlighted_key();
+            SclButtonContext *cur_context = cache->get_cur_button_context(window, key_index);
+
+            if (cur_context == NULL) {
+                return FALSE;
+            }
+            if (key_index != highlighted_key || window != highlighted_window) {
+                SECURE_LOGD("%d != %d || %p != %p", key_index, highlighted_key, window, highlighted_window);
+                if (layout) {
+                    if (coordinate->key_type != KEY_TYPE_NONE) {
+                        if (context->get_tts_enabled()) {
+                            const sclchar *targetstr = coordinate->hint_string[shift_index][button_context->multitap_index];
+                            if (targetstr == NULL) {
+                                targetstr = coordinate->label[shift_index][0];
+                            }
+                            if (targetstr == NULL) {
+                                targetstr = coordinate->key_value[shift_index][button_context->multitap_index];
+                            }
+                            /*if(state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+                                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ) {
+                                    targetstr = coordinate->long_key_value;
+                            }*/
+                            const sclchar *sayit = cache->find_substituted_string(targetstr);
+                            utils->play_tts(sayit);
+                        }
+                    }
+                }
+
+                context->set_cur_highlighted_window(window);
+                context->set_cur_highlighted_key(key_index);
+            }
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLControllerButton::process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+                                             scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+
+    sclboolean ret = FALSE;
+    sclboolean redraw = FALSE;
+    sclboolean fire_event = FALSE;
+    SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
+
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLFeedback *feedback = CSCLFeedback::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+    if (!sclres_manager) return FALSE;
+
+    PSclLayout sclres_layout = sclres_manager->get_layout_table();
+    PSclInputModeConfigure sclres_input_mode_configure = sclres_manager->get_input_mode_configure_table();
+    if (!sclres_layout || !sclres_input_mode_configure) return FALSE;
+
+    SclButtonContext *button_context = NULL;
+    const SclLayoutKeyCoordinate *coordinate = NULL;
+
+    if (cache) {
+        button_context = cache->get_cur_button_context(window, key_index);
+        coordinate = cache->get_cur_layout_key_coordinate(window, key_index);
+    }
+
+    const SclLayoutKeyCoordinate *targetCoordinate = NULL;
+
+    if (utils && feedback && windows && context && state && handler && cache && button_context && coordinate) {
+        scl8 savedInputMode = context->get_input_mode();
+
+        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+
+        if (actual_event) {
+             if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                 /* When calling mouse_release, the seq order of current multitouch events will be changed,
+                    so we put all the multitouch events into a vector and use them afterwards for releasing */
+                 sclboolean finished = FALSE;
+                 sclint loop = 0;
+                 sclint multi_touch_context_num = context->get_multi_touch_context_num();
+                 std::vector<SclUIEventDesc> multi_touch_events;
+                 for (loop = 0;loop < multi_touch_context_num;loop++) {
+                     SclUIEventDesc desc;
+                     context->get_multi_touch_event(loop, &desc);
+                     multi_touch_events.push_back(desc);
+                 }
+                 for (loop = 0;loop < multi_touch_context_num && !finished;loop++) {
+                     SclUIEventDesc desc = multi_touch_events[loop];
+                     if (desc.touch_id != touch_id) {
+                         sclwindow cur_pressed_window = context->get_cur_pressed_window(desc.touch_id);
+                         scl8 cur_pressed_key = context->get_cur_pressed_key(desc.touch_id);
+                         const SclLayoutKeyCoordinate *cur_pressed_coordinate =
+                             cache->get_cur_layout_key_coordinate(cur_pressed_window, cur_pressed_key);
+                         if (cur_pressed_coordinate) {
+                             if (cur_pressed_coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                                 CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+                                 controller_mouse->mouse_release(context->get_cur_moving_window(desc.touch_id),
+                                     context->get_cur_moving_point(desc.touch_id).x,
+                                     context->get_cur_moving_point(desc.touch_id).y,
+                                     desc.touch_id, FALSE);
+                             }
+                         }
+                     } else {
+                         finished = TRUE;
+                     }
+                 }
+             }
+         }
+
+        /* If this key is the key previously pressed, add threshold value for avoiding unintended moving */
+        sclint thresholdX = 0;
+        sclint thresholdY = 0;
+        if (context) {
+            if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+                thresholdX = utils->get_scaled_x(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_X);
+                thresholdY = utils->get_scaled_y(SCL_MOUSE_BUTTON_CHANGE_THRESHOLD_Y);
+            }
+        }
+
+        /* Check if the pressed button's type is directional button */
+        if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+            if (context) {
+                if (context->get_cur_pressed_window(touch_id) == window && context->get_cur_pressed_key(touch_id) == key_index) {
+                    ret = TRUE;
+                    sclboolean check_farthest = FALSE;
+
+                    sclint startx = x;
+                    sclint starty = y;
+
+                    /* If the buttontype is RELATIVE_DIRECTION, get the distance from last move point */
+                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        startx = context->get_prev_moving_point(touch_id).x;
+                        starty = context->get_prev_moving_point(touch_id).y;
+                    } else {
+                        startx = context->get_cur_pressed_point(touch_id).x;
+                        starty = context->get_cur_pressed_point(touch_id).y;
+                    }
+
+                    sclint deltax = x - startx;
+                    sclint deltay = y - starty;
+
+                    sclfloat dist = utils->get_distance(x, y, startx, starty);
+                    sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
+                    if (coordinate->is_side_button) {
+                        direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
+                    };
+                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
+                    }
+                    if (context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN &&
+                        coordinate->button_type != BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
+                            coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
+                            coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
+                                deltax = context->get_farthest_move_point(touch_id).x - context->get_cur_pressed_point(touch_id).x;
+                                deltay = context->get_farthest_move_point(touch_id).y - context->get_cur_pressed_point(touch_id).y;
+                                dist = utils->get_distance(context->get_farthest_move_point(touch_id), context->get_cur_pressed_point(touch_id));
+                                check_farthest = TRUE;
+                        }
+                    }
+                    if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        key_modifier = context->get_cur_key_modifier(touch_id);
+                    } else if (dist > direction_recog_dist) {
+                        CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+                        key_modifier = controller_mouse->get_drag_key_modifier(deltax, deltay, dist, check_farthest, touch_id, coordinate->extra_option);
+                    }
+                }
+            }
+        }
+
+        /* First check if this button is enabled in current active sublayout */
+        sclboolean subLayoutMatch = TRUE;
+        if (coordinate->sub_layout && context->get_cur_sublayout()) {
+            if (strncmp(coordinate->sub_layout, context->get_cur_sublayout(), MAX_SIZE_OF_SUBLAYOUT_STRING) != 0) {
+                subLayoutMatch = FALSE;
+            }
+        }
+        /* Check if the event occured inside this button's rectangle */
+        if ( x >= coordinate->x - coordinate->add_hit_left  - thresholdX &&
+                x < coordinate->x + coordinate->width + coordinate->add_hit_right + thresholdX &&
+                y >= coordinate->y - coordinate->add_hit_top - thresholdY &&
+                y < coordinate->y + coordinate->height + coordinate->add_hit_bottom + thresholdY &&
+                subLayoutMatch ) {
+            ret = TRUE;
+        }
+
+        if (ret) {
+            /* for feedback */
+            feedback->button_released(window, key_index);
+
+            /* If this button's index is the same as the one initially pressed */
+            if (pressed_window == window && pressed_key == key_index) {
+                fire_event = TRUE;
+                targetCoordinate = coordinate;
+            } else {
+                const SclLayoutKeyCoordinate *pressed_coordinate =
+                    cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+                if (pressed_coordinate) {
+                    CSCLController *controller = CSCLController::get_instance();
+                    if (controller->check_event_transition_enabled(pressed_coordinate, coordinate)) {
+                        fire_event = TRUE;
+                        targetCoordinate = pressed_coordinate;
+                    } else {
+                        ret = FALSE;
+                    }
+                }
+            }
+        }
+
+        /* In case of mode change buttons, event should be fired only when it was pressed lastly */
+        if (fire_event) {
+            if (coordinate->key_type == KEY_TYPE_MODECHANGE) {
+                if (touch_id != context->get_last_touch_device_id()) {
+                    fire_event = FALSE;
+                }
+            }
+        }
+
+        /* If this key's modifier is LONGKEY, this means the event is already fired so skip this one */
+        if (context->get_cur_key_modifier(touch_id) == KEY_MODIFIER_LONGKEY) {
+            fire_event = FALSE;
+        }
+
+        /* Don't fire any events if we're in longkey state */
+        if (state->get_cur_action_state() != ACTION_STATE_BASE_LONGKEY &&
+                state->get_cur_action_state() != ACTION_STATE_BASE_REPEATKEY &&
+                state->get_cur_action_state() != ACTION_STATE_POPUP_LONGKEY &&
+                state->get_cur_action_state() != ACTION_STATE_POPUP_REPEATKEY) {
+            if (ret) {
+                SCLShiftState shift_index = context->get_shift_state();
+                if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                if (context->get_caps_lock_mode()) {
+                    shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                }
+
+                SclUIEventDesc key_event_desc;
+                if (targetCoordinate) {
+                    key_event_desc.key_type = targetCoordinate->key_type;
+
+                    key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
+                    key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
+                }
+                key_event_desc.key_modifier = key_modifier;
+
+                key_event_desc.event_type = EVENT_TYPE_RELEASE;
+                key_event_desc.touch_id = touch_id;
+                key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                if (handler->on_event_drag_state_changed(key_event_desc) != SCL_EVENT_PASS_ON) {
+                    fire_event = FALSE;
+                }
+            }
+            if (fire_event) {
+                if (targetCoordinate) {
+                    SCLShiftState shift_index = context->get_shift_state();
+                    if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                    if (context->get_caps_lock_mode()) {
+                        shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                    }
+
+                    SclUIEventDesc key_event_desc;
+                    key_event_desc.key_type = targetCoordinate->key_type;
+
+                    key_event_desc.event_type = EVENT_TYPE_RELEASE;
+                    key_event_desc.touch_id = touch_id;
+                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                    switch (targetCoordinate->button_type) {
+                    case BUTTON_TYPE_NORMAL:
+                    case BUTTON_TYPE_GRAB :
+                    case BUTTON_TYPE_SELFISH:
+                    case BUTTON_TYPE_DIRECTION :
+                    case BUTTON_TYPE_RELATIVE_DIRECTION: {
+                        SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+                        if (pressed_context) {
+                            if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
+                                key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
+                                key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
+                                key_event_desc.key_modifier = key_modifier;
+                                handler->on_event_key_clicked(key_event_desc);
+                            }
+                        }
+                    }
+                    break;
+                    case BUTTON_TYPE_MULTITAP:
+                    case BUTTON_TYPE_ROTATION: {
+                        if (targetCoordinate->button_type == BUTTON_TYPE_MULTITAP) {
+                            if (window == context->get_last_event_fired_window() &&
+                                key_index == context->get_last_event_fired_key()) {
+                                key_modifier = KEY_MODIFIER_MULTITAP_REPEAT;
+                            } else {
+                                key_modifier = KEY_MODIFIER_MULTITAP_START;
+                            }
+                        } else {
+                            key_modifier = KEY_MODIFIER_NONE;
+                        }
+                        if (button_context->multitap_index < MAX_SIZE_OF_MULTITAP_CHAR) {
+                            key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
+                            key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
+                            key_event_desc.key_modifier = key_modifier;
+                            if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
+                                CSCLEvents *events = CSCLEvents::get_instance();
+                                events->destroy_timer(SCL_TIMER_MULTITAP);
+                                CSCLController *controller = CSCLController::get_instance();
+                                events->create_timer(SCL_TIMER_MULTITAP, controller->get_multitap_delay_duration(), 0);
+                            }
+                        }
+                        /* Check if the multikey index is in valid range, and increase by one */
+                        if (button_context->multitap_index >= MAX_SIZE_OF_MULTITAP_CHAR - 1) {
+                            button_context->multitap_index = 0;
+                        } else {
+                            sclbyte orgindex = button_context->multitap_index;
+                            button_context->multitap_index = 0;
+                            if (targetCoordinate->key_value[shift_index][orgindex + 1]) {
+                                if (strlen(targetCoordinate->key_value[shift_index][orgindex + 1]) > 0) {
+                                    button_context->multitap_index = orgindex + 1;
+                                }
+                            }
+                        }
+                    }
+                    break;
+                    case BUTTON_TYPE_DRAG : {
+                    }
+                    break;
+                    case BUTTON_TYPE_TOGGLE : {
+                        SclButtonContext *pressed_context = cache->get_cur_button_context(pressed_window, pressed_key);
+                        if (pressed_context) {
+                            if (!(targetCoordinate->use_repeat_key) && pressed_context->state == BUTTON_STATE_PRESSED) {
+                                key_event_desc.key_value = targetCoordinate->key_value[shift_index][0];
+                                key_event_desc.key_event = targetCoordinate->key_event[shift_index][0];
+                                if (pressed_context->toggled) {
+                                    key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+                                } else {
+                                    key_event_desc.key_modifier = KEY_MODIFIER_TOGGLED;
+                                }
+                                if (SCL_EVENT_PASS_ON == handler->on_event_key_clicked(key_event_desc)) {
+                                    pressed_context->toggled = !(pressed_context->toggled);
+                                }
+                            }
+                        }
+                    }
+                    case BUTTON_TYPE_UIITEM: break;
+                    case MAX_BUTTON_TYPE: break;
+                    default: break;
+                    }
+                    switch (coordinate->popup_type) {
+                    case POPUP_TYPE_BTN_RELEASE_POPUP:
+                    case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE: {
+                        SCLDragState dragstate = context->get_cur_drag_state(touch_id);
+                        sclint popup_input_mode = NOT_USED;
+
+                        SclNotiPopupOpeningDesc desc;
+                        desc.ui_event_desc = &key_event_desc;
+
+                        if (scl_check_arrindex(dragstate, SCL_DRAG_STATE_MAX)) {
+                            desc.input_mode = coordinate->popup_input_mode[dragstate];
+                            popup_input_mode = sclres_manager->get_inputmode_id(coordinate->popup_input_mode[dragstate]);
+                            /* FIXME */
+                            //if (!scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP)) {
+                            if (!scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE)) {
+                                desc.input_mode = coordinate->popup_input_mode[SCL_DRAG_STATE_NONE];
+                            }
+                        }
+                        if (SCL_EVENT_PASS_ON == handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENING, &desc)) {
+                            popup_input_mode = sclres_manager->get_inputmode_id(desc.input_mode);
+                            SCLDisplayMode display_mode = context->get_display_mode();
+                            /* FIXME */
+                            //if (scl_check_arrindex(popup_input_mode, MAX_INPUT_MODE_POPUP) &&
+                            if (scl_check_arrindex(popup_input_mode, MAX_SCL_INPUT_MODE) &&
+                                scl_check_arrindex(display_mode, DISPLAYMODE_MAX)) {
+                                sclshort popupLayoutId =
+                                    sclres_manager->get_layout_id(sclres_input_mode_configure[popup_input_mode].layouts[display_mode]);
+                                if (popupLayoutId == NOT_USED) {
+                                    // deal with NOT_USED
+                                    LOGD("popupLayoutID is not used.");
+                                }
+                                SclLayout *layout = NULL;
+                                /* FIXME */
+                                //if (scl_check_arrindex(popupLayoutId, MAX_LAYOUT)) {
+                                if (scl_check_arrindex(popupLayoutId, MAX_SCL_LAYOUT)) {
+                                    layout = &sclres_layout[popupLayoutId];
+                                }
+                                if (layout) {
+                                    SclRectangle popupRect;
+                                    SclRectangle baseWndRect;
+                                    windows->get_window_rect(windows->get_base_window(), &baseWndRect);
+                                    popupRect.x = coordinate->x + coordinate->popup_relative_x + baseWndRect.x;
+                                    popupRect.y = coordinate->y + coordinate->popup_relative_y + baseWndRect.y;
+
+                                    //popupRect.width = utils->get_scale_x(layout->width);
+                                    //popupRect.height= utils->get_scale_y(layout->height);
+                                    if (!(sclres_manager->loaded(popupLayoutId))) {
+                                        sclres_manager->load(popupLayoutId);
+                                    }
+                                    popupRect.width = layout->width;
+                                    popupRect.height = layout->height;
+
+                                    /* Let's make sure this popup window does not go beyond the screen area */
+                                    sclint scr_w, scr_h;
+                                    utils->get_screen_resolution(&scr_w, &scr_h);
+
+                                    if (popupRect.x + popupRect.width > scr_w) {
+                                        popupRect.x = scr_w - popupRect.width;
+                                    }
+                                    if (popupRect.y + popupRect.height > scr_h) {
+                                        popupRect.y = scr_h - popupRect.height;
+                                    }
+
+                                    SclWindowOpener opener;
+                                    opener.window = window;
+                                    opener.key = key_index;
+
+                                    sclwindow popup_window = windows->open_popup(
+                                        opener,
+                                        popupRect,
+                                        popup_input_mode,
+                                        popupLayoutId,
+                                        coordinate->popup_type,
+                                        sclres_input_mode_configure[popup_input_mode].use_virtual_window,
+                                        sclres_input_mode_configure[popup_input_mode].use_dim_window,
+                                        coordinate->extract_offset_x,
+                                        coordinate->extract_offset_y,
+                                        sclres_input_mode_configure[popup_input_mode].timeout);
+
+                                    SclNotiPopupOpenedDesc opened_desc;
+                                    opened_desc.ui_event_desc = &key_event_desc;
+                                    opened_desc.input_mode = desc.input_mode;
+                                    opened_desc.window = popup_window;
+                                    handler->on_event_notification(SCL_UINOTITYPE_POPUP_OPENED, &opened_desc);
+
+                                    windows->hide_window(windows->get_magnifier_window());
+                                    _play_tts_for_input_mode_name(popup_input_mode);
+                                }
+                            }
+                        }
+                    }
+                    break;
+                    case POPUP_TYPE_AUTO_POPUP:
+                    case POPUP_TYPE_BTN_PRESS_POPUP_DRAG:
+                    case POPUP_TYPE_NONE:
+                        /* Nothing to do in here */
+                        break;
+                    case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE: break;
+                    case POPUP_TYPE_BTN_LONGPRESS_POPUP: break;
+                    case MAX_POPUP_TYPE: break;
+                    default: break;
+                    }
+                }
+
+                context->set_last_event_fired_window(window);
+                context->set_last_event_fired_key(key_index);
+            }
+        } else {
+            if (targetCoordinate) {
+                SCLShiftState shift_index = context->get_shift_state();
+                if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+                if (context->get_caps_lock_mode()) {
+                    shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+                }
+
+                SclUIEventDesc key_event_desc;
+                key_event_desc.key_type = targetCoordinate->key_type;
+
+                key_event_desc.key_value = targetCoordinate->key_value[shift_index][button_context->multitap_index];
+                key_event_desc.key_event = targetCoordinate->key_event[shift_index][button_context->multitap_index];
+                key_event_desc.key_modifier = key_modifier;
+
+                key_event_desc.event_type = EVENT_TYPE_RELEASE;
+                key_event_desc.touch_id = touch_id;
+                key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                handler->on_event_drag_state_changed(key_event_desc);
+            }
+        }
+
+        /* If this button was pressed, initialize the button context regardless of event  */
+        if (button_context->state == BUTTON_STATE_PRESSED) {
+            /* But, if this button should be in pressed state in other multitouch id, do not initialize */
+            sclboolean found = FALSE;
+            for (sclint loop = 0;loop < context->get_multi_touch_context_num() && !found;loop++) {
+                SclUIEventDesc desc;
+                context->get_multi_touch_event(loop, &desc);
+                if (desc.touch_id != touch_id) {
+                    MultiTouchContext *multi_touch_context = context->find_multi_touch_context(desc.touch_id);
+                    if (multi_touch_context) {
+                        if (multi_touch_context->cur_pressed_window == window &&
+                            multi_touch_context->cur_pressed_key == key_index) {
+                            found = TRUE;
+                        }
+                    }
+                }
+            }
+            if (!found) {
+                button_context->state = BUTTON_STATE_NORMAL;
+                redraw = TRUE;
+            }
+        }
+
+        /* If this button needs to be redrawn */
+        if (redraw) {
+#ifdef DIRECTLY_DRAW_ON_EVENTS
+            CSCLUIBuilder *builder = CSCLUIBuilder::get_instance();
+            if (builder) {
+                builder->draw_button(window, NULL, key_index, button_context->state, TRUE);
+            }
+#else
+            if (savedInputMode == context->get_input_mode()) {
+                windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+            }
+
+#endif
+        }
+    }
+
+    return ret;
+}
+
diff --git a/scl/sclcontroller_button.h b/scl/sclcontroller_button.h
new file mode 100644 (file)
index 0000000..d878c1c
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sclgwes.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+
+#ifndef __SCL_CONTROLLER_BUTTON_H__
+#define __SCL_CONTROLLER_BUTTON_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+
+class CSCLControllerButton
+{
+private:
+    CSCLControllerButton() {}
+public:
+    virtual ~CSCLControllerButton() {}
+
+    static CSCLControllerButton* get_instance();
+
+public:
+    sclboolean process_button_pressed_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_long_pressed_event(sclwindow window, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_repeat_pressed_event(sclwindow window, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_move_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+    sclboolean process_button_over_event(sclwindow window, sclint x, sclint y, sclbyte key_index);
+    sclboolean process_button_release_event(sclwindow window, sclint x, sclint y, sclbyte key_index,
+        scltouchdevice touch_id, sclboolean actual_event = TRUE);
+
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_CONTROLLER_BUTTON_H__
diff --git a/scl/sclcontroller_mouse.cpp b/scl/sclcontroller_mouse.cpp
new file mode 100644 (file)
index 0000000..002a152
--- /dev/null
@@ -0,0 +1,1479 @@
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <time.h>
+#include <math.h>
+#include <assert.h>
+#include <vector>
+
+#include "sclcontroller_mouse.h"
+#include "sclcontroller.h"
+#include "sclcontroller_button.h"
+#include "scldebug.h"
+#include "sclresourcecache.h"
+#include "sclactionstate.h"
+#include "scluibuilder.h"
+#include "sclkeydefines.h"
+#include "sclfeedback.h"
+#include "sclerroradjustment.h"
+#include "sclimageproxy.h"
+#include "sclres_manager.h"
+#include "scleventhandler.h"
+#include "sclanimator.h"
+#include "sclkeyfocushandler.h"
+#include <dlog.h>
+
+//#define DIRECTLY_DRAW_ON_EVENTS
+
+using namespace scl;
+
+CSCLControllerMouse*
+CSCLControllerMouse::get_instance()
+{
+    static CSCLControllerMouse instance;
+    return &instance;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    CSCLController *controller = CSCLController::get_instance();
+    if (controller->get_input_events_disabled()) return FALSE;
+
+    //utils->log("Controller::mouse_press : %d %d\n", x, y);
+
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+
+    sclint button_index = NOT_USED;
+    SclWindowContext *window_context = NULL;
+    if (windows && cache) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+        window_context = windows->get_window_context(window);
+        /* If the dim window is virtual and currently active, let's just skip this event */
+        if (windows->is_base_window(window)) {
+            SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+            if (dim_window_context) {
+                LOGD("dim window is_virtual:%d, hidden:%d", dim_window_context->is_virtual, dim_window_context->hidden);
+                if (/*dim_window_context->is_virtual &&*/ !(dim_window_context->hidden)) {
+                    window = windows->get_dim_window();
+                    window_context = dim_window_context;
+                }
+            }
+        }
+    }
+
+    if (cache && state && windows && context && window_context) {
+        SCLDisplayMode display_mode = context->get_display_mode();
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        PSclDefaultConfigure default_configure = NULL;
+        if (sclres_manager) {
+            default_configure = sclres_manager->get_default_configure();
+        }
+        if (default_configure) {
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+        }
+
+        sclboolean isSubEvent = FALSE;
+        if (context->get_multi_touch_context_num() > 0) {
+            SclUIEventDesc desc;
+            context->get_multi_touch_event(0, &desc);
+            sclwindow pressed_window = context->get_cur_pressed_window(desc.touch_id);
+            scl8 pressed_key = context->get_cur_pressed_key(desc.touch_id);
+            SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+            if (coordinate) {
+                if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_GRAB_SUB_EVENTS) {
+                    isSubEvent = TRUE;
+                    if (utils)
+                        utils->play_vibration(DEFAULT_VIBRATION_STYLE, DEFAULT_VIBRATION_DURATION);
+                }
+            }
+        }
+        context->create_multi_touch_context(touch_id, isSubEvent);
+        context->set_cur_pressed_window(touch_id, window);
+        context->set_cur_pressed_point(touch_id, x, y);
+        context->set_cur_pressed_time(touch_id);
+        context->set_cur_moving_window(touch_id, window);
+        context->set_cur_moving_point(touch_id, x, y);
+        context->set_last_touch_device_id(touch_id);
+        context->set_cur_drag_state(touch_id, SCL_DRAG_STATE_NONE);
+        context->set_cur_key_modifier(touch_id, KEY_MODIFIER_NONE);
+        for (sclint labelidx = 0;labelidx < MAX_SIZE_OF_LABEL_FOR_ONE;labelidx++) {
+            context->set_custom_magnifier_label(touch_id, labelidx, NULL);
+        }
+
+        /* If there is postponed update of button, update it now */
+        CSCLEvents *events = CSCLEvents::get_instance();
+        sclwindow last_win = context->get_last_pressed_window();
+        scl8 last_key = context->get_last_pressed_key();
+        if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+            const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
+            if (coords) {
+                windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
+            }
+        }
+        context->set_prev_pressed_window(touch_id, SCLWINDOW_INVALID);
+        context->set_prev_pressed_key(touch_id, NOT_USED);
+        context->set_prev_drag_state(touch_id, SCL_DRAG_STATE_NONE);
+        context->set_prev_moving_point(touch_id, x, y);
+
+        /* Destroy key related timers */
+        events->destroy_timer(SCL_TIMER_BUTTON_DELAY);
+        events->destroy_timer(SCL_TIMER_AUTOPOPUP);
+        events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
+        events->destroy_timer(SCL_TIMER_LONGKEY);
+        events->destroy_timer(SCL_TIMER_REPEATKEY);
+        events->destroy_timer(SCL_TIMER_MULTITAP);
+
+        /* Do what has to be done when mouse gets pressed */
+        CSCLController *controller = CSCLController::get_instance();
+        controller->handle_engine_signal(SCL_SIG_MOUSE_PRESS, window);
+
+        /* Adjust event x and y positions as relative position to the virtual window */
+        if (window_context) {
+            /*if (window_context->isVirtual) {
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    x -= (window_context->x - base_window_context->x);
+                    y -= (window_context->y - base_window_context->y);
+                }
+            }*/
+        }
+
+        if (!isSubEvent) {
+            sclboolean process_finished = FALSE;
+            do {
+                /* Iterate all the buttons and inform the event */
+                sclboolean ended = FALSE;
+                for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                    SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+                    const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                    if (button_context && coordinate) {
+                        if (!(button_context->used)) {
+                            ended = TRUE;
+                        } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                    coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                            CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                            if (controller_button->process_button_pressed_event(window, x, y, loop, touch_id, actual_event)) {
+                                if (windows->is_base_window(window)) {
+                                    state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
+                                } else {
+                                    state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
+                                }
+                                button_index = loop;
+                                ret = TRUE;
+                            }
+                        }
+                    }
+                }
+
+                /* For covering a missing area about 1 pixel */
+                if (!ret) {
+                    for (int loop = 0;loop < MAX_KEY;loop++) {
+                        SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+                        const SclLayoutKeyCoordinate* coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                        if (button_context && coordinate) {
+                            if (!(button_context->used)) {
+                                break;
+                            } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                        coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                                if (controller_button->process_button_pressed_event(window, x+1, y+1, loop, touch_id, actual_event)) {
+                                    if (windows->is_base_window(window)) {
+                                        state->set_cur_action_state(ACTION_STATE_BASE_PRESS);
+                                    } else {
+                                        state->set_cur_action_state(ACTION_STATE_POPUP_PRESS);
+                                    }
+                                    button_index = loop;
+                                    break;
+                                }
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                }
+
+                if (windows->is_base_window(window)) {
+                    process_finished = TRUE;
+                } else if (button_index != NOT_USED) {
+                    process_finished = TRUE;
+                } else {
+                    const SclLayout *layout = cache->get_cur_layout(window);
+                    if (layout) {
+                        if (layout->use_sw_background && layout->bg_color.a == 0) {
+                            /* If we could not find appropriate button in this popup window and the popup is transparent */
+                            SclWindowContext *base_window_context =
+                                windows->get_window_context(windows->get_base_window());
+                            if (base_window_context) {
+                                x = (window_context->geometry.x + x - base_window_context->geometry.x);
+                                y = (window_context->geometry.y + y - base_window_context->geometry.y);
+                            }
+                            window = windows->get_base_window();
+                        } else {
+                            process_finished = TRUE;
+                        }
+                    } else {
+                        process_finished = TRUE;
+                    }
+                }
+            } while (!process_finished);
+        }
+
+        sclwindow skip_window = window;
+        if (ret && button_index != NOT_USED) {
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
+            if (coordinate) {
+                sclboolean dont_close_popup = FALSE;
+                if (coordinate->dont_close_popup) {
+                    dont_close_popup = TRUE;
+                }
+                /* If the button's popup type is drag type, the opened popup could be the one opened by this press event */
+                if (coordinate->popup_type == POPUP_TYPE_BTN_PRESS_POPUP_DRAG) {
+                    /* Check the opened popup was opened by this button */
+                    sclwindow popupwin = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                    SclWindowContext *popup_window_context = windows->get_window_context(popupwin);
+                    if (popup_window_context) {
+                        SclWindowOpener opener = popup_window_context->opener;
+                        if (opener.window == window && opener.key == button_index) {
+                            dont_close_popup = TRUE;
+                        }
+                    }
+                }
+                if (dont_close_popup) {
+                    skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                }
+            }
+        } else {
+            SclUIEventDesc key_event_desc;
+            key_event_desc.event_type = EVENT_TYPE_PRESS;
+
+            SclPoint curpoint = {x, y};
+            key_event_desc.touch_id = touch_id;
+            key_event_desc.mouse_pressed_point = curpoint;
+            key_event_desc.mouse_current_point = curpoint;
+            key_event_desc.mouse_farthest_point = curpoint;
+
+            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+            CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+            if (handler) {
+                handler->on_event_drag_state_changed(key_event_desc);
+            }
+        }
+        windows->close_all_popups(skip_window);
+
+        /* When press event occured in popup window, reset POPUP_TIMEOUT timer */
+        if (!(windows->is_base_window(window))) {
+            if (window_context->timeout > 0) {
+                events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+                events->create_timer(SCL_TIMER_POPUP_TIMEOUT, window_context->timeout, 0, TRUE);
+            }
+        } else if (skip_window != window) { /* Or the pressed button has dont_close_popup property, reset POPUP_TIMEOUT timer */
+            //SclWindowContext *skip_window_context = windows->get_window_context(skip_window, FALSE);
+            SclWindowContext *skip_window_context = windows->get_window_context(skip_window);
+            if (skip_window_context) {
+                if (skip_window_context->timeout > 0) {
+                    events->destroy_timer(SCL_TIMER_POPUP_TIMEOUT);
+                    events->create_timer(SCL_TIMER_POPUP_TIMEOUT, skip_window_context->timeout, 0, TRUE);
+                }
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    //if (m_input_events_disabled) return FALSE;
+
+    //utils->log("Controller::mouse_release : %d %d\n", x, y);
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLController *controller = CSCLController::get_instance();
+
+    sclint button_index = NOT_USED;
+
+    if (cache && state && windows && context && utils && handler && events &&
+        context->find_multi_touch_context(touch_id)) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+
+        sclwindow skip_window = SCLWINDOW_INVALID;
+        SCLDisplayMode display_mode = context->get_display_mode();
+
+        SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+        PSclDefaultConfigure default_configure = NULL;
+        if (sclres_manager) {
+            default_configure = sclres_manager->get_default_configure();
+        }
+        if (default_configure) {
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+        }
+
+        context->set_cur_moving_window(touch_id, SCLWINDOW_INVALID);
+
+        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+        //SclWindowContext *window_context = windows->get_window_context(window, TRUE);
+        SclWindowContext *window_context = windows->get_window_context(window);
+        /* Adjust event x and y positions as relative position to the virtual window */
+        if (window_context) {
+            /*if (window_context->isVirtual) {
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    x -= (window_context->x - base_window_context->x);
+                    y -= (window_context->y - base_window_context->y);
+                }
+            }*/
+            /* If the dim window is virtual and currently active, consider base window's event is occured in dim window */
+            if (windows->is_base_window(window)) {
+                SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+                if (dim_window_context) {
+                    if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
+                        window = windows->get_dim_window();
+                        window_context = dim_window_context;
+                    }
+                }
+            }
+        }
+
+        /* Iterate all the buttons and inform the event */
+        sclboolean ended = FALSE;
+
+        /* FIXME : The routine below seems to be removed, which was originally requested by Vodafone,
+         * to slow down the speed of repeat key right before stopping repeatkey event */
+        /* if (state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY) {
+            if (m_key_repeated_num > 10) {
+                utils->sleep(100);
+                CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                controller_button->process_button_repeat_pressed_event(pressed_window, pressed_key, touch_id);
+            }
+            ended = TRUE;
+        }*/
+
+        if (context->get_cur_pressed_window(touch_id) == window) {
+            if (abs(context->get_cur_pressed_point(touch_id).x - x) > utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD) ||
+                abs(context->get_cur_pressed_point(touch_id).y - y) > utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD) )
+            {
+                struct timeval t0 = context->get_cur_pressed_time(touch_id);
+                struct timeval t1;
+                gettimeofday(&t1, NULL);
+                float etime;
+                etime = ((t1.tv_sec * 1000000 + t1.tv_usec) - (t0.tv_sec * 1000000 + t0.tv_usec))/1000.0;
+                if (etime < SCL_FLICK_GESTURE_RECOG_TIME) {
+                    SCLDragType drag_type = DRAG_NONE;
+                    if (x > context->get_cur_pressed_point(touch_id).x + utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_RIGHT;
+                    }
+                    if (x < context->get_cur_pressed_point(touch_id).x - utils->get_scaled_x(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_LEFT;
+                    }
+                    if (y > context->get_cur_pressed_point(touch_id).y + utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_DOWN;
+                    }
+                    if (y < context->get_cur_pressed_point(touch_id).y - utils->get_scaled_y(SCL_FLICK_GESTURE_RECOG_THRESHOLD)) {
+                        drag_type = DRAG_UP;
+                    }
+                    SclNotiGestureFlickDesc desc;
+                    SclUIEventDesc ui_event_desc;
+                    ui_event_desc.key_value = NULL;
+                    ui_event_desc.key_event = NOT_USED;
+                    ui_event_desc.key_modifier = KEY_MODIFIER_NONE;
+                    ui_event_desc.event_type = EVENT_TYPE_RELEASE;
+                    ui_event_desc.touch_id = touch_id;
+                    ui_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    ui_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    ui_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+                    ui_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+                    desc.ui_event_desc = &ui_event_desc;
+                    desc.drag_type = drag_type;
+                    if (handler->on_event_notification(SCL_UINOTITYPE_GESTURE_FLICK, &desc)) {
+                        ended = TRUE;
+                    }
+                }
+            }
+        }
+
+        /* FIXME : We should consider this kind of action in general manner, not only specific to autopopup */
+        /* And also, this kind of implementation only selects button that was highlighted at least once. */
+        // {
+        //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
+        SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
+        if (pressed_window_context) {
+            utils->log("PRESSED CTX : %p %d %d\n", pressed_window,
+                pressed_window_context->geometry.x, pressed_window_context->geometry.y);
+            //if (pressedCtx->popuptype == POPUP_TYPE_AUTO_POPUP) {
+            sclboolean grab_event = FALSE;
+            const SclLayout *pressed_layout = cache->get_cur_layout(pressed_window);
+            if (pressed_layout) {
+                if (pressed_layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+                    grab_event = TRUE;
+                }
+                /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
+                if (grab_event) {
+                    /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
+                    sclboolean in_grab_area = TRUE;
+                    if (pressed_layout->add_grab_left != NOT_USED &&
+                        x < (pressed_window_context->geometry.x - pressed_layout->add_grab_left)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (pressed_layout->add_grab_right != NOT_USED &&
+                        x > (pressed_window_context->geometry.x + pressed_window_context->geometry.width
+                        + pressed_layout->add_grab_right)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (pressed_layout->add_grab_top != NOT_USED &&
+                        y < (pressed_window_context->geometry.y - pressed_layout->add_grab_top)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (pressed_layout->add_grab_bottom != NOT_USED &&
+                        y > (pressed_window_context->geometry.y + pressed_window_context->geometry.height
+                        + pressed_layout->add_grab_bottom)) {
+                        in_grab_area = FALSE;
+                    }
+                    if (in_grab_area) {
+                        SclLayoutKeyCoordinate *coord = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+                        if (coord) {
+                            x = coord->x + (coord->width / 2);
+                            y = coord->y + (coord->height / 2);
+
+                            for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                                SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, loop);
+                                const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, loop);
+                                if (button_context && coordinate) {
+                                    if (!(button_context->used)) {
+                                        ended = TRUE;
+                                    } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                                coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                        CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                                        if (controller_button->process_button_release_event(pressed_window, x, y, loop, touch_id, actual_event)) {
+                                            ret = TRUE;
+                                            ended = TRUE;
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        // }
+
+        SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+        /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
+        /* Ignore base window's release event if a popup window is opened */
+        if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+            if (windows->is_base_window(window)) {
+                ended = TRUE;
+                /* In case of direction button, the release event on other window should be processed */
+                if (coordinate && window_context && pressed_window_context) {
+                    if (coordinate->button_type == BUTTON_TYPE_DIRECTION || coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                        sclint relx = (window_context->geometry.x + x) - pressed_window_context->geometry.x;
+                        sclint rely = (window_context->geometry.y + y) - pressed_window_context->geometry.y;
+                        CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                        if (controller_button->process_button_release_event(pressed_window, relx, rely, pressed_key, touch_id, actual_event)) {
+                            button_index = pressed_key;
+                            ret = TRUE;
+                            x = coordinate->x + (coordinate->width / 2);
+                            y = coordinate->y + (coordinate->height / 2);
+                            skip_window = pressed_window;
+                        }
+                    }
+                }
+            }
+        }
+
+        sclboolean process_finished = FALSE;
+        do {
+            MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
+            if (multi_touch_context) {
+                if (!(multi_touch_context->is_sub_event)) {
+                    /* First check if the event occured in pressed key's threshold area */
+                    if (button_context && coordinate && !ended) {
+                        if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
+                            CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                            if (controller_button->process_button_release_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
+                                button_index = pressed_key;
+                                ret = TRUE;
+                                x = coordinate->x + (coordinate->width / 2);
+                                y = coordinate->y + (coordinate->height / 2);
+                            }
+                        }
+                    }
+                    for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                        SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
+                        const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                        if (cur_context && cur_coordinate) {
+                            if (!(cur_context->used)) {
+                                ended = TRUE;
+                            } else if (cur_context->state != BUTTON_STATE_DISABLED &&
+                                        cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                if (window != pressed_window || loop != pressed_key) {
+                                    CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                                    if (controller_button->process_button_release_event(window, x, y, loop, touch_id, actual_event)) {
+                                        button_index = loop;
+                                        ret = TRUE;
+                                    }
+                                }
+                            }
+                        }
+                    }
+                } else {
+                    process_finished = TRUE;
+
+                    SclUIEventDesc key_event_desc;
+                    key_event_desc.key_value = NULL;
+                    key_event_desc.key_event = NOT_USED;
+                    key_event_desc.key_modifier = KEY_MODIFIER_NONE;
+                    key_event_desc.event_type = EVENT_TYPE_NONE;
+                    key_event_desc.touch_id = touch_id;
+                    key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+                    key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+                    key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+                    key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+                    handler->on_event_key_clicked(key_event_desc);
+                }
+            }
+
+            /* For covering a missing area about 1 pixel */
+            if (!ret) {
+                ended = FALSE;
+
+                if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+                        state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+                    if (windows->is_base_window(window)) {
+                        ended = TRUE;
+                    }
+                }
+
+                for (int loop = 0;loop < MAX_KEY && !ended;loop++) {
+                    SclButtonContext *cur_context = cache->get_cur_button_context(window, loop);
+                    if (cur_context && coordinate) {
+                        if (!(cur_context->used)) {
+                            ended = TRUE;
+                            break;
+                        } else if (cur_context->state != BUTTON_STATE_DISABLED &&
+                                    coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                            CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                            if (controller_button->process_button_release_event(window, x+1, y+1, loop, touch_id)) {
+                                button_index = loop;
+                                ret = TRUE;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+            if (windows->is_base_window(window)) {
+                process_finished = TRUE;
+            } else if (button_index != NOT_USED) {
+                process_finished = TRUE;
+            } else {
+                if (layout && layout->use_sw_background && layout->bg_color.a == 0) {
+                    /* If we could not find appropriate button in this popup window and the popup is transparent */
+                    SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                    if (base_window_context && window_context) {
+                        x = (window_context->geometry.x + x - base_window_context->geometry.x);
+                        y = (window_context->geometry.y + y - base_window_context->geometry.y);
+                    }
+                    window = windows->get_base_window();
+                } else {
+                    process_finished = TRUE;
+                }
+            }
+        } while (!process_finished);
+
+        if (!ret) {
+            SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+            SCLShiftState shift_index = context->get_shift_state();
+            if (!scl_check_arrindex(shift_index, SCL_SHIFT_STATE_MAX)) shift_index = SCL_SHIFT_STATE_OFF;
+            if (context->get_caps_lock_mode()) {
+                shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+            }
+
+            SclUIEventDesc key_event_desc;
+            if (coordinate && button_context) {
+                key_event_desc.key_type = coordinate->key_type;
+
+                key_event_desc.key_value = coordinate->key_value[shift_index][button_context->multitap_index];
+                key_event_desc.key_event = coordinate->key_event[shift_index][button_context->multitap_index];
+            }
+            key_event_desc.key_modifier = context->get_cur_key_modifier(touch_id);;
+
+            key_event_desc.event_type = EVENT_TYPE_RELEASE;
+            key_event_desc.touch_id = touch_id;
+            key_event_desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+            key_event_desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+            key_event_desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+            key_event_desc.touch_event_order = context->get_multi_touch_event_order(touch_id);
+
+            handler->on_event_drag_state_changed(key_event_desc);
+        }
+
+        if (windows->is_base_window(window)) {
+            state->set_cur_action_state(ACTION_STATE_BASE_INIT);
+        } else {
+            state->set_cur_action_state(ACTION_STATE_POPUP_INIT);
+        }
+
+        /* Restore previously pressed button's context and redraw it */
+        if (button_context && coordinate) {
+            button_context->state = BUTTON_STATE_NORMAL;
+            /* Commented below line to postpone some of the feedback for releasing */
+            //windows->update_window(pressed_window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+        }
+
+        /* If there is postponed update of button, update it now */
+        sclwindow last_win = context->get_last_pressed_window();
+        scl8 last_key = context->get_last_pressed_key();
+        if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+            const SclLayoutKeyCoordinate* coords = cache->get_cur_layout_key_coordinate(last_win, last_key);
+            if (coords) {
+                windows->update_window(last_win, coords->x, coords->y, coords->width, coords->height);
+            }
+        }
+
+        /* To postpone some of the feedback for releasing */
+        context->set_last_pressed_key(context->get_cur_pressed_key(touch_id));
+        context->set_last_pressed_window(context->get_cur_pressed_window(touch_id));
+
+        /* Do what has to be done when mouse gets released */
+        sclboolean signaled = FALSE;
+        if (coordinate) {
+            switch (coordinate->popup_type) {
+                case POPUP_TYPE_BTN_RELEASE_POPUP:
+                case POPUP_TYPE_BTN_RELEASE_POPUP_ONCE:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP:
+                case POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE:
+                    {
+                        /* Fix me : We should consider z-order */
+                        skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                        controller->handle_engine_signal(SCL_SIG_MOUSE_RELEASE, skip_window);
+                        signaled = TRUE;
+                    }
+                    break;
+                case POPUP_TYPE_NONE: break;
+                case POPUP_TYPE_BTN_PRESS_POPUP_DRAG: break;
+                case POPUP_TYPE_AUTO_POPUP: break;
+                case MAX_POPUP_TYPE: break;
+                default: break;
+            }
+        }
+        if (!signaled) {
+            //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+            window_context = windows->get_window_context(window);
+            if (window_context) {
+                if (window_context->popup_type == POPUP_TYPE_BTN_RELEASE_POPUP ||
+                    window_context->popup_type == POPUP_TYPE_BTN_LONGPRESS_POPUP) {
+                    /* Don't close window if the clicked button is a child of ReleasePopup window */
+                    skip_window = window;
+                    controller->handle_engine_signal(SCL_SIG_MOUSE_RELEASE, window);
+                    signaled = TRUE;
+                }
+            }
+            if (!signaled) {
+                controller->handle_engine_signal(SCL_SIG_MOUSE_RELEASE);
+            }
+        }
+
+        context->set_cur_pressed_key(touch_id, NOT_USED);
+        context->set_cur_pressed_window(touch_id, SCLWINDOW_INVALID);
+
+        if (ret && button_index != NOT_USED) {
+            const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, button_index);
+            if (cur_coordinate) {
+                if (cur_coordinate->dont_close_popup) {
+                    skip_window = windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP);
+                }
+            }
+        } else {
+            if (pressed_window == windows->get_nth_window_in_Z_order_list(SCL_WINDOW_Z_TOP)) {
+                if (pressed_window_context) {
+                    if (pressed_window_context->popup_type != POPUP_TYPE_BTN_RELEASE_POPUP_ONCE &&
+                        pressed_window_context->popup_type != POPUP_TYPE_BTN_LONGPRESS_POPUP_ONCE &&
+                        pressed_window_context->popup_type != POPUP_TYPE_AUTO_POPUP &&
+                        pressed_window_context->popup_type != POPUP_TYPE_BTN_PRESS_POPUP_DRAG)
+                    {
+                        skip_window = pressed_window;
+                    }
+                }
+            }
+        }
+        windows->close_all_popups(skip_window);
+
+        /* Destroy key related timers */
+        events->destroy_timer(SCL_TIMER_AUTOPOPUP);
+        events->destroy_timer(SCL_TIMER_SHORT_LONGKEY);
+        events->destroy_timer(SCL_TIMER_LONGKEY);
+        events->destroy_timer(SCL_TIMER_REPEATKEY);
+
+        /* If there are more than 1 active multitouch ids, don't play button_delay trick */
+        if (context->get_multi_touch_context_num() == 1) {
+            /* To postpone some of the feedback for releasing */
+            CSCLController *controller = CSCLController::get_instance();
+            events->create_timer(SCL_TIMER_BUTTON_DELAY, controller->get_button_delay_duration(), 0);
+        } else {
+            last_win = context->get_last_pressed_window();
+            last_key = context->get_last_pressed_key();
+
+            if (last_win != SCLWINDOW_INVALID && last_key != NOT_USED) {
+                const SclLayoutKeyCoordinate* last_coordinate = cache->get_cur_layout_key_coordinate(last_win, last_key);
+                if (last_coordinate) {
+                    windows->update_window(last_win,
+                        last_coordinate->x, last_coordinate->y, last_coordinate->width, last_coordinate->height);
+                }
+            }
+
+            windows->hide_window(windows->get_magnifier_window());
+            context->set_last_pressed_window(SCLWINDOW_INVALID);
+            context->set_last_pressed_key(NOT_USED);
+        }
+    }
+
+    if (context) {
+        if (touch_id == context->get_last_touch_device_id()) {
+            context->set_last_touch_device_id(SCLTOUCHDEVICE_INVALID);
+        }
+        context->destroy_multi_touch_context(touch_id);
+    }
+
+    return ret;
+}
+
+SCLKeyModifier
+CSCLControllerMouse::get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist, sclboolean check_farthest,
+                                      scltouchdevice touch_id, sclbyte extra_option) {
+    typedef struct {
+        double lowerbound;
+        double upperbound;
+        SCLKeyModifier modifier;
+    } DIRECTIONINFO;
+
+    CSCLContext *context = CSCLContext::get_instance();
+    SCLKeyModifier key_modifier = KEY_MODIFIER_NONE;
+
+    if (context) {
+        double theta = atan2(deltay , (deltax ? deltax : 1)); /* Avoid divide by 0 exception */
+        sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
+        SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
+        if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS ||
+            extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
+            extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN) { /* 8 directions */
+                /* If the theta is below 0, the direction is upward since the y coordinate grows downward */
+                /* The below angle values are customized for MoAKey, need to provide customizing API */
+                DIRECTIONINFO info[] = {
+                    {-8 * (M_PI / 8), -7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
+                    {-7 * (M_PI / 8), -5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_LEFT},
+                    {-5 * (M_PI / 8), -2.7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP},
+                    {-2.7 * (M_PI / 8), -1.5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_UP_RIGHT},
+                    {-1.5 * (M_PI / 8),  1 * (M_PI / 8), KEY_MODIFIER_DIRECTION_RIGHT},
+                    { 1 * (M_PI / 8),  3 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_RIGHT},
+                    { 3 * (M_PI / 8),  5 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN},
+                    { 5 * (M_PI / 8),  7 * (M_PI / 8), KEY_MODIFIER_DIRECTION_DOWN_LEFT},
+                    { 7 * (M_PI / 8),  8 * (M_PI / 8), KEY_MODIFIER_DIRECTION_LEFT},
+                };
+                for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
+                    if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
+                        key_modifier = info[loop].modifier;
+                    }
+                }
+        } else { /* 4 directions */
+            /* If the state was dragging to one of 4 directions and the final release point is
+            * far enough from inital press point, and the angle is in between out predefined angle value */
+            if (extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE &&
+                cur_drag_state != SCL_DRAG_STATE_NONE && cur_drag_state != SCL_DRAG_STATE_INVALID &&
+                dist > SCL_DRAG_CURVE_RECOG_DIST &&
+                ratio > (1 / SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) &&
+                ratio < SCL_DRAG_CURVE_FINAL_ANGLE_VALUE) {
+                    if (cur_drag_state == SCL_DRAG_STATE_DOWN) {
+                        if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_RIGHT;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_DOWN_LEFT;
+                    }
+                    if (cur_drag_state == SCL_DRAG_STATE_UP) {
+                        if (deltax > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_RIGHT;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_UP_LEFT;
+                    }
+                    if (cur_drag_state == SCL_DRAG_STATE_LEFT) {
+                        if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_DOWN;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_LEFT_UP;
+                    }
+                    if (cur_drag_state == SCL_DRAG_STATE_RIGHT) {
+                        if (deltay > 0) key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_DOWN;
+                        else key_modifier = KEY_MODIFIER_DIRECTION_CURVE_RIGHT_UP;
+                    }
+            } else {
+                DIRECTIONINFO info[] = {
+                    {-4 * (M_PI / 4), -3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
+                    {-3 * (M_PI / 4), -1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_UP},
+                    {-1 * (M_PI / 4),  1 * (M_PI / 4), KEY_MODIFIER_DIRECTION_RIGHT},
+                    { 1 * (M_PI / 4),  3 * (M_PI / 4), KEY_MODIFIER_DIRECTION_DOWN},
+                    { 3 * (M_PI / 4),  4 * (M_PI / 4), KEY_MODIFIER_DIRECTION_LEFT},
+                };
+                for (size_t loop = 0; loop < sizeof(info) / sizeof(DIRECTIONINFO); loop++) {
+                    if (theta >= info[loop].lowerbound && theta <= info[loop].upperbound) {
+                        key_modifier = info[loop].modifier;
+                    }
+                }
+            }
+        }
+
+        if (extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_LONG ||
+            extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_LONG) {
+                if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
+                    key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
+                        key_modifier = (SCLKeyModifier)(key_modifier + 8); // Add LONG attribute;
+                }
+        }
+        if (check_farthest || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
+            if (key_modifier >= KEY_MODIFIER_DIRECTION_LEFT &&
+                key_modifier <= KEY_MODIFIER_DIRECTION_DOWN_RIGHT) {
+                    key_modifier = (SCLKeyModifier)(key_modifier + 16); // Add RETURN attribute;
+            }
+        }
+    }
+
+    return key_modifier;
+}
+
+SCLDragState get_drag_state(sclint deltax, sclint deltay)
+{
+    SCLDragState ret = SCL_DRAG_STATE_INVALID;
+
+    sclfloat ratio = fabs((sclfloat)deltay / (deltax ? deltax : 1));
+    /* If tan(theta) is smaller than our predefined value */
+    if (ratio <= (1 / SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE)) {
+        if (deltax > 0) {
+            ret = SCL_DRAG_STATE_RIGHT;
+        } else {
+            ret = SCL_DRAG_STATE_LEFT;
+        }
+    } else if (ratio >= SCL_DRAG_CURVE_4_DIRECTION_ANGLE_VALUE) {
+        /* If tan(theta) is bigger than our predefined value */
+        if (deltay > 0) {
+            ret = SCL_DRAG_STATE_DOWN;
+        } else {
+            ret = SCL_DRAG_STATE_UP;
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id, sclboolean actual_event)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    CSCLController *controller = CSCLController::get_instance();
+    if (controller->get_input_events_disabled()) return FALSE;
+
+    //utils->log("Controller::mouse_move : %d %d\n", x, y);
+
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLEvents *events = CSCLEvents::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    CSCLEventHandler *handler = CSCLEventHandler::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (!sclres_manager) return FALSE;
+
+    PSclModifierDecoration sclres_modifier_decoration = sclres_manager->get_modifier_decoration_table();
+    if (!sclres_modifier_decoration) return FALSE;
+
+    if (cache && state && windows && context && utils && adjustment && sclres_manager) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+
+        if (!(context->find_multi_touch_context(touch_id))) return FALSE;
+
+        PSclDefaultConfigure default_configure = sclres_manager->get_default_configure();
+        if (default_configure) {
+            SCLDisplayMode display_mode = context->get_display_mode();
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[display_mode], &x, &y);
+        }
+
+        //SclWindowContext *window_context = windows->get_window_context(window, FALSE);
+        SclWindowContext *window_context = windows->get_window_context(window);
+        /* Adjust event x and y positions as relative position to the virtual window */
+        if (window_context) {
+            /*if (window_context->isVirtual) {
+                SclWindowContext *base_window_context = windows->get_window_context(windows->get_base_window());
+                if (base_window_context) {
+                    x -= (window_context->x - base_window_context->x);
+                    y -= (window_context->y - base_window_context->y);
+                }
+            }*/
+            /* If the dim window is virtual and currently active, let's just skip this event */
+            if (windows->is_base_window(window)) {
+                SclWindowContext *dim_window_context = windows->get_window_context(windows->get_dim_window());
+                if (dim_window_context) {
+                    if (dim_window_context->is_virtual && !(dim_window_context->hidden)) {
+                        return FALSE;
+                    }
+                }
+            }
+            /* If the pressed event was occured in dim window, let's just skip this move event */
+            if (context->get_last_pressed_window() == windows->get_dim_window()) {
+                return FALSE;
+            }
+        }
+
+        sclwindow pressed_window = context->get_cur_pressed_window(touch_id);
+        scl8 pressed_key = context->get_cur_pressed_key(touch_id);
+        SclButtonContext *button_context = cache->get_cur_button_context(pressed_window, pressed_key);
+        const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(pressed_window, pressed_key);
+
+        /* If the multitouch type is SETTLE_PREVIOUS and is not the last touch device, let's ignore move events */
+        if (coordinate) {
+            if (coordinate->multitouch_type == SCL_MULTI_TOUCH_TYPE_SETTLE_PREVIOUS) {
+                if (context->get_last_touch_device_id() != touch_id) {
+                    return FALSE;
+                }
+            }
+        }
+
+        context->set_cur_moving_point(touch_id, x, y);
+        context->set_cur_moving_window(touch_id, window);
+
+        /* If in longkey state, do not process, just return */
+        if (state->get_cur_action_state() == ACTION_STATE_BASE_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_BASE_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY) {
+            return FALSE;
+        }
+        /* FIXME : The rule below would not be a general requirement. A policy is needed regarding this. */
+        /* And if the event occured in popup window, don't come back to base window */
+        if (state->get_cur_action_state() == ACTION_STATE_POPUP_INIT ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_PRESS ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_MOVING ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_RELEASE ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_REPEATKEY ||
+                state->get_cur_action_state() == ACTION_STATE_POPUP_LONGKEY) {
+            if (windows->is_base_window(window)) {
+                return FALSE;
+            }
+        }
+
+        SclUIEventDesc desc;
+        SCLShiftState shift_index = context->get_shift_state();
+        if (context->get_caps_lock_mode()) {
+            shift_index = (shift_index == SCL_SHIFT_STATE_OFF) ? SCL_SHIFT_STATE_ON : SCL_SHIFT_STATE_OFF;
+        }
+        if (coordinate) {
+            desc.key_type = coordinate->key_type;
+            desc.key_value = coordinate->key_value[shift_index][0];
+            desc.key_event = coordinate->key_event[shift_index][0];
+        }
+        desc.event_type = EVENT_TYPE_MOVE;
+        desc.mouse_pressed_point = context->get_cur_pressed_point(touch_id);
+        desc.mouse_current_point = context->get_cur_moving_point(touch_id);
+        desc.mouse_farthest_point = context->get_farthest_move_point(touch_id);
+
+        if (handler && handler->on_event_drag_state_changed(desc) != SCL_EVENT_PASS_ON) {
+            return FALSE;
+        }
+
+        /* FIXME : Add a condition to skip this code if longkey timer is not active */
+        /* If the mouse has moved out of threshold value of longkey keypress area, destroy longkey timer */
+        CSCLController *controller = CSCLController::get_instance();
+        if (controller->get_longkey_cancel_dist() > 0) {
+            sclfloat dist = utils->get_distance(x, y,
+                context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
+            if (controller->get_longkey_cancel_dist() < dist) {
+                events->destroy_timer(SCL_TIMER_LONGKEY);
+            }
+        }
+
+        if (windows->is_base_window(window)) {
+            state->set_cur_action_state(ACTION_STATE_BASE_MOVING);
+        } else {
+            state->set_cur_action_state(ACTION_STATE_POPUP_MOVING);
+        }
+
+        /* Iterate all the buttons and inform the event */
+        sclboolean ended = FALSE;
+
+        /* Check farthest move point and update it */
+        sclint originx = x;
+        sclint originy = y;
+        if (pressed_window != window) {
+            //SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window, FALSE);
+            SclWindowContext *pressed_window_context = windows->get_window_context(pressed_window);
+            if (window_context && pressed_window_context) {
+                originx = (window_context->geometry.x - pressed_window_context->geometry.x) + x;
+                originy = (window_context->geometry.y - pressed_window_context->geometry.y) + y;
+            }
+        }
+        sclint startx = originx;
+        sclint starty = originy;
+
+        /* Check if we should recognize drag curve */
+        if (coordinate) {
+            startx = context->get_cur_pressed_point(touch_id).x;
+            starty = context->get_cur_pressed_point(touch_id).y;
+            sclint deltax = originx - startx;
+            sclint deltay = originy - starty;
+            sclfloat approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
+
+            sclboolean update_magnifier = FALSE;
+            sclboolean drag_state_changed = FALSE;
+            SCLDragState cur_drag_state = context->get_cur_drag_state(touch_id);
+            SCLDragState next_drag_state = SCL_DRAG_STATE_NONE;
+            sclfloat direction_recog_dist = SCL_DIRECTION_RECOG_DIST * utils->get_smallest_scale_rate();
+            if (coordinate->is_side_button) {
+                direction_recog_dist = SCL_DIRECTION_RECOG_DIST_SIDE * utils->get_smallest_scale_rate();
+            };
+
+            if (coordinate->button_type == BUTTON_TYPE_DIRECTION) {
+                /* Do not check farthest move point if current drag state is SCL_DRAG_STATE_RETURN */
+                if (context->get_cur_drag_state(touch_id) != SCL_DRAG_STATE_RETURN) {
+                    if (approximate_dist > context->get_farthest_move_dist(touch_id)) {
+                        context->set_farthest_move_point(touch_id, originx, originy);
+                    }
+                }
+
+                if (cur_drag_state == SCL_DRAG_STATE_RETURN) {
+                    direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_RETURN;
+                } else if (cur_drag_state != SCL_DRAG_STATE_NONE) {
+                    direction_recog_dist *= SCL_DRAG_RETURN_RECOG_THRESHOLD_OTHER;
+                }
+                if (approximate_dist > direction_recog_dist) {
+                    next_drag_state = get_drag_state(deltax, deltay);
+                    /* Disable longkey if dragging is recognized */
+                    events->destroy_timer(SCL_TIMER_LONGKEY);
+                }
+                if (cur_drag_state != next_drag_state) {
+                    drag_state_changed = TRUE;
+                }
+                if (cur_drag_state == SCL_DRAG_STATE_NONE) {
+                    //if (nextDragState != SCL_DRAG_STATE_INVALID) {
+                        cur_drag_state = next_drag_state;
+                    //}
+                } else if (cur_drag_state != next_drag_state) {
+                    if (next_drag_state == SCL_DRAG_STATE_NONE) {
+                        cur_drag_state = SCL_DRAG_STATE_RETURN;
+                    } else {
+                        cur_drag_state = next_drag_state;
+                    }
+                }
+
+                context->set_cur_drag_state(touch_id, cur_drag_state);
+                sclboolean check_farthest = FALSE;
+                sclshort display = context->get_display_mode();
+                if (!scl_check_arrindex(display, DISPLAYMODE_MAX)) display = 0;
+                sclfloat dist = utils->get_distance(originx, originy,
+                    context->get_cur_pressed_point(touch_id).x, context->get_cur_pressed_point(touch_id).y);
+                if (dist < direction_recog_dist && context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_RETURN) {
+                    if (coordinate->extra_option == DIRECTION_EXTRA_OPTION_8_DIRECTIONS_WITH_RETURN ||
+                        coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN ||
+                        coordinate->extra_option == DIRECTION_EXTRA_OPTION_4_DIRECTIONS_WITH_RETURN_AND_CURVE) {
+                            deltax = context->get_farthest_move_point(touch_id).x -
+                                context->get_cur_pressed_point(touch_id).x;
+                            deltay = context->get_farthest_move_point(touch_id).y -
+                                context->get_cur_pressed_point(touch_id).y;
+                            dist = utils->get_distance(context->get_farthest_move_point(touch_id),
+                                context->get_cur_pressed_point(touch_id));
+                            check_farthest = TRUE;
+                    }
+                }
+                SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist,
+                    check_farthest, touch_id, coordinate->extra_option);
+                if (dist > direction_recog_dist) {
+                    context->set_cur_key_modifier(touch_id, key_modifier);
+                }
+                /* If this button needs to be decorated when dragged */
+                if (coordinate->modifier_decorator) {
+                    const SclModifierDecoration *decoration = NULL;
+                    /* FIXME */
+                    /*if (scl_check_arrindex(coordinate->modifier_decorator,
+                        sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+                    scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+                    if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+                        if (sclres_modifier_decoration[decoration_id].valid) {
+                            decoration = &(sclres_modifier_decoration[decoration_id]);
+                        }
+                    }
+                    /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
+                    if (decoration) {
+                        if (decoration->bg_image_path[display][key_modifier]) {
+                            windows->update_window(window,
+                                coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                        }
+                    }
+                }
+                if (dist > direction_recog_dist) {
+                    if (context->get_magnifier_enabled()) {
+                        update_magnifier = TRUE;
+                    }
+                }
+            } else if (coordinate->button_type == BUTTON_TYPE_RELATIVE_DIRECTION) {
+                if (cur_drag_state != SCL_DRAG_STATE_NONE) {
+                    startx = context->get_prev_moving_point(touch_id).x;
+                    starty = context->get_prev_moving_point(touch_id).y;
+                    approximate_dist = utils->get_approximate_distance(originx, originy, startx, starty);
+                    direction_recog_dist = SCL_DIRECTION_RELATIVE_RECOG_DIST * utils->get_smallest_scale_rate();
+                }
+                deltax = originx - startx;
+                deltay = originy - starty;
+                //printf("DIST : %f, RECOG : %f\n", dist, direction_recog_dist);
+                if (approximate_dist > direction_recog_dist) {
+                    next_drag_state = get_drag_state(deltax, deltay);
+                    /* Disable longkey if dragging is recognized */
+                    events->destroy_timer(SCL_TIMER_LONGKEY);
+
+                    if (cur_drag_state != next_drag_state) {
+                        drag_state_changed = TRUE;
+                    }
+                    if (next_drag_state != SCL_DRAG_STATE_NONE) {
+                        cur_drag_state = next_drag_state;
+                    }
+                    context->set_cur_drag_state(touch_id, cur_drag_state);
+
+                    startx = context->get_farthest_move_point(touch_id).x;
+                    starty = context->get_farthest_move_point(touch_id).y;
+                    deltax = originx - startx;
+                    deltay = originy - starty;
+                    sclfloat dist_farthest = utils->get_approximate_distance(originx, originy, startx, starty);
+                    //printf("%d %d %d %d %f, %d %d\n", originx, originy, startx, starty, dist_farthest, cur_drag_state, next_drag_state);
+                    /* Let's see how much we are away from the last farthest point */
+                    sclfloat diffdir_recog_dist = SCL_DIRECTION_RELATIVE_DIFFDIR_RECOG_DIST * utils->get_smallest_scale_rate();
+                    /* If we moved certain amount from the point where direction changed, process drag state change routine */
+                    if (dist_farthest > diffdir_recog_dist || context->get_cur_drag_state(touch_id) == SCL_DRAG_STATE_NONE) {
+                        sclshort display = context->get_display_mode();
+                        SCLKeyModifier key_modifier = get_drag_key_modifier(deltax, deltay, dist_farthest,
+                            FALSE, touch_id, coordinate->extra_option);
+                        context->set_cur_key_modifier(touch_id, key_modifier);
+                        /* If this button needs to be decorated when dragged */
+                        if (coordinate->modifier_decorator) {
+                            const SclModifierDecoration  *decoration = NULL;
+                            /* FIXME */
+                            /*if (scl_check_arrindex(coordinate->modifier_decorator,
+                                sizeof(sclres_modifier_decoration) / sizeof(SclModifierDecoration ))) {*/
+                            scl8 decoration_id = sclres_manager->get_modifier_decoration_id(coordinate->modifier_decorator);
+                            if (scl_check_arrindex(decoration_id, MAX_SCL_MODIFIER_DECORATION_NUM)) {
+                                if (sclres_modifier_decoration[decoration_id].valid) {
+                                    decoration = &(sclres_modifier_decoration[decoration_id]);
+                                }
+                            }
+                            /* Check if the button really needs to be redrawn (whether it has non-null bg_image_path information */
+                            if (decoration) {
+                                if (decoration->bg_image_path[display][key_modifier]) {
+                                    windows->update_window(window,
+                                        coordinate->x, coordinate->y, coordinate->width, coordinate->height);
+                                }
+                            }
+                        }
+
+                        if (context->get_magnifier_enabled()) {
+                            update_magnifier = TRUE;
+                        }
+                    }
+                    context->set_prev_moving_point(touch_id, originx, originy);
+                }
+                if (drag_state_changed) {
+                    /* When the dragging direction changes, save the current position as farthest point for future comparison */
+                    context->set_farthest_move_point(touch_id, originx, originy);
+                    LOGD("SET_FARTHEST : %d %d %d", originx, originy, context->get_cur_drag_state(touch_id));
+                }
+            }
+
+            if (update_magnifier) {
+                PSclMagnifierWndConfigure magnifier_configure = NULL;
+                if (sclres_manager) {
+                    magnifier_configure = sclres_manager->get_magnifier_configure();
+                }
+
+                const SclLayout *base_layout = cache->get_cur_layout(windows->get_base_window());
+                if (base_layout && magnifier_configure) {
+                    SclPoint zoomwinpos = {0, 0};
+                    /* calculates x position to be set */
+                    zoomwinpos.x = (coordinate->x + (coordinate->width / 2)) -
+                        (magnifier_configure->width * utils->get_custom_scale_rate_x() / 2);
+
+                    /* calculates y position to be set */
+                    sclint scnWidth, scnHeight;
+                    utils->get_screen_resolution(&scnWidth, &scnHeight);
+
+                    zoomwinpos.y =  coordinate->y - magnifier_configure->height * utils->get_custom_scale_rate_y();
+                    if (window_context) {
+                        zoomwinpos.x += window_context->geometry.x;
+                        zoomwinpos.y += window_context->geometry.y;
+                    }
+                    if (zoomwinpos.x < 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x()) {
+                        zoomwinpos.x = 0 - magnifier_configure->padding_x * utils->get_custom_scale_rate_x();
+                    }
+                    if (zoomwinpos.x > scnWidth +
+                        magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                        magnifier_configure->width * utils->get_custom_scale_rate_x()) {
+                        zoomwinpos.x = scnWidth +
+                            magnifier_configure->padding_x * utils->get_custom_scale_rate_x() -
+                            magnifier_configure->width * utils->get_custom_scale_rate_x();
+                    }
+                    zoomwinpos.y += magnifier_configure->padding_y * utils->get_custom_scale_rate_y();
+
+                    zoomwinpos.x += coordinate->magnifier_offset_x;
+                    zoomwinpos.y += coordinate->magnifier_offset_y;
+                    windows->move_window(windows->get_magnifier_window(), zoomwinpos.x, zoomwinpos.y);
+                    windows->show_window(windows->get_magnifier_window(), 0);
+                }
+            }
+        }
+
+        sclboolean grab_event = FALSE;
+        if (layout) {
+            if (layout->style == LAYOUT_STYLE_POPUP_GRAB) {
+                grab_event = TRUE;
+            }
+            /* If the topmost window has the POPUP_GRAB style, find the nearest button to the mouse pointer */
+            if (grab_event && window_context) {
+                /* If the layout's addGrab* values are defined, process this event only if the event occured inside grab area */
+                sclboolean in_grab_area = TRUE;
+                if (layout->add_grab_left != NOT_USED && x < -(layout->add_grab_left)) {
+                    in_grab_area = FALSE;
+                }
+                if (layout->add_grab_right != NOT_USED && x >
+                    (window_context->geometry.width + layout->add_grab_right)) {
+                    in_grab_area = FALSE;
+                }
+                if (layout->add_grab_top != NOT_USED && y < -(layout->add_grab_top)) {
+                    in_grab_area = FALSE;
+                }
+                if (layout->add_grab_bottom != NOT_USED && y >
+                    (window_context->geometry.height + layout->add_grab_bottom)) {
+                    in_grab_area = FALSE;
+                }
+                if (in_grab_area) {
+                    float min_dist = (float)((unsigned int)(-1));
+                    int min_dist_index = NOT_USED;
+                    for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
+                        button_context = cache->get_cur_button_context(window, loop);
+                        const SclLayoutKeyCoordinate *cur_coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+                        if (button_context && cur_coordinate) {
+                            if (!(button_context->used)) {
+                                ended = TRUE;
+                            } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                float dist = utils->get_approximate_distance(x, y,
+                                        cur_coordinate->x + (cur_coordinate->width / 2),
+                                        cur_coordinate->y + (cur_coordinate->height / 2));
+                                if (dist < min_dist) {
+                                    min_dist_index = loop;
+                                    min_dist = dist;
+                                }
+                            }
+                        }
+                    }
+                    /* When we found the nearest button, generate this event on the button */
+                    if (min_dist_index != NOT_USED) {
+                        const SclLayoutKeyCoordinate *min_coordinate =
+                            cache->get_cur_layout_key_coordinate(window, min_dist_index);
+                        if (min_coordinate) {
+                            x = min_coordinate->x + (min_coordinate->width / 2);
+                            y = min_coordinate->y + (min_coordinate->height / 2);
+                            CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                            if (controller_button->process_button_move_event(window, x, y, min_dist_index, touch_id, actual_event)) {
+                                ret = TRUE;
+                            }
+                        }
+                    }
+                }
+            } else {
+                MultiTouchContext *multi_touch_context = context->find_multi_touch_context(touch_id);
+                if (multi_touch_context) {
+                    sclint button_index = NOT_USED;
+                    if (!(multi_touch_context->is_sub_event)) {
+                        sclboolean process_finished = FALSE;
+                        do {
+                            /* First check if the event occured in pressed key's threshold area */
+                            if (button_context && coordinate) {
+                                if (pressed_window == window) { // Check only when the window is the one initally pressed
+                                    if (button_context->used && button_context->state != BUTTON_STATE_DISABLED) {
+                                        CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                                        if (controller_button->process_button_move_event(pressed_window, x, y, pressed_key, touch_id, actual_event)) {
+                                            ret = TRUE;
+                                            x = coordinate->x + (coordinate->width / 2);
+                                            y = coordinate->y + (coordinate->height / 2);
+                                            button_index = pressed_key;
+                                        }
+                                    }
+                                }
+                            }
+                            for (int loop = 0;loop < MAX_KEY && !ended && !ret;loop++) {
+                                button_context = cache->get_cur_button_context(window, loop);
+                                const SclLayoutKeyCoordinate *cur_coordinate =
+                                    cache->get_cur_layout_key_coordinate(window, loop);
+                                if (button_context && cur_coordinate) {
+                                    if (!(button_context->used)) {
+                                        ended = TRUE;
+                                    } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                                                cur_coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                                        if (window != pressed_window || loop != pressed_key) {
+                                            CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                                            if (controller_button->process_button_move_event(window, x, y, loop, touch_id, actual_event)) {
+                                                ret = TRUE;
+                                                button_index = loop;
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+
+                            if (windows->is_base_window(window)) {
+                                process_finished = TRUE;
+                            } else if (button_index != NOT_USED) {
+                                process_finished = TRUE;
+                            } else {
+                                const SclLayout *cur_layout = cache->get_cur_layout(window);
+                                if (cur_layout && cur_layout->use_sw_background && cur_layout->bg_color.a == 0) {
+                                    /* If we could not find appropriate button in this popup window and the popup is transparent */
+                                    SclWindowContext *base_window_context =
+                                        windows->get_window_context(windows->get_base_window());
+                                    if (base_window_context && window_context) {
+                                        x = (window_context->geometry.x + x - base_window_context->geometry.x);
+                                        y = (window_context->geometry.y + y - base_window_context->geometry.y);
+                                    }
+                                    window = windows->get_base_window();
+                                } else {
+                                    process_finished = TRUE;
+                                }
+                            }
+                        } while (!process_finished);
+                    }
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
+sclboolean
+CSCLControllerMouse::mouse_over(sclwindow window, sclint x, sclint y)
+{
+    SCL_DEBUG();
+    sclboolean ret = FALSE;
+
+    CSCLController *controller = CSCLController::get_instance();
+    if (controller->get_input_events_disabled())
+        return FALSE;
+
+    /* Adjust x,y coordinate by touch offset */
+    CSCLErrorAdjustment *adjustment = CSCLErrorAdjustment::get_instance();
+    /* Iterate all the buttons and inform the event */
+
+    CSCLContext *context = CSCLContext::get_instance();
+    CSCLResourceCache *cache = CSCLResourceCache::get_instance();
+    CSCLActionState *state = CSCLActionState::get_instance();
+    CSCLWindows *windows = CSCLWindows::get_instance();
+    CSCLUtils *utils = CSCLUtils::get_instance();
+    SclResParserManager *sclres_manager = SclResParserManager::get_instance();
+
+    if (cache && state && windows && context && utils && adjustment && sclres_manager) {
+        const SclLayout *layout = cache->get_cur_layout(window);
+        if (layout) {
+            x += layout->mouse_manipulate_x;
+            y += layout->mouse_manipulate_y;
+        }
+
+        SCLDisplayMode cur_display_mode = context->get_display_mode();
+
+        const SclDefaultConfigure *default_configure = sclres_manager->get_default_configure();
+        if (default_configure) {
+            adjustment->apply_touch_offset(default_configure->touch_offset_level[cur_display_mode], &x, &y);
+        }
+
+        /* Iterate all the buttons and inform the event */
+        sclboolean ended = FALSE;
+
+        for (int loop = 0; loop < MAX_KEY && !ended && !ret; loop++) {
+            SclButtonContext *button_context = cache->get_cur_button_context(window, loop);
+            const SclLayoutKeyCoordinate *coordinate = cache->get_cur_layout_key_coordinate(window, loop);
+            if (button_context && coordinate) {
+                if (!(button_context->used)) {
+                    ended = TRUE;
+                } else if (button_context->state != BUTTON_STATE_DISABLED &&
+                            coordinate->button_type != BUTTON_TYPE_UIITEM) {
+                    CSCLControllerButton *controller_button = CSCLControllerButton::get_instance();
+                    if (controller_button->process_button_over_event(window, x, y, loop)) {
+                        ret = TRUE;
+                    }
+                }
+            }
+        }
+    }
+
+    return ret;
+}
+
diff --git a/scl/sclcontroller_mouse.h b/scl/sclcontroller_mouse.h
new file mode 100644 (file)
index 0000000..3a3a817
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "sclgwes.h"
+#include "sclutils.h"
+#include "sclcontext.h"
+
+#ifndef __SCL_CONTROLLER_MOUSE_H__
+#define __SCL_CONTROLLER_MOUSE_H__
+
+//SCL_BEGIN_DECLS
+
+namespace scl
+{
+/**
+ * @brief The base class to work as a soft-based keyboard
+ *
+ * This class implements all functions for working as a soft-based keyboard
+ * In side of ISE developer, they can modify it by their requirements.
+ */
+class CSCLControllerMouse
+{
+private:
+    CSCLControllerMouse() {}
+public:
+    virtual ~CSCLControllerMouse() {}
+
+    static CSCLControllerMouse* get_instance();
+
+    sclboolean mouse_press(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+    sclboolean mouse_release(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+    sclboolean mouse_move(sclwindow window, sclint x, sclint y, scltouchdevice touch_id = 0, sclboolean actual_event = TRUE);
+    sclboolean mouse_over(sclwindow window, sclint x, sclint y);
+
+    SCLKeyModifier get_drag_key_modifier(sclint deltax, sclint deltay, sclfloat dist,
+        sclboolean check_farthest, scltouchdevice touch_id, sclbyte extra_option);
+
+};
+
+}
+
+//SCL_END_DECLS
+
+#endif //__SCL_CONTROLLER_MOUSE_H__
index 4492bc8..c9b6521 100644 (file)
@@ -18,6 +18,7 @@
 #include "sclevents-efl.h"
 #include "scldebug.h"
 #include "sclcontroller.h"
+#include "sclcontroller_mouse.h"
 #include "sclgraphics.h"
 #include "scluibuilder.h"
 #include "sclerroradjustment.h"
@@ -195,10 +196,10 @@ static void gesture_cb(void *data, const Eldbus_Message *msg)
         LOGD("Incoming message is empty");
         return;
     }
-    CSCLController *controller = CSCLController::get_instance();
+    CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     CSCLWindows *windows = CSCLWindows::get_instance();
 
-    if (!windows || !controller) return;
+    if (!windows || !controller_mouse) return;
 
     sclwindow base_window = windows->get_base_window();
     SclWindowContext *window_context = windows->get_window_context(base_window);
@@ -230,15 +231,15 @@ static void gesture_cb(void *data, const Eldbus_Message *msg)
             last_pos_x = info->x;
             last_pos_y = info->y - window_context->geometry.y;
             LOGD("hover last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
-            controller->mouse_over(base_window, last_pos_x, last_pos_y);
+            controller_mouse->mouse_over(base_window, last_pos_x, last_pos_y);
         }
     } else if (info->type == ONE_FINGER_DOUBLE_TAP) {
         if (info->y >= window_context->geometry.y) {
             last_pos_x = info->x;
             last_pos_y = info->y - window_context->geometry.y;
             LOGD("double last_pos_x=%d last_pos_y=%d", last_pos_x, last_pos_y);
-            controller->mouse_press(base_window, last_pos_x, last_pos_y);
-            controller->mouse_release(base_window, last_pos_x, last_pos_y);
+            controller_mouse->mouse_press(base_window, last_pos_x, last_pos_y);
+            controller_mouse->mouse_release(base_window, last_pos_x, last_pos_y);
         }
     }
     free(info);
@@ -410,7 +411,7 @@ static Eina_Bool mouse_press(void *data, int type, void *event_info)
     Ecore_Wl2_Window *wl_window;
 #endif
 
-    CSCLController *controller = CSCLController::get_instance();
+    CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     CSCLWindows *windows = CSCLWindows::get_instance();
     CSCLContext *context = CSCLContext::get_instance();
     CSCLUtils *utils = CSCLUtils::get_instance();
@@ -422,7 +423,7 @@ static Eina_Bool mouse_press(void *data, int type, void *event_info)
         return TRUE;
     }
 
-    if (controller && windows && context && utils && adjustment && ev) {
+    if (controller_mouse && windows && context && utils && adjustment && ev) {
         LOGD("mouse_press : %d %d, %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y,
                 g_timestamp_last_base_window_resized, ev->timestamp);
 
@@ -557,7 +558,7 @@ static Eina_Bool mouse_press(void *data, int type, void *event_info)
                             /* Now convert the global coordinate to appropriate local coordinate */
                             SclPoint coords = get_rotated_local_coords(
                                     root_x, root_y, context->get_rotation(), &rect);
-                            controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
+                            controller_mouse->mouse_press(window, coords.x, coords.y, ev->multi.device);
                             mouse_pressed = TRUE;
                             processed = TRUE;
                             pressed_window = window;
@@ -591,7 +592,7 @@ static Eina_Bool mouse_press(void *data, int type, void *event_info)
 #endif
 
                 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
-                controller->mouse_press(window, coords.x, coords.y, ev->multi.device);
+                controller_mouse->mouse_press(window, coords.x, coords.y, ev->multi.device);
                 mouse_pressed = TRUE;
                 processed = TRUE;
             }
@@ -601,7 +602,7 @@ static Eina_Bool mouse_press(void *data, int type, void *event_info)
     return TRUE;
 
     /*CSCLContext *context = CSCLContext::get_instance();
-    controller->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
+    controller_mouse->mouse_press((sclwindow)data, ev->output.x, ev->output.y);
     mouse_pressed = TRUE;*/
 
     //LOGD("=-=-=-=- mouse_press : %p %d %d\n", data, ev->output.x, ev->output.y);
@@ -612,7 +613,7 @@ static Eina_Bool mouse_release(void *data, int type, void *event_info)
 {
     SCL_DEBUG();
 
-    CSCLController *controller = CSCLController::get_instance();
+    CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     CSCLWindows *windows = CSCLWindows::get_instance();
     CSCLContext *context = CSCLContext::get_instance();
 
@@ -624,7 +625,7 @@ static Eina_Bool mouse_release(void *data, int type, void *event_info)
         return TRUE;
     }
 
-    if (controller && windows && context && ev) {
+    if (controller_mouse && windows && context && ev) {
         LOGD("mouse_release : %d %d, %d %d\n", ev->root.x, ev->root.y, ev->x, ev->y);
 
         sclbyte index = 0;
@@ -641,7 +642,7 @@ static Eina_Bool mouse_release(void *data, int type, void *event_info)
             }
         }
         if (dimwinevent) {
-            controller->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
+            controller_mouse->mouse_press(windows->get_dim_window(), ev->root.x, ev->root.y, ev->multi.device);
         } else {
             do {
                 window = windows->get_nth_window_in_Z_order_list(index);
@@ -709,7 +710,7 @@ static Eina_Bool mouse_release(void *data, int type, void *event_info)
                                 /* Now convert the global coordinate to appropriate local coordinate */
                                 SclPoint coords = get_rotated_local_coords(
                                         root_x, root_y, context->get_rotation(), &rect);
-                                controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
+                                controller_mouse->mouse_release(window, coords.x, coords.y, ev->multi.device);
                                 processed = TRUE;
                             }
                         }
@@ -742,7 +743,7 @@ static Eina_Bool mouse_release(void *data, int type, void *event_info)
 #endif
 
                 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
-                controller->mouse_release(window, coords.x, coords.y, ev->multi.device);
+                controller_mouse->mouse_release(window, coords.x, coords.y, ev->multi.device);
                 processed = TRUE;
             }
         }
@@ -751,17 +752,17 @@ static Eina_Bool mouse_release(void *data, int type, void *event_info)
     }
 
     return TRUE;
-    //CSCLController *controller = CSCLController::get_instance();
+    //CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     //CSCLWindows *windows = CSCLWindows::get_instance();
-    //controller->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
-    //controller->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
+    //controller_mouse->mouse_release((sclwindow)data, (int)ev->output.x, (int)ev->output.y);
+    //controller_mouse->mouse_release((sclwindow)data, (int)ev->x, (int)ev->y);
 }
 
 #ifdef HANDLE_KEY_EVENTS
 static Eina_Bool key_pressed(void *data, int type, void *event_info)
 {
     LOGD("=-=-=-=- key_pressed \n");
-    CSCLController *controller = CSCLController::get_instance();
+    CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     Ecore_Event_Key *ev = (Ecore_Event_Key *)event_info;
     const char *ckey_val = ev->key;
     LOGD("=-=-=-=- ev->key(char) = %c \n", ev->key);
@@ -796,8 +797,8 @@ static Eina_Bool key_pressed(void *data, int type, void *event_info)
         button_context = cache->get_cur_button_context(window, current_key_index);
         coordinate = cache->get_cur_layout_key_coordinate(window, current_key_index);
         button_context->state = BUTTON_STATE_NORMAL;
-        controller->mouse_press(window, coordinate->x, coordinate->y, TRUE);
-        controller->mouse_release(window, coordinate->x, coordinate->y, TRUE);
+        controller_mouse->mouse_press(window, coordinate->x, coordinate->y, TRUE);
+        controller_mouse->mouse_release(window, coordinate->x, coordinate->y, TRUE);
         if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
             button_context->state = BUTTON_STATE_PRESSED;
             windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
@@ -852,7 +853,7 @@ static Eina_Bool mouse_move(void *data, int type, void *event_info)
 {
     SCL_DEBUG();
 
-    CSCLController *controller = CSCLController::get_instance();
+    CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     CSCLWindows *windows = CSCLWindows::get_instance();
     CSCLContext *context = CSCLContext::get_instance();
     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
@@ -865,7 +866,7 @@ static Eina_Bool mouse_move(void *data, int type, void *event_info)
         return TRUE;
     }
 
-    if (controller && windows && context && cache && ev) {
+    if (controller_mouse && windows && context && cache && ev) {
         sclbyte index = 0;
         sclboolean processed = FALSE;
         sclwindow window = SCLWINDOW_INVALID;
@@ -912,7 +913,7 @@ static Eina_Bool mouse_move(void *data, int type, void *event_info)
 
             SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
 
-            controller->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
+            controller_mouse->mouse_move(context->get_cur_pressed_window(ev->multi.device), coords.x, coords.y, ev->multi.device);
             processed = TRUE;
         } else {
             do {
@@ -975,7 +976,7 @@ static Eina_Bool mouse_move(void *data, int type, void *event_info)
                                 /* Now convert the global coordinate to appropriate local coordinate */
                                 SclPoint coords = get_rotated_local_coords(
                                         root_x, root_y, context->get_rotation(), &rect);
-                                controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
+                                controller_mouse->mouse_move(window, coords.x, coords.y, ev->multi.device);
                                 processed = TRUE;
                             }
                         }
@@ -1002,22 +1003,22 @@ static Eina_Bool mouse_move(void *data, int type, void *event_info)
 #endif
 
                 SclPoint coords = get_rotated_local_coords(root_x, root_y, context->get_rotation(), &rect);
-                controller->mouse_move(window, coords.x, coords.y, ev->multi.device);
+                controller_mouse->mouse_move(window, coords.x, coords.y, ev->multi.device);
                 processed = TRUE;
             }
         }
     }
-    //CSCLController *controller = CSCLController::get_instance();
+    //CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     //CSCLWindows *windows = CSCLWindows::get_instance();
-    //controller->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
-    //controller->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
+    //controller_mouse->mouse_move((sclwindow)data, (int)ev->cur.output.x, (int)ev->cur.output.y);
+    //controller_mouse->mouse_move((sclwindow)data, (int)ev->x, (int)ev->y);
 
     return TRUE;
 }
 
 /**
  * Registers a event callback func to given window.
- * In this function, it should call several event functions of CSCLController class whenever an event has occurred
+ * In this function, it should call several event functions of CSCLControllerMouse class whenever an event has occurred
  * The below list shows what event function should be called.
  * - mouse_press (when the user presses mouse button)
  * - mouse_release (when the user releases mouse button)
@@ -1041,26 +1042,26 @@ client_message_cb(void *data, int type, void *event)
     Ecore_X_Event_Client_Message *ev = (Ecore_X_Event_Client_Message *)event;
     if (ev->message_type == ECORE_X_ATOM_E_ILLUME_ACCESS_CONTROL) {
         CSCLWindows *windows = CSCLWindows::get_instance();
-        CSCLController *controller = CSCLController::get_instance();
+        CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
 
         static int last_pos_x = -10000;
         static int last_pos_y = -10000;
 
-        if (windows && controller) {
+        if (windows && controller_mouse) {
             Evas_Object *base_win = (Evas_Object *)windows->get_base_window();
             if (base_win == NULL) return FALSE;
 
             if ((unsigned int)ev->data.l[0] == elm_win_xwindow_get(base_win)) {
                 if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_ACTIVATE) {
                 // 1 finger double tap
-                controller->mouse_press(base_win, last_pos_x, last_pos_y);
-                controller->mouse_release(base_win, last_pos_x, last_pos_y);
+                controller_mouse->mouse_press(base_win, last_pos_x, last_pos_y);
+                controller_mouse->mouse_release(base_win, last_pos_x, last_pos_y);
                 } else if ((unsigned int)ev->data.l[1] == ECORE_X_ATOM_E_ILLUME_ACCESS_ACTION_READ) {
                     // 1 finger tap
                     // 1 finger touch & move
                     last_pos_x = ev->data.l[2];
                     last_pos_y = ev->data.l[3];
-                    controller->mouse_over(base_win, last_pos_x, last_pos_y);
+                    controller_mouse->mouse_over(base_win, last_pos_x, last_pos_y);
                 }
             }
         }
index 2183f2b..276d2f0 100644 (file)
@@ -26,7 +26,7 @@
 #include "scldebug.h"
 #include "sclwindows.h"
 
-#include "sclcontroller.h"
+#include "sclcontroller_mouse.h"
 #include "sclresourcecache.h"
 #include "sclkeyfocushandler.h"
 #include <dlog.h>
@@ -123,7 +123,7 @@ CSCLEvents::process_key_event(const char *key)
 
     const char *keyname = key;
     LOGD("=-=-=-=- key_pressed \n");
-    CSCLController *controller = CSCLController::get_instance();
+    CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
     LOGD("=-=-=-=- keyname(char) = %s \n", keyname);
 
     CSCLResourceCache *cache = CSCLResourceCache::get_instance();
@@ -133,7 +133,7 @@ CSCLEvents::process_key_event(const char *key)
     CSCLWindows *windows = CSCLWindows::get_instance();
     CSCLKeyFocusHandler* focus_handler = CSCLKeyFocusHandler::get_instance();
 
-    if (!windows || !focus_handler || !cache || !controller) return FALSE;
+    if (!windows || !focus_handler || !cache || !controller_mouse) return FALSE;
 
     sclwindow current_focus_window = focus_handler->get_current_focus_window();
     scl8 current_key_index = focus_handler->get_current_focus_key();
@@ -164,9 +164,9 @@ CSCLEvents::process_key_event(const char *key)
         if (cache)
             coordinate = cache->get_cur_layout_key_coordinate(current_focus_window, current_key_index);
         //button_context->state = BUTTON_STATE_NORMAL;
-        if (coordinate && controller) {
-            controller->mouse_press(current_focus_window, coordinate->x, coordinate->y, TRUE);
-            controller->mouse_release(current_focus_window, coordinate->x, coordinate->y, TRUE);
+        if (coordinate && controller_mouse) {
+            controller_mouse->mouse_press(current_focus_window, coordinate->x, coordinate->y, TRUE);
+            controller_mouse->mouse_release(current_focus_window, coordinate->x, coordinate->y, TRUE);
             if (KEY_TYPE_MODECHANGE != coordinate->key_type) {
                 //button_context->state = BUTTON_STATE_PRESSED;
                 //windows->update_window(window, coordinate->x, coordinate->y, coordinate->width, coordinate->height);
index 8f5c79d..683c748 100644 (file)
@@ -27,6 +27,7 @@
 #include "sclevents.h"
 #include "sclresourcecache.h"
 #include "sclcontroller.h"
+#include "sclcontroller_mouse.h"
 #include "sclactionstate.h"
 #include "sclres_manager.h"
 #include "sclkeyfocushandler.h"
@@ -254,7 +255,8 @@ sclwindow CSCLWindows::open_popup(const SclWindowOpener opener, const SclRectang
                             cur_layout->mouse_manipulate_x;
                         sclint y = popup_coordinate->y + (popup_coordinate->height / 2) -
                             cur_layout->mouse_manipulate_y;
-                        controller->mouse_press(window, x, y, context->get_last_touch_device_id());
+                        CSCLControllerMouse *controller_mouse = CSCLControllerMouse::get_instance();
+                        controller_mouse->mouse_press(window, x, y, context->get_last_touch_device_id());
                     }
                 }