⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eventsender.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. * * 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 "DraggingInfo.h"#include "DumpRenderTree.h"#include <WebCore/COMPtr.h>#include <wtf/ASCIICType.h>#include <wtf/Platform.h>#include <JavaScriptCore/JavaScriptCore.h>#include <JavaScriptCore/Assertions.h>#include <WebKit/WebKit.h>#include <windows.h>#define WM_DRT_SEND_QUEUED_EVENT (WM_APP+1)static bool down;static bool dragMode = true;static bool replayingSavedEvents;static int timeOffset;static POINT lastMousePosition;struct DelayedMessage {    MSG msg;    unsigned delay;};static DelayedMessage msgQueue[1024];static unsigned endOfQueue;static unsigned startOfQueue;static bool didDragEnter;DraggingInfo* draggingInfo = 0;static JSValueRef getDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){    return JSValueMakeBoolean(context, dragMode);}static bool setDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef value, JSValueRef* exception){    dragMode = JSValueToBoolean(context, value);    return true;}static JSValueRef getConstantCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception){    if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYDOWN"))        return JSValueMakeNumber(context, WM_KEYDOWN);    if (JSStringIsEqualToUTF8CString(propertyName, "WM_KEYUP"))        return JSValueMakeNumber(context, WM_KEYUP);    if (JSStringIsEqualToUTF8CString(propertyName, "WM_CHAR"))        return JSValueMakeNumber(context, WM_CHAR);    if (JSStringIsEqualToUTF8CString(propertyName, "WM_DEADCHAR"))        return JSValueMakeNumber(context, WM_DEADCHAR);    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYDOWN"))        return JSValueMakeNumber(context, WM_SYSKEYDOWN);    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYUP"))        return JSValueMakeNumber(context, WM_SYSKEYUP);    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSCHAR"))        return JSValueMakeNumber(context, WM_SYSCHAR);    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSDEADCHAR"))        return JSValueMakeNumber(context, WM_SYSDEADCHAR);    ASSERT_NOT_REACHED();    return JSValueMakeUndefined(context);}static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){    if (argumentCount > 0) {        msgQueue[endOfQueue].delay = JSValueToNumber(context, arguments[0], exception);        ASSERT(!exception || !*exception);    }    return JSValueMakeUndefined(context);}static DWORD currentEventTime(){    return ::GetTickCount() + timeOffset;}static MSG makeMsg(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    MSG result = {0};    result.hwnd = hwnd;    result.message = message;    result.wParam = wParam;    result.lParam = lParam;    result.time = currentEventTime();    result.pt = lastMousePosition;    return result;}static LRESULT dispatchMessage(const MSG* msg){    ASSERT(msg);    ::TranslateMessage(msg);    return ::DispatchMessage(msg);}static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){    COMPtr<IWebFramePrivate> framePrivate;    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))        framePrivate->layout();    down = true;    MSG msg = makeMsg(webViewWindow, WM_RBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));    dispatchMessage(&msg);    down = false;    msg = makeMsg(webViewWindow, WM_RBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));    dispatchMessage(&msg);        return JSValueMakeUndefined(context);}static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){    COMPtr<IWebFramePrivate> framePrivate;    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))        framePrivate->layout();    down = true;    MSG msg = makeMsg(webViewWindow, WM_LBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));    if (!msgQueue[endOfQueue].delay)        dispatchMessage(&msg);    else {        // replaySavedEvents has the required logic to make leapForward delays work        msgQueue[endOfQueue++].msg = msg;        replaySavedEvents();    }    return JSValueMakeUndefined(context);}static inline POINTL pointl(const POINT& point){    POINTL result;    result.x = point.x;    result.y = point.y;    return result;}static void doMouseUp(MSG msg){    COMPtr<IWebFramePrivate> framePrivate;    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))        framePrivate->layout();    dispatchMessage(&msg);    down = false;    if (draggingInfo) {        COMPtr<IWebView> webView;        COMPtr<IDropTarget> webViewDropTarget;        if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {            POINT screenPoint = msg.pt;            DWORD effect = 0;            ::ClientToScreen(webViewWindow, &screenPoint);            if (!didDragEnter) {                webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);                didDragEnter = true;            }            HRESULT hr = draggingInfo->dropSource()->QueryContinueDrag(0, 0);            webViewDropTarget->DragOver(0, pointl(screenPoint), &effect);            if (hr == DRAGDROP_S_DROP && effect != DROPEFFECT_NONE) {                DWORD effect = 0;                webViewDropTarget->Drop(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);            } else                webViewDropTarget->DragLeave();            delete draggingInfo;            draggingInfo = 0;        }    }}static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){    MSG msg = makeMsg(webViewWindow, WM_LBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));    if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) {        msgQueue[endOfQueue++].msg = msg;        replaySavedEvents();    } else        doMouseUp(msg);    return JSValueMakeUndefined(context);}static void doMouseMove(MSG msg){    COMPtr<IWebFramePrivate> framePrivate;    if (SUCCEEDED(frame->QueryInterface(&framePrivate)))        framePrivate->layout();    dispatchMessage(&msg);    if (down && draggingInfo) {        POINT screenPoint = msg.pt;        ::ClientToScreen(webViewWindow, &screenPoint);        IWebView* webView;        COMPtr<IDropTarget> webViewDropTarget;        if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {            DWORD effect = 0;            if (didDragEnter)                webViewDropTarget->DragOver(MK_LBUTTON, pointl(screenPoint), &effect);            else {                webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);                didDragEnter = true;            }            draggingInfo->dropSource()->GiveFeedback(effect);        }    }}static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception){    if (argumentCount < 2)        return JSValueMakeUndefined(context);    lastMousePosition.x = (int)JSValueToNumber(context, arguments[0], exception);    ASSERT(!exception || !*exception);    lastMousePosition.y = (int)JSValueToNumber(context, arguments[1], exception);    ASSERT(!exception || !*exception);    MSG msg = makeMsg(webViewWindow, WM_MOUSEMOVE, down ? MK_LBUTTON : 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));    if (dragMode && down && !replayingSavedEvents) {        msgQueue[endOfQueue++].msg = msg;        return JSValueMakeUndefined(context);    }    doMouseMove(msg);    return JSValueMakeUndefined(context);}void replaySavedEvents(){    replayingSavedEvents = true;      MSG msg = { 0 };    while (startOfQueue < endOfQueue && !msgQueue[startOfQueue].delay) {        msg = msgQueue[startOfQueue++].msg;        switch (msg.message) {            case WM_LBUTTONUP:                doMouseUp(msg);                break;            case WM_MOUSEMOVE:                doMouseMove(msg);                break;            case WM_LBUTTONDOWN:                dispatchMessage(&msg);                break;            default:                // Not reached                break;        }    }    int numQueuedMessages = endOfQueue - startOfQueue;    if (!numQueuedMessages) {        startOfQueue = 0;        endOfQueue = 0;        replayingSavedEvents = false;        ASSERT(!down);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -