1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/*
2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2006-2009 Google Inc. All rights reserved.
3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Redistribution and use in source and binary forms, with or without
5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * modification, are permitted provided that the following conditions are
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * met:
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions of source code must retain the above copyright
9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * notice, this list of conditions and the following disclaimer.
10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions in binary form must reproduce the above
11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * copyright notice, this list of conditions and the following disclaimer
12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * in the documentation and/or other materials provided with the
13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * distribution.
14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Neither the name of Google Inc. nor the names of its
15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * contributors may be used to endorse or promote products derived from
16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * this software without specific prior written permission.
17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h"
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebInputEventFactory.h"
33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebInputEvent.h"
35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/Assertions.h>
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace WebKit {
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const unsigned long defaultScrollLinesPerWheelDelta = 3;
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic const unsigned long defaultScrollCharsPerWheelDelta = 1;
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// WebKeyboardEvent -----------------------------------------------------------
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic bool isKeyPad(WPARAM wparam, LPARAM lparam)
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool keypad = false;
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (wparam) {
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_RETURN:
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        keypad = (lparam >> 16) & KF_EXTENDED;
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
52643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_INSERT:
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_DELETE:
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_HOME:
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_END:
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_PRIOR:
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NEXT:
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_UP:
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_DOWN:
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_LEFT:
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_RIGHT:
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        keypad = !((lparam >> 16) & KF_EXTENDED);
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMLOCK:
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD0:
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD1:
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD2:
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD3:
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD4:
70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD5:
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD6:
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD7:
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD8:
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_NUMPAD9:
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_DIVIDE:
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_MULTIPLY:
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_SUBTRACT:
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_ADD:
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_DECIMAL:
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case VK_CLEAR:
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        keypad = true;
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    default:
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        keypad = false;
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return keypad;
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
89bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen// Loads the state for toggle keys into the event.
90bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsenstatic void SetToggleKeyState(WebInputEvent* event)
91bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen{
92bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    // Low bit set from GetKeyState indicates "toggled".
93bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (::GetKeyState(VK_NUMLOCK) & 1)
94bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        event->modifiers |= WebInputEvent::NumLockOn;
95bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    if (::GetKeyState(VK_CAPITAL) & 1)
96bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen        event->modifiers |= WebInputEvent::CapsLockOn;
97bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen}
98bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
99643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebKeyboardEvent WebInputEventFactory::keyboardEvent(HWND hwnd, UINT message,
100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                     WPARAM wparam, LPARAM lparam)
101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
102643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebKeyboardEvent result;
103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that
105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // GetMessageTime() refers to is the same one that we're passed in? Perhaps
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // one of the construction parameters should be the time passed by the
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // caller, who would know for sure.
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.timeStampSeconds = GetMessageTime() / 1000.0;
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.windowsKeyCode = result.nativeKeyCode = static_cast<int>(wparam);
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (message) {
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_SYSKEYDOWN:
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.isSystemKey = true;
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_KEYDOWN:
116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::RawKeyDown;
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_SYSKEYUP:
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.isSystemKey = true;
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_KEYUP:
121643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::KeyUp;
122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_IME_CHAR:
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::Char;
125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_SYSCHAR:
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.isSystemKey = true;
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::Char;
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_CHAR:
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::Char;
131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    default:
133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT_NOT_REACHED();
134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
135643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (result.type == WebInputEvent::Char || result.type == WebInputEvent::RawKeyDown) {
137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.text[0] = result.windowsKeyCode;
138643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.unmodifiedText[0] = result.windowsKeyCode;
139643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
140643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (result.type != WebInputEvent::Char)
141643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.setKeyIdentifierFromWindowsKeyCode();
142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (GetKeyState(VK_SHIFT) & 0x8000)
144643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::ShiftKey;
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (GetKeyState(VK_CONTROL) & 0x8000)
146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::ControlKey;
147643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (GetKeyState(VK_MENU) & 0x8000)
148643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::AltKey;
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // NOTE: There doesn't seem to be a way to query the mouse button state in
150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // this case.
151643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
152643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (LOWORD(lparam) > 1)
153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::IsAutoRepeat;
154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (isKeyPad(wparam, lparam))
155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::IsKeyPad;
156643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
157bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    SetToggleKeyState(&result);
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return result;
159643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
160643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
161643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// WebMouseEvent --------------------------------------------------------------
162643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
163643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int gLastClickCount;
164643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic double gLastClickTime;
165643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
166643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic LPARAM GetRelativeCursorPos(HWND hwnd)
167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    POINT pos = {-1, -1};
169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    GetCursorPos(&pos);
170643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ScreenToClient(hwnd, &pos);
171643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return MAKELPARAM(pos.x, pos.y);
172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
174643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebInputEventFactory::resetLastClickState()
175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
176643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    gLastClickTime = gLastClickCount = 0;
177643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
178643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
179643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebMouseEvent WebInputEventFactory::mouseEvent(HWND hwnd, UINT message,
180643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                               WPARAM wparam, LPARAM lparam)
181643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
182643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebMouseEvent result; //(WebInputEvent::Uninitialized());
183643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    switch (message) {
185643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_MOUSEMOVE:
186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseMove;
187643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (wparam & MK_LBUTTON)
188643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            result.button = WebMouseEvent::ButtonLeft;
189643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        else if (wparam & MK_MBUTTON)
190643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            result.button = WebMouseEvent::ButtonMiddle;
191643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        else if (wparam & MK_RBUTTON)
192643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            result.button = WebMouseEvent::ButtonRight;
193643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        else
194643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            result.button = WebMouseEvent::ButtonNone;
195643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
196643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_MOUSELEAVE:
197643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseLeave;
198643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.button = WebMouseEvent::ButtonNone;
199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // set the current mouse position (relative to the client area of the
200643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // current window) since none is specified for this event
201643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        lparam = GetRelativeCursorPos(hwnd);
202643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_LBUTTONDOWN:
204643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_LBUTTONDBLCLK:
205643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseDown;
206643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.button = WebMouseEvent::ButtonLeft;
207643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
208643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_MBUTTONDOWN:
209643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_MBUTTONDBLCLK:
210643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseDown;
211643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.button = WebMouseEvent::ButtonMiddle;
212643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
213643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_RBUTTONDOWN:
214643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_RBUTTONDBLCLK:
215643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseDown;
216643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.button = WebMouseEvent::ButtonRight;
217643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
218643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_LBUTTONUP:
219643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseUp;
220643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.button = WebMouseEvent::ButtonLeft;
221643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
222643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_MBUTTONUP:
223643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseUp;
224643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.button = WebMouseEvent::ButtonMiddle;
225643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
226643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    case WM_RBUTTONUP:
227643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.type = WebInputEvent::MouseUp;
228643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.button = WebMouseEvent::ButtonRight;
229643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        break;
230643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    default:
231643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ASSERT_NOT_REACHED();
232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
233643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
234643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that
235643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // GetMessageTime() refers to is the same one that we're passed in? Perhaps
236643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // one of the construction parameters should be the time passed by the
237643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // caller, who would know for sure.
238643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.timeStampSeconds = GetMessageTime() / 1000.0;
239643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
240643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // set position fields:
241643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
242643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.x = static_cast<short>(LOWORD(lparam));
243643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.y = static_cast<short>(HIWORD(lparam));
244643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.windowX = result.x;
245643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.windowY = result.y;
246643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
247643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    POINT globalPoint = { result.x, result.y };
248643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ClientToScreen(hwnd, &globalPoint);
249643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
250643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.globalX = globalPoint.x;
251643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.globalY = globalPoint.y;
252643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
253643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // calculate number of clicks:
254643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
255643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // This differs slightly from the WebKit code in WebKit/win/WebView.cpp
256643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // where their original code looks buggy.
257643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    static int lastClickPositionX;
258643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    static int lastClickPositionY;
259643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    static WebMouseEvent::Button lastClickButton = WebMouseEvent::ButtonLeft;
260643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
261643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    double currentTime = result.timeStampSeconds;
262643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool cancelPreviousClick =
263643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        (abs(lastClickPositionX - result.x) > (GetSystemMetrics(SM_CXDOUBLECLK) / 2))
264643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        || (abs(lastClickPositionY - result.y) > (GetSystemMetrics(SM_CYDOUBLECLK) / 2))
265643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        || ((currentTime - gLastClickTime) * 1000.0 > GetDoubleClickTime());
266643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
267643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (result.type == WebInputEvent::MouseDown) {
268643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!cancelPreviousClick && (result.button == lastClickButton))
269643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            ++gLastClickCount;
270643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        else {
271643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            gLastClickCount = 1;
272643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            lastClickPositionX = result.x;
273643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            lastClickPositionY = result.y;
274643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
275643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        gLastClickTime = currentTime;
276643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        lastClickButton = result.button;
277643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else if (result.type == WebInputEvent::MouseMove
278643ca7872b450ea4efacab6188849e5aac2ba161Steve Block               || result.type == WebInputEvent::MouseLeave) {
279643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (cancelPreviousClick) {
280643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            gLastClickCount = 0;
281643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            lastClickPositionX = 0;
282643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            lastClickPositionY = 0;
283643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            gLastClickTime = 0;
284643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
285643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
286643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.clickCount = gLastClickCount;
287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
288643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // set modifiers:
289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
290643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (wparam & MK_CONTROL)
291643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::ControlKey;
292643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (wparam & MK_SHIFT)
293643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::ShiftKey;
294643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (GetKeyState(VK_MENU) & 0x8000)
295643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::AltKey;
296643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (wparam & MK_LBUTTON)
297643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::LeftButtonDown;
298643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (wparam & MK_MBUTTON)
299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::MiddleButtonDown;
300643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (wparam & MK_RBUTTON)
301643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::RightButtonDown;
302643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
303bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    SetToggleKeyState(&result);
304643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return result;
305643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
306643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
307643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// WebMouseWheelEvent ---------------------------------------------------------
308643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
309643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(HWND hwnd, UINT message,
310643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                         WPARAM wparam, LPARAM lparam)
311643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
312643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    WebMouseWheelEvent result; //(WebInputEvent::Uninitialized());
313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
314643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.type = WebInputEvent::MouseWheel;
315643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
316643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // TODO(pkasting): http://b/1117926 Are we guaranteed that the message that
317643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // GetMessageTime() refers to is the same one that we're passed in? Perhaps
318643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // one of the construction parameters should be the time passed by the
319643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // caller, who would know for sure.
320643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.timeStampSeconds = GetMessageTime() / 1000.0;
321643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
322643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.button = WebMouseEvent::ButtonNone;
323643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Get key state, coordinates, and wheel delta from event.
325643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    typedef SHORT (WINAPI *GetKeyStateFunction)(int key);
326643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    GetKeyStateFunction getKeyState;
327643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    UINT keyState;
328643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    float wheelDelta;
329643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    bool horizontalScroll = false;
330643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if ((message == WM_VSCROLL) || (message == WM_HSCROLL)) {
331643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Synthesize mousewheel event from a scroll event.  This is needed to
332643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // simulate middle mouse scrolling in some laptops.  Use GetAsyncKeyState
333643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // for key state since we are synthesizing the input event.
334643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        getKeyState = GetAsyncKeyState;
335643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        keyState = 0;
336643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (getKeyState(VK_SHIFT))
337643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            keyState |= MK_SHIFT;
338643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (getKeyState(VK_CONTROL))
339643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            keyState |= MK_CONTROL;
340643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // NOTE: There doesn't seem to be a way to query the mouse button state
341643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // in this case.
342643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
343643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        POINT cursorPosition = {0};
344643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        GetCursorPos(&cursorPosition);
345643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.globalX = cursorPosition.x;
346643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.globalY = cursorPosition.y;
347643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
348643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        switch (LOWORD(wparam)) {
349643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case SB_LINEUP:    // == SB_LINELEFT
350643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            wheelDelta = WHEEL_DELTA;
351643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            break;
352643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case SB_LINEDOWN:  // == SB_LINERIGHT
353643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            wheelDelta = -WHEEL_DELTA;
354643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            break;
355643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case SB_PAGEUP:
356643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            wheelDelta = 1;
357643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            result.scrollByPage = true;
358643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            break;
359643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        case SB_PAGEDOWN:
360643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            wheelDelta = -1;
361643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            result.scrollByPage = true;
362643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            break;
363643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        default:  // We don't supoprt SB_THUMBPOSITION or SB_THUMBTRACK here.
364643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            wheelDelta = 0;
365643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            break;
366643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
367643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
368643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (message == WM_HSCROLL)
369643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            horizontalScroll = true;
370643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else {
371643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // Non-synthesized event; we can just read data off the event.
372643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        getKeyState = GetKeyState;
373643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        keyState = GET_KEYSTATE_WPARAM(wparam);
374643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
375643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.globalX = static_cast<short>(LOWORD(lparam));
376643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.globalY = static_cast<short>(HIWORD(lparam));
377643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
378643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        wheelDelta = static_cast<float>(GET_WHEEL_DELTA_WPARAM(wparam));
379643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (message == WM_MOUSEHWHEEL) {
380643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            horizontalScroll = true;
381643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            wheelDelta = -wheelDelta;  // Windows is <- -/+ ->, WebKit <- +/- ->.
382643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
383643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
384643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (keyState & MK_SHIFT)
385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        horizontalScroll = true;
386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
387643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Set modifiers based on key state.
388643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (keyState & MK_SHIFT)
389643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::ShiftKey;
390643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (keyState & MK_CONTROL)
391643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::ControlKey;
392643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (getKeyState(VK_MENU) & 0x8000)
393643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::AltKey;
394643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (keyState & MK_LBUTTON)
395643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::LeftButtonDown;
396643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (keyState & MK_MBUTTON)
397643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::MiddleButtonDown;
398643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (keyState & MK_RBUTTON)
399643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.modifiers |= WebInputEvent::RightButtonDown;
400643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
401bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen    SetToggleKeyState(&result);
402bec39347bb3bb5bf1187ccaf471d26247f28b585Kristian Monsen
403643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Set coordinates by translating event coordinates from screen to client.
404643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    POINT clientPoint = { result.globalX, result.globalY };
405643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    MapWindowPoints(0, hwnd, &clientPoint, 1);
406643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.x = clientPoint.x;
407643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.y = clientPoint.y;
408643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.windowX = result.x;
409643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    result.windowY = result.y;
410643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
411643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Convert wheel delta amount to a number of pixels to scroll.
412643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    //
413643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // How many pixels should we scroll per line?  Gecko uses the height of the
414643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // current line, which means scroll distance changes as you go through the
4155ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // page or go to different pages.  IE 8 is ~60 px/line, although the value
4165ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // seems to vary slightly by page and zoom level.  Also, IE defaults to
4175ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // smooth scrolling while Firefox doesn't, so it can get away with somewhat
4185ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // larger scroll values without feeling as jerky.  Here we use 100 px per
4195ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen    // three lines (the default scroll amount is three lines per wheel tick).
4205abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // Even though we have smooth scrolling, we don't make this as large as IE
4215abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // because subjectively IE feels like it scrolls farther than you want while
4225abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick    // reading articles.
423643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    static const float scrollbarPixelsPerLine = 100.0f / 3.0f;
424643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    wheelDelta /= WHEEL_DELTA;
425643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    float scrollDelta = wheelDelta;
426643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (horizontalScroll) {
427643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        unsigned long scrollChars = defaultScrollCharsPerWheelDelta;
428643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &scrollChars, 0);
429643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // TODO(pkasting): Should probably have a different multiplier
430643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        // scrollbarPixelsPerChar here.
431643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        scrollDelta *= static_cast<float>(scrollChars) * scrollbarPixelsPerLine;
432643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else {
433643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        unsigned long scrollLines = defaultScrollLinesPerWheelDelta;
434643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &scrollLines, 0);
435643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (scrollLines == WHEEL_PAGESCROLL)
436643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            result.scrollByPage = true;
437643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        if (!result.scrollByPage)
438643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            scrollDelta *= static_cast<float>(scrollLines) * scrollbarPixelsPerLine;
439643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
440643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
441643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Set scroll amount based on above calculations.  WebKit expects positive
442643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // deltaY to mean "scroll up" and positive deltaX to mean "scroll left".
443643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (horizontalScroll) {
444643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.deltaX = scrollDelta;
445643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.wheelTicksX = wheelDelta;
446643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    } else {
447643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.deltaY = scrollDelta;
448643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        result.wheelTicksY = wheelDelta;
449643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
450643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
451643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return result;
452643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
453643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
454643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} // namespace WebKit
455