diff options
Diffstat (limited to 'Tools/DumpRenderTree/efl/EventSender.cpp')
-rw-r--r-- | Tools/DumpRenderTree/efl/EventSender.cpp | 1035 |
1 files changed, 0 insertions, 1035 deletions
diff --git a/Tools/DumpRenderTree/efl/EventSender.cpp b/Tools/DumpRenderTree/efl/EventSender.cpp deleted file mode 100644 index 92b788991..000000000 --- a/Tools/DumpRenderTree/efl/EventSender.cpp +++ /dev/null @@ -1,1035 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Zan Dobersek <zandobersek@gmail.com> - * Copyright (C) 2009 Holger Hans Peter Freyther - * Copyright (C) 2010 Igalia S.L. - * Copyright (C) 2011 ProFUSION Embedded Systems - * Copyright (C) 2011, 2012 Samsung Electronics - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "EventSender.h" - -#include "DumpRenderTree.h" -#include "DumpRenderTreeChrome.h" -#include "IntPoint.h" -#include "JSStringUtils.h" -#include "NotImplemented.h" -#include "PlatformEvent.h" -#include "WebCoreSupport/DumpRenderTreeSupportEfl.h" -#include "ewk_private.h" -#include <EWebKit.h> -#include <Ecore_Input.h> -#include <JavaScriptCore/JSObjectRef.h> -#include <JavaScriptCore/JSRetainPtr.h> -#include <JavaScriptCore/JSStringRef.h> -#include <JavaScriptCore/OpaqueJSString.h> -#include <wtf/ASCIICType.h> -#include <wtf/Platform.h> -#include <wtf/text/CString.h> - -static bool gDragMode; -static int gTimeOffset = 0; - -static int gLastMousePositionX; -static int gLastMousePositionY; -static int gLastClickPositionX; -static int gLastClickPositionY; -static int gLastClickTimeOffset; -static int gLastClickButton; -static int gButtonCurrentlyDown; -static int gClickCount; - -static const float zoomMultiplierRatio = 1.2f; - -// Key event location code defined in DOM Level 3. -enum KeyLocationCode { - DomKeyLocationStandard, - DomKeyLocationLeft, - DomKeyLocationRight, - DomKeyLocationNumpad -}; - -enum EvasKeyModifier { - EvasKeyModifierNone = 0, - EvasKeyModifierControl = 1 << 0, - EvasKeyModifierShift = 1 << 1, - EvasKeyModifierAlt = 1 << 2, - EvasKeyModifierMeta = 1 << 3 -}; - -enum EvasMouseButton { - EvasMouseButtonNone, - EvasMouseButtonLeft, - EvasMouseButtonMiddle, - EvasMouseButtonRight -}; - -enum EvasMouseEvent { - EvasMouseEventNone = 0, - EvasMouseEventDown = 1 << 0, - EvasMouseEventUp = 1 << 1, - EvasMouseEventMove = 1 << 2, - EvasMouseEventScrollUp = 1 << 3, - EvasMouseEventScrollDown = 1 << 4, - EvasMouseEventScrollLeft = 1 << 5, - EvasMouseEventScrollRight = 1 << 6, - EvasMouseEventClick = EvasMouseEventMove | EvasMouseEventDown | EvasMouseEventUp, -}; - -enum ZoomEvent { - ZoomIn, - ZoomOut -}; - -enum EventQueueStrategy { - FeedQueuedEvents, - DoNotFeedQueuedEvents -}; - -struct KeyEventInfo { - KeyEventInfo(const CString& keyName, unsigned modifiers, const CString& keyString = CString()) - : keyName(keyName) - , keyString(keyString) - , modifiers(modifiers) - { - } - - const CString keyName; - const CString keyString; - unsigned modifiers; -}; - -struct MouseEventInfo { - MouseEventInfo(EvasMouseEvent event, unsigned modifiers = EvasKeyModifierNone, EvasMouseButton button = EvasMouseButtonNone, int horizontalDelta = 0, int verticalDelta = 0) - : event(event) - , modifiers(modifiers) - , button(button) - , horizontalDelta(horizontalDelta) - , verticalDelta(verticalDelta) - { - } - - EvasMouseEvent event; - unsigned modifiers; - EvasMouseButton button; - int horizontalDelta; - int verticalDelta; -}; - -struct DelayedEvent { - DelayedEvent(MouseEventInfo* eventInfo, unsigned long delay = 0) - : eventInfo(eventInfo) - , delay(delay) - { - } - - MouseEventInfo* eventInfo; - unsigned long delay; -}; - -struct TouchEventInfo { - TouchEventInfo(unsigned id, Ewk_Touch_Point_Type state, const WebCore::IntPoint& point) - : state(state) - , point(point) - , id(id) - { - } - - unsigned id; - Ewk_Touch_Point_Type state; - WebCore::IntPoint point; -}; - -static unsigned touchModifiers; - -WTF::Vector<TouchEventInfo>& touchPointList() -{ - DEFINE_STATIC_LOCAL(WTF::Vector<TouchEventInfo>, staticTouchPointList, ()); - return staticTouchPointList; -} - -WTF::Vector<DelayedEvent>& delayedEventQueue() -{ - DEFINE_STATIC_LOCAL(WTF::Vector<DelayedEvent>, staticDelayedEventQueue, ()); - return staticDelayedEventQueue; -} - - -static void feedOrQueueMouseEvent(MouseEventInfo*, EventQueueStrategy); -static void feedMouseEvent(MouseEventInfo*); -static void feedQueuedMouseEvents(); - -static void setEvasModifiers(Evas* evas, unsigned modifiers) -{ - static const char* modifierNames[] = { "Control", "Shift", "Alt", "Super" }; - for (unsigned modifier = 0; modifier < 4; ++modifier) { - if (modifiers & (1 << modifier)) - evas_key_modifier_on(evas, modifierNames[modifier]); - else - evas_key_modifier_off(evas, modifierNames[modifier]); - } -} - -static EvasMouseButton translateMouseButtonNumber(int eventSenderButtonNumber) -{ - static const EvasMouseButton translationTable[] = { - EvasMouseButtonLeft, - EvasMouseButtonMiddle, - EvasMouseButtonRight, - EvasMouseButtonMiddle // fast/events/mouse-click-events expects the 4th button to be treated as the middle button - }; - static const unsigned translationTableSize = sizeof(translationTable) / sizeof(translationTable[0]); - - if (eventSenderButtonNumber < translationTableSize) - return translationTable[eventSenderButtonNumber]; - - return EvasMouseButtonLeft; -} - -static Eina_Bool sendClick(void*) -{ - MouseEventInfo* eventInfo = new MouseEventInfo(EvasMouseEventClick, EvasKeyModifierNone, EvasMouseButtonLeft); - feedOrQueueMouseEvent(eventInfo, FeedQueuedEvents); - return ECORE_CALLBACK_CANCEL; -} - -static JSValueRef scheduleAsynchronousClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - ecore_idler_add(sendClick, 0); - return JSValueMakeUndefined(context); -} - -static void updateClickCount(int button) -{ - if (gLastClickPositionX != gLastMousePositionX - || gLastClickPositionY != gLastMousePositionY - || gLastClickButton != button - || gTimeOffset - gLastClickTimeOffset >= 1) - gClickCount = 1; - else - gClickCount++; -} - -static EvasKeyModifier modifierFromJSValue(JSContextRef context, const JSValueRef value) -{ - JSRetainPtr<JSStringRef> jsKeyValue(Adopt, JSValueToStringCopy(context, value, 0)); - - if (equals(jsKeyValue, "ctrlKey") || equals(jsKeyValue, "addSelectionKey")) - return EvasKeyModifierControl; - if (equals(jsKeyValue, "shiftKey") || equals(jsKeyValue, "rangeSelectionKey")) - return EvasKeyModifierShift; - if (equals(jsKeyValue, "altKey")) - return EvasKeyModifierAlt; - if (equals(jsKeyValue, "metaKey")) - return EvasKeyModifierMeta; - - return EvasKeyModifierNone; -} - -static unsigned modifiersFromJSValue(JSContextRef context, const JSValueRef modifiers) -{ - // The value may either be a string with a single modifier or an array of modifiers. - if (JSValueIsString(context, modifiers)) - return modifierFromJSValue(context, modifiers); - - JSObjectRef modifiersArray = JSValueToObject(context, modifiers, 0); - if (!modifiersArray) - return EvasKeyModifierNone; - - unsigned modifier = EvasKeyModifierNone; - JSRetainPtr<JSStringRef> lengthProperty(Adopt, JSStringCreateWithUTF8CString("length")); - int modifiersCount = JSValueToNumber(context, JSObjectGetProperty(context, modifiersArray, lengthProperty.get(), 0), 0); - for (int i = 0; i < modifiersCount; ++i) - modifier |= modifierFromJSValue(context, JSObjectGetPropertyAtIndex(context, modifiersArray, i, 0)); - return modifier; -} - -static JSValueRef getMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) -{ - Ewk_Context_Menu_Item* item = static_cast<Ewk_Context_Menu_Item*>(JSObjectGetPrivate(object)); - CString label; - if (ewk_context_menu_item_type_get(item) == EWK_SEPARATOR_TYPE) - label = "<separator>"; - else - label = ewk_context_menu_item_title_get(item); - - return JSValueMakeString(context, JSStringCreateWithUTF8CString(label.data())); -} - -static bool setMenuItemTitleCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - return true; -} - -static JSValueRef menuItemClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - Ewk_Context_Menu_Item* item = static_cast<Ewk_Context_Menu_Item*>(JSObjectGetPrivate(thisObject)); - ewk_context_menu_item_select(ewk_context_menu_item_parent_get(item), item); - return JSValueMakeUndefined(context); -} - -static JSStaticFunction staticMenuItemFunctions[] = { - { "click", menuItemClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { 0, 0, 0 } -}; - -static JSStaticValue staticMenuItemValues[] = { - { "title", getMenuItemTitleCallback, setMenuItemTitleCallback, kJSPropertyAttributeNone }, - { 0, 0, 0, 0 } -}; - -static JSClassRef getMenuItemClass() -{ - static JSClassRef menuItemClass = 0; - - if (!menuItemClass) { - JSClassDefinition classDefinition = { - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - classDefinition.staticFunctions = staticMenuItemFunctions; - classDefinition.staticValues = staticMenuItemValues; - - menuItemClass = JSClassCreate(&classDefinition); - } - - return menuItemClass; -} - -static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - Evas_Object* view = ewk_frame_view_get(browser->mainFrame()); - if (!view) - return JSValueMakeUndefined(context); - - Evas* evas = evas_object_evas_get(view); - if (!evas) - return JSValueMakeUndefined(context); - - Evas_Event_Mouse_Down mouseDown; - mouseDown.button = 3; - mouseDown.output.x = gLastMousePositionX; - mouseDown.output.y = gLastMousePositionY; - mouseDown.canvas.x = gLastMousePositionX; - mouseDown.canvas.y = gLastMousePositionY; - mouseDown.data = 0; - mouseDown.modifiers = const_cast<Evas_Modifier*>(evas_key_modifier_get(evas)); - mouseDown.locks = const_cast<Evas_Lock*>(evas_key_lock_get(evas)); - mouseDown.flags = EVAS_BUTTON_NONE; - mouseDown.timestamp = ecore_loop_time_get(); - mouseDown.event_flags = EVAS_EVENT_FLAG_NONE; - mouseDown.dev = 0; - - ewk_view_context_menu_forward_event(view, &mouseDown); - Ewk_Context_Menu* ewkMenu = ewk_view_context_menu_get(view); - - JSValueRef valueRef = JSObjectMakeArray(context, 0, 0, 0); - if (ewkMenu) { - const Eina_List* ewkMenuItems = ewk_context_menu_item_list_get(ewkMenu); - JSValueRef arrayValues[eina_list_count(ewkMenuItems)]; - - const Eina_List* listIterator; - void* data; - int index = 0; - EINA_LIST_FOREACH(ewkMenuItems, listIterator, data) - arrayValues[index++] = JSObjectMake(context, getMenuItemClass(), data); - - if (index) - valueRef = JSObjectMakeArray(context, index - 1, arrayValues, 0); - } - - return valueRef; -} - -static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - int button = 0; - if (argumentCount == 1) { - button = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); - - if (exception && *exception) - return JSValueMakeUndefined(context); - } - - button = translateMouseButtonNumber(button); - // If the same mouse button is already in the down position don't send another event as it may confuse Xvfb. - if (gButtonCurrentlyDown == button) - return JSValueMakeUndefined(context); - - updateClickCount(button); - - unsigned modifiers = argumentCount >= 2 ? modifiersFromJSValue(context, arguments[1]) : EvasKeyModifierNone; - MouseEventInfo* eventInfo = new MouseEventInfo(EvasMouseEventDown, modifiers, static_cast<EvasMouseButton>(button)); - feedOrQueueMouseEvent(eventInfo, FeedQueuedEvents); - gButtonCurrentlyDown = button; - return JSValueMakeUndefined(context); -} - -static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - int button = 0; - if (argumentCount == 1) { - button = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); - if (exception && *exception) - return JSValueMakeUndefined(context); - } - - gLastClickPositionX = gLastMousePositionX; - gLastClickPositionY = gLastMousePositionY; - gLastClickButton = gButtonCurrentlyDown; - gLastClickTimeOffset = gTimeOffset; - gButtonCurrentlyDown = 0; - - unsigned modifiers = argumentCount >= 2 ? modifiersFromJSValue(context, arguments[1]) : EvasKeyModifierNone; - MouseEventInfo* eventInfo = new MouseEventInfo(EvasMouseEventUp, modifiers, translateMouseButtonNumber(button)); - feedOrQueueMouseEvent(eventInfo, FeedQueuedEvents); - return JSValueMakeUndefined(context); -} - -static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount < 2) - return JSValueMakeUndefined(context); - - gLastMousePositionX = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); - if (exception && *exception) - return JSValueMakeUndefined(context); - gLastMousePositionY = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); - if (exception && *exception) - return JSValueMakeUndefined(context); - - MouseEventInfo* eventInfo = new MouseEventInfo(EvasMouseEventMove); - feedOrQueueMouseEvent(eventInfo, DoNotFeedQueuedEvents); - return JSValueMakeUndefined(context); -} - -static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount > 0) { - const unsigned long leapForwardDelay = JSValueToNumber(context, arguments[0], exception); - if (delayedEventQueue().isEmpty()) - delayedEventQueue().append(DelayedEvent(0, leapForwardDelay)); - else - delayedEventQueue().last().delay = leapForwardDelay; - gTimeOffset += leapForwardDelay; - } - - return JSValueMakeUndefined(context); -} - -static EvasMouseEvent evasMouseEventFromHorizontalAndVerticalOffsets(int horizontalOffset, int verticalOffset) -{ - unsigned mouseEvent = 0; - - if (verticalOffset > 0) - mouseEvent |= EvasMouseEventScrollUp; - else if (verticalOffset < 0) - mouseEvent |= EvasMouseEventScrollDown; - - if (horizontalOffset > 0) - mouseEvent |= EvasMouseEventScrollRight; - else if (horizontalOffset < 0) - mouseEvent |= EvasMouseEventScrollLeft; - - return static_cast<EvasMouseEvent>(mouseEvent); -} - -static JSValueRef mouseScrollByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount < 2) - return JSValueMakeUndefined(context); - - // We need to invert scrolling values since in EFL negative z value means that - // canvas is scrolling down - const int horizontal = -(static_cast<int>(JSValueToNumber(context, arguments[0], exception))); - if (exception && *exception) - return JSValueMakeUndefined(context); - const int vertical = -(static_cast<int>(JSValueToNumber(context, arguments[1], exception))); - if (exception && *exception) - return JSValueMakeUndefined(context); - - MouseEventInfo* eventInfo = new MouseEventInfo(evasMouseEventFromHorizontalAndVerticalOffsets(horizontal, vertical), EvasKeyModifierNone, EvasMouseButtonNone, horizontal, vertical); - feedOrQueueMouseEvent(eventInfo, FeedQueuedEvents); - return JSValueMakeUndefined(context); -} - -static JSValueRef continuousMouseScrollByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - return JSValueMakeUndefined(context); -} - -static KeyEventInfo* keyPadNameFromJSValue(JSStringRef character, unsigned modifiers) -{ - if (equals(character, "leftArrow")) - return new KeyEventInfo("KP_Left", modifiers); - if (equals(character, "rightArrow")) - return new KeyEventInfo("KP_Right", modifiers); - if (equals(character, "upArrow")) - return new KeyEventInfo("KP_Up", modifiers); - if (equals(character, "downArrow")) - return new KeyEventInfo("KP_Down", modifiers); - if (equals(character, "pageUp")) - return new KeyEventInfo("KP_Prior", modifiers); - if (equals(character, "pageDown")) - return new KeyEventInfo("KP_Next", modifiers); - if (equals(character, "home")) - return new KeyEventInfo("KP_Home", modifiers); - if (equals(character, "end")) - return new KeyEventInfo("KP_End", modifiers); - if (equals(character, "insert")) - return new KeyEventInfo("KP_Insert", modifiers); - if (equals(character, "delete")) - return new KeyEventInfo("KP_Delete", modifiers); - - return new KeyEventInfo(character->string().utf8(), modifiers, character->string().utf8()); -} - -static KeyEventInfo* keyNameFromJSValue(JSStringRef character, unsigned modifiers) -{ - if (equals(character, "leftArrow")) - return new KeyEventInfo("Left", modifiers); - if (equals(character, "rightArrow")) - return new KeyEventInfo("Right", modifiers); - if (equals(character, "upArrow")) - return new KeyEventInfo("Up", modifiers); - if (equals(character, "downArrow")) - return new KeyEventInfo("Down", modifiers); - if (equals(character, "pageUp")) - return new KeyEventInfo("Prior", modifiers); - if (equals(character, "pageDown")) - return new KeyEventInfo("Next", modifiers); - if (equals(character, "home")) - return new KeyEventInfo("Home", modifiers); - if (equals(character, "end")) - return new KeyEventInfo("End", modifiers); - if (equals(character, "insert")) - return new KeyEventInfo("Insert", modifiers); - if (equals(character, "delete")) - return new KeyEventInfo("Delete", modifiers); - if (equals(character, "printScreen")) - return new KeyEventInfo("Print", modifiers); - if (equals(character, "menu")) - return new KeyEventInfo("Menu", modifiers); - if (equals(character, "leftControl")) - return new KeyEventInfo("Control_L", modifiers); - if (equals(character, "rightControl")) - return new KeyEventInfo("Control_R", modifiers); - if (equals(character, "leftShift")) - return new KeyEventInfo("Shift_L", modifiers); - if (equals(character, "rightShift")) - return new KeyEventInfo("Shift_R", modifiers); - if (equals(character, "leftAlt")) - return new KeyEventInfo("Alt_L", modifiers); - if (equals(character, "rightAlt")) - return new KeyEventInfo("Alt_R", modifiers); - if (equals(character, "F1")) - return new KeyEventInfo("F1", modifiers); - if (equals(character, "F2")) - return new KeyEventInfo("F2", modifiers); - if (equals(character, "F3")) - return new KeyEventInfo("F3", modifiers); - if (equals(character, "F4")) - return new KeyEventInfo("F4", modifiers); - if (equals(character, "F5")) - return new KeyEventInfo("F5", modifiers); - if (equals(character, "F6")) - return new KeyEventInfo("F6", modifiers); - if (equals(character, "F7")) - return new KeyEventInfo("F7", modifiers); - if (equals(character, "F8")) - return new KeyEventInfo("F8", modifiers); - if (equals(character, "F9")) - return new KeyEventInfo("F9", modifiers); - if (equals(character, "F10")) - return new KeyEventInfo("F10", modifiers); - if (equals(character, "F11")) - return new KeyEventInfo("F11", modifiers); - if (equals(character, "F12")) - return new KeyEventInfo("F12", modifiers); - - int charCode = JSStringGetCharactersPtr(character)[0]; - if (charCode == '\n' || charCode == '\r') - return new KeyEventInfo("Return", modifiers, "\r"); - if (charCode == '\t') - return new KeyEventInfo("Tab", modifiers, "\t"); - if (charCode == '\x8') - return new KeyEventInfo("BackSpace", modifiers, "\x8"); - if (charCode == ' ') - return new KeyEventInfo("space", modifiers, " "); - if (charCode == '\x1B') - return new KeyEventInfo("Escape", modifiers, "\x1B"); - - if ((character->length() == 1) && (charCode >= 'A' && charCode <= 'Z')) - modifiers |= EvasKeyModifierShift; - - return new KeyEventInfo(character->string().utf8(), modifiers, character->string().utf8()); -} - -static KeyEventInfo* createKeyEventInfo(JSContextRef context, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (!ewk_frame_view_get(browser->mainFrame())) - return 0; - - if (argumentCount < 1) - return 0; - - // handle location argument. - int location = DomKeyLocationStandard; - if (argumentCount > 2) - location = static_cast<int>(JSValueToNumber(context, arguments[2], exception)); - - JSRetainPtr<JSStringRef> character(Adopt, JSValueToStringCopy(context, arguments[0], exception)); - if (exception && *exception) - return 0; - - unsigned modifiers = EvasKeyModifierNone; - if (argumentCount >= 2) - modifiers = modifiersFromJSValue(context, arguments[1]); - - return (location == DomKeyLocationNumpad) ? keyPadNameFromJSValue(character.get(), modifiers) : keyNameFromJSValue(character.get(), modifiers); -} - -static void sendKeyDown(Evas* evas, KeyEventInfo* keyEventInfo) -{ - if (!keyEventInfo) - return; - - const char* keyName = keyEventInfo->keyName.data(); - const char* keyString = keyEventInfo->keyString.data(); - unsigned modifiers = keyEventInfo->modifiers; - - DumpRenderTreeSupportEfl::layoutFrame(browser->mainFrame()); - - ASSERT(evas); - - int eventIndex = 0; - // Mimic the emacs ctrl-o binding by inserting a paragraph - // separator and then putting the cursor back to its original - // position. Allows us to pass emacs-ctrl-o.html - if ((modifiers & EvasKeyModifierControl) && !strcmp(keyName, "o")) { - setEvasModifiers(evas, EvasKeyModifierNone); - evas_event_feed_key_down(evas, "Return", "Return", "\r", 0, eventIndex++, 0); - evas_event_feed_key_up(evas, "Return", "Return", "\r", 0, eventIndex++, 0); - - modifiers = EvasKeyModifierNone; - keyName = "Left"; - keyString = 0; - } - - setEvasModifiers(evas, modifiers); - evas_event_feed_key_down(evas, keyName, keyName, keyString, 0, eventIndex++, 0); - evas_event_feed_key_up(evas, keyName, keyName, keyString, 0, eventIndex++, 0); - setEvasModifiers(evas, EvasKeyModifierNone); - - DumpRenderTreeSupportEfl::deliverAllMutationsIfNecessary(); -} - -static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - OwnPtr<KeyEventInfo> keyEventInfo = adoptPtr(createKeyEventInfo(context, argumentCount, arguments, exception)); - sendKeyDown(evas_object_evas_get(browser->mainFrame()), keyEventInfo.get()); - - return JSValueMakeUndefined(context); -} - -static JSValueRef scalePageByCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount < 3) - return JSValueMakeUndefined(context); - - Evas_Object* view = ewk_frame_view_get(browser->mainFrame()); - if (!view) - return JSValueMakeUndefined(context); - - float scaleFactor = JSValueToNumber(context, arguments[0], exception); - float x = JSValueToNumber(context, arguments[1], exception); - float y = JSValueToNumber(context, arguments[2], exception); - ewk_view_scale_set(view, scaleFactor, x, y); - - return JSValueMakeUndefined(context); -} - -static void textZoom(ZoomEvent zoomEvent) -{ - Evas_Object* view = ewk_frame_view_get(browser->mainFrame()); - if (!view) - return; - - float zoomFactor = ewk_view_text_zoom_get(view); - if (zoomEvent == ZoomIn) - zoomFactor *= zoomMultiplierRatio; - else - zoomFactor /= zoomMultiplierRatio; - - ewk_view_text_zoom_set(view, zoomFactor); -} - -static void pageZoom(ZoomEvent zoomEvent) -{ - Evas_Object* view = ewk_frame_view_get(browser->mainFrame()); - if (!view) - return; - - float zoomFactor = ewk_view_page_zoom_get(view); - if (zoomEvent == ZoomIn) - zoomFactor *= zoomMultiplierRatio; - else - zoomFactor /= zoomMultiplierRatio; - - ewk_view_page_zoom_set(view, zoomFactor); -} - -static JSValueRef textZoomInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - textZoom(ZoomIn); - return JSValueMakeUndefined(context); -} - -static JSValueRef textZoomOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - textZoom(ZoomOut); - return JSValueMakeUndefined(context); -} - -static JSValueRef zoomPageInCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - pageZoom(ZoomIn); - return JSValueMakeUndefined(context); -} - -static JSValueRef zoomPageOutCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - pageZoom(ZoomOut); - return JSValueMakeUndefined(context); -} - -static Eina_Bool sendAsynchronousKeyDown(void* userData) -{ - OwnPtr<KeyEventInfo> keyEventInfo = adoptPtr(static_cast<KeyEventInfo*>(userData)); - sendKeyDown(evas_object_evas_get(browser->mainFrame()), keyEventInfo.get()); - return ECORE_CALLBACK_CANCEL; -} - -static JSValueRef scheduleAsynchronousKeyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - KeyEventInfo* keyEventInfo = createKeyEventInfo(context, argumentCount, arguments, exception); - ecore_idler_add(sendAsynchronousKeyDown, static_cast<void*>(keyEventInfo)); - return JSValueMakeUndefined(context); -} - -static void sendTouchEvent(Ewk_Touch_Event_Type type) -{ - Eina_List* eventList = 0; - - for (unsigned i = 0; i < touchPointList().size(); ++i) { - Ewk_Touch_Point* event = new Ewk_Touch_Point; - WebCore::IntPoint point = touchPointList().at(i).point; - event->id = touchPointList().at(i).id; - event->x = point.x(); - event->y = point.y(); - event->state = touchPointList().at(i).state; - eventList = eina_list_append(eventList, event); - } - - ewk_frame_feed_touch_event(browser->mainFrame(), type, eventList, touchModifiers); - - void* listData; - EINA_LIST_FREE(eventList, listData) { - Ewk_Touch_Point* event = static_cast<Ewk_Touch_Point*>(listData); - delete event; - } - - for (unsigned i = 0; i < touchPointList().size(); ) { - if (touchPointList().at(i).state == EWK_TOUCH_POINT_RELEASED) - touchPointList().remove(i); - else { - touchPointList().at(i).state = EWK_TOUCH_POINT_STATIONARY; - ++i; - } - } -} - -static JSValueRef addTouchPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount != 2) - return JSValueMakeUndefined(context); - - int x = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); - ASSERT(!exception || !*exception); - int y = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); - ASSERT(!exception || !*exception); - - const WebCore::IntPoint point(x, y); - const unsigned id = touchPointList().isEmpty() ? 0 : touchPointList().last().id + 1; - TouchEventInfo eventInfo(id, EWK_TOUCH_POINT_PRESSED, point); - touchPointList().append(eventInfo); - - return JSValueMakeUndefined(context); -} - -static JSValueRef touchStartCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - sendTouchEvent(EWK_TOUCH_START); - return JSValueMakeUndefined(context); -} - -static JSValueRef updateTouchPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount != 3) - return JSValueMakeUndefined(context); - - int index = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); - ASSERT(!exception || !*exception); - int x = static_cast<int>(JSValueToNumber(context, arguments[1], exception)); - ASSERT(!exception || !*exception); - int y = static_cast<int>(JSValueToNumber(context, arguments[2], exception)); - ASSERT(!exception || !*exception); - - if (index < 0 || index >= touchPointList().size()) - return JSValueMakeUndefined(context); - - WebCore::IntPoint& point = touchPointList().at(index).point; - point.setX(x); - point.setY(y); - touchPointList().at(index).state = EWK_TOUCH_POINT_MOVED; - - return JSValueMakeUndefined(context); -} - -static JSValueRef touchMoveCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - sendTouchEvent(EWK_TOUCH_MOVE); - return JSValueMakeUndefined(context); -} - -static JSValueRef cancelTouchPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount != 1) - return JSValueMakeUndefined(context); - - int index = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); - ASSERT(!exception || !*exception); - if (index < 0 || index >= touchPointList().size()) - return JSValueMakeUndefined(context); - - touchPointList().at(index).state = EWK_TOUCH_POINT_CANCELLED; - return JSValueMakeUndefined(context); -} - -static JSValueRef touchCancelCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - sendTouchEvent(EWK_TOUCH_CANCEL); - return JSValueMakeUndefined(context); -} - -static JSValueRef releaseTouchPointCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount != 1) - return JSValueMakeUndefined(context); - - int index = static_cast<int>(JSValueToNumber(context, arguments[0], exception)); - ASSERT(!exception || !*exception); - if (index < 0 || index >= touchPointList().size()) - return JSValueMakeUndefined(context); - - touchPointList().at(index).state = EWK_TOUCH_POINT_RELEASED; - return JSValueMakeUndefined(context); -} - -static JSValueRef touchEndCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - sendTouchEvent(EWK_TOUCH_END); - touchModifiers = 0; - return JSValueMakeUndefined(context); -} - -static JSValueRef clearTouchPointsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - touchPointList().clear(); - return JSValueMakeUndefined(context); -} - -static JSValueRef setTouchModifierCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) -{ - if (argumentCount != 2) - return JSValueMakeUndefined(context); - - JSRetainPtr<JSStringRef> jsModifier(Adopt, JSValueToStringCopy(context, arguments[0], exception)); - unsigned mask = 0; - - if (equals(jsModifier, "alt")) - mask |= ECORE_EVENT_MODIFIER_ALT; - else if (equals(jsModifier, "ctrl")) - mask |= ECORE_EVENT_MODIFIER_CTRL; - else if (equals(jsModifier, "meta")) - mask |= ECORE_EVENT_MODIFIER_WIN; - else if (equals(jsModifier, "shift")) - mask |= ECORE_EVENT_MODIFIER_SHIFT; - - if (JSValueToBoolean(context, arguments[1])) - touchModifiers |= mask; - else - touchModifiers &= ~mask; - - return JSValueMakeUndefined(context); -} - -static JSStaticFunction staticFunctions[] = { - { "contextClick", contextClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "mouseScrollBy", mouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "continuousMouseScrollBy", continuousMouseScrollByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "mouseDown", mouseDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "mouseUp", mouseUpCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "mouseMoveTo", mouseMoveToCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "leapForward", leapForwardCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "keyDown", keyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "scheduleAsynchronousClick", scheduleAsynchronousClickCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "scheduleAsynchronousKeyDown", scheduleAsynchronousKeyDownCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "scalePageBy", scalePageByCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "textZoomIn", textZoomInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "textZoomOut", textZoomOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "zoomPageIn", zoomPageInCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "zoomPageOut", zoomPageOutCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "addTouchPoint", addTouchPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "touchStart", touchStartCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "updateTouchPoint", updateTouchPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "touchMove", touchMoveCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "releaseTouchPoint", releaseTouchPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "touchEnd", touchEndCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "cancelTouchPoint", cancelTouchPointCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "touchCancel", touchCancelCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "clearTouchPoints", clearTouchPointsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { "setTouchModifier", setTouchModifierCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete }, - { 0, 0, 0 } -}; - -static JSStaticValue staticValues[] = { - { 0, 0, 0, 0 } -}; - -static JSClassRef getClass(JSContextRef context) -{ - static JSClassRef eventSenderClass = 0; - - if (!eventSenderClass) { - JSClassDefinition classDefinition = { - 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - classDefinition.staticFunctions = staticFunctions; - classDefinition.staticValues = staticValues; - - eventSenderClass = JSClassCreate(&classDefinition); - } - - return eventSenderClass; -} - -JSObjectRef makeEventSender(JSContextRef context, bool isTopFrame) -{ - if (isTopFrame) { - gDragMode = true; - - // Fly forward in time one second when the main frame loads. This will - // ensure that when a test begins clicking in the same location as - // a previous test, those clicks won't be interpreted as continuations - // of the previous test's click sequences. - gTimeOffset += 1000; - - gLastMousePositionX = gLastMousePositionY = 0; - gLastClickPositionX = gLastClickPositionY = 0; - gLastClickTimeOffset = 0; - gLastClickButton = 0; - gButtonCurrentlyDown = 0; - gClickCount = 0; - } - - return JSObjectMake(context, getClass(context), 0); -} - -static void feedOrQueueMouseEvent(MouseEventInfo* eventInfo, EventQueueStrategy strategy) -{ - if (!delayedEventQueue().isEmpty()) { - if (delayedEventQueue().last().eventInfo) - delayedEventQueue().append(DelayedEvent(eventInfo)); - else - delayedEventQueue().last().eventInfo = eventInfo; - - if (strategy == FeedQueuedEvents) - feedQueuedMouseEvents(); - } else - feedMouseEvent(eventInfo); -} - -static void feedMouseEvent(MouseEventInfo* eventInfo) -{ - if (!eventInfo) - return; - - unsigned timeStamp = 0; - Evas_Object* mainFrame = browser->mainFrame(); - Evas* evas = evas_object_evas_get(mainFrame); - EvasMouseEvent event = eventInfo->event; - - setEvasModifiers(evas, eventInfo->modifiers); - - Evas_Button_Flags flags = EVAS_BUTTON_NONE; - - // FIXME: We need to pass additional information with our events, so that - // we could construct correct PlatformWheelEvent. At the moment, max number - // of clicks is 3 - if (gClickCount == 3) - flags = EVAS_BUTTON_TRIPLE_CLICK; - else if (gClickCount == 2) - flags = EVAS_BUTTON_DOUBLE_CLICK; - - if (event & EvasMouseEventMove) - evas_event_feed_mouse_move(evas, gLastMousePositionX, gLastMousePositionY, timeStamp++, 0); - if (event & EvasMouseEventDown) - evas_event_feed_mouse_down(evas, eventInfo->button, flags, timeStamp++, 0); - if (event & EvasMouseEventUp) - evas_event_feed_mouse_up(evas, eventInfo->button, flags, timeStamp++, 0); - if (event & EvasMouseEventScrollLeft | event & EvasMouseEventScrollRight) - evas_event_feed_mouse_wheel(evas, 1, eventInfo->horizontalDelta, timeStamp, 0); - if (event & EvasMouseEventScrollUp | event & EvasMouseEventScrollDown) - evas_event_feed_mouse_wheel(evas, 0, eventInfo->verticalDelta, timeStamp, 0); - - setEvasModifiers(evas, EvasKeyModifierNone); - - delete eventInfo; -} - -static void feedQueuedMouseEvents() -{ - WTF::Vector<DelayedEvent>::const_iterator it = delayedEventQueue().begin(); - for (; it != delayedEventQueue().end(); it++) { - DelayedEvent delayedEvent = *it; - if (delayedEvent.delay) - usleep(delayedEvent.delay * 1000); - feedMouseEvent(delayedEvent.eventInfo); - } - delayedEventQueue().clear(); -} |