1 /*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 * THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "config.h"
28 #include "WebEventFactoryQt.h"
29 #include <qgraphicssceneevent.h>
30 #include <QApplication>
31 #include <QKeyEvent>
32 #include <WebCore/IntPoint.h>
33 #include <WebCore/FloatPoint.h>
34 #include <WebCore/PlatformKeyboardEvent.h>
35 #include <wtf/ASCIICType.h>
36 #include <wtf/CurrentTime.h>
37
38 using namespace WebCore;
39
40 namespace WebKit {
41
mouseButtonForEvent(QGraphicsSceneMouseEvent * event)42 static WebMouseEvent::Button mouseButtonForEvent(QGraphicsSceneMouseEvent *event)
43 {
44 if (event->button() == Qt::LeftButton || (event->buttons() & Qt::LeftButton))
45 return WebMouseEvent::LeftButton;
46 else if (event->button() == Qt::RightButton || (event->buttons() & Qt::RightButton))
47 return WebMouseEvent::RightButton;
48 else if (event->button() == Qt::MidButton || (event->buttons() & Qt::MidButton))
49 return WebMouseEvent::MiddleButton;
50 return WebMouseEvent::NoButton;
51 }
52
webEventTypeForEvent(QEvent * event)53 static WebEvent::Type webEventTypeForEvent(QEvent* event)
54 {
55 switch (event->type()) {
56 case QEvent::GraphicsSceneMouseDoubleClick:
57 case QEvent::GraphicsSceneMousePress:
58 return WebEvent::MouseDown;
59 case QEvent::GraphicsSceneMouseRelease:
60 return WebEvent::MouseUp;
61 case QEvent::GraphicsSceneMouseMove:
62 return WebEvent::MouseMove;
63 case QEvent::Wheel:
64 return WebEvent::Wheel;
65 case QEvent::KeyPress:
66 return WebEvent::KeyDown;
67 case QEvent::KeyRelease:
68 return WebEvent::KeyUp;
69 #if ENABLE(TOUCH_EVENTS)
70 case QEvent::TouchBegin:
71 return WebEvent::TouchStart;
72 case QEvent::TouchUpdate:
73 return WebEvent::TouchMove;
74 case QEvent::TouchEnd:
75 return WebEvent::TouchEnd;
76 #endif
77 default:
78 // assert
79 return WebEvent::MouseMove;
80 }
81 }
82
modifiersForEvent(Qt::KeyboardModifiers modifiers)83 static inline WebEvent::Modifiers modifiersForEvent(Qt::KeyboardModifiers modifiers)
84 {
85 unsigned result = 0;
86 if (modifiers & Qt::ShiftModifier)
87 result |= WebEvent::ShiftKey;
88 if (modifiers & Qt::ControlModifier)
89 result |= WebEvent::ControlKey;
90 if (modifiers & Qt::AltModifier)
91 result |= WebEvent::AltKey;
92 if (modifiers & Qt::MetaModifier)
93 result |= WebEvent::MetaKey;
94 return (WebEvent::Modifiers)result;
95 }
96
createWebMouseEvent(QGraphicsSceneMouseEvent * event,int eventClickCount)97 WebMouseEvent WebEventFactory::createWebMouseEvent(QGraphicsSceneMouseEvent* event, int eventClickCount)
98 {
99 FloatPoint delta(event->pos().x() - event->lastPos().x(), event->pos().y() - event->lastPos().y());
100
101 WebEvent::Type type = webEventTypeForEvent(event);
102 WebMouseEvent::Button button = mouseButtonForEvent(event);
103 float deltaX = delta.x();
104 float deltaY = delta.y();
105 int clickCount = eventClickCount;
106 WebEvent::Modifiers modifiers = modifiersForEvent(event->modifiers());
107 double timestamp = WTF::currentTime();
108
109 return WebMouseEvent(type, button, event->pos().toPoint(), event->screenPos(), deltaX, deltaY, 0.0f, clickCount, modifiers, timestamp);
110 }
111
createWebWheelEvent(QGraphicsSceneWheelEvent * e)112 WebWheelEvent WebEventFactory::createWebWheelEvent(QGraphicsSceneWheelEvent* e)
113 {
114 float deltaX = 0;
115 float deltaY = 0;
116 float wheelTicksX = 0;
117 float wheelTicksY = 0;
118 WebWheelEvent::Granularity granularity = WebWheelEvent::ScrollByPixelWheelEvent;
119 WebEvent::Modifiers modifiers = modifiersForEvent(e->modifiers());
120 double timestamp = WTF::currentTime();
121
122 // A delta that is not mod 120 indicates a device that is sending
123 // fine-resolution scroll events, so use the delta as number of wheel ticks
124 // and number of pixels to scroll.See also webkit.org/b/29601
125 bool fullTick = !(e->delta() % 120);
126
127 if (e->orientation() == Qt::Horizontal) {
128 deltaX = (fullTick) ? e->delta() / 120.0f : e->delta();
129 wheelTicksX = deltaX;
130 } else {
131 deltaY = (fullTick) ? e->delta() / 120.0f : e->delta();
132 wheelTicksY = deltaY;
133 }
134
135 // Use the same single scroll step as QTextEdit
136 // (in QTextEditPrivate::init [h,v]bar->setSingleStep)
137 static const float cDefaultQtScrollStep = 20.f;
138 #ifndef QT_NO_WHEELEVENT
139 deltaX *= (fullTick) ? QApplication::wheelScrollLines() * cDefaultQtScrollStep : 1;
140 deltaY *= (fullTick) ? QApplication::wheelScrollLines() * cDefaultQtScrollStep : 1;
141 #endif
142
143 return WebWheelEvent(WebEvent::Wheel, e->pos().toPoint(), e->screenPos(), FloatSize(deltaX, deltaY), FloatSize(wheelTicksX, wheelTicksY), granularity, modifiers, timestamp);
144 }
145
createWebKeyboardEvent(QKeyEvent * event)146 WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(QKeyEvent* event)
147 {
148 const int state = event->modifiers();
149 WebEvent::Type type = webEventTypeForEvent(event);
150 const String text = event->text();
151 const String unmodifiedText = event->text();
152 bool isAutoRepeat = event->isAutoRepeat();
153 bool isSystemKey = false; // FIXME: No idea what that is.
154 bool isKeypad = (state & Qt::KeypadModifier);
155 const String keyIdentifier = keyIdentifierForQtKeyCode(event->key());
156 int windowsVirtualKeyCode = windowsKeyCodeForKeyEvent(event->key(), isKeypad);
157 int nativeVirtualKeyCode = event->nativeVirtualKey();
158 int macCharCode = 0;
159 WebEvent::Modifiers modifiers = modifiersForEvent(event->modifiers());
160 double timestamp = WTF::currentTime();
161
162 return WebKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp);
163 }
164
165 #if ENABLE(TOUCH_EVENTS)
166
createWebTouchEvent(QTouchEvent * event)167 WebTouchEvent WebEventFactory::createWebTouchEvent(QTouchEvent* event)
168 {
169 WebEvent::Type type = webEventTypeForEvent(event);
170 WebPlatformTouchPoint::TouchPointState state = static_cast<WebPlatformTouchPoint::TouchPointState>(0);
171 unsigned int id;
172 WebEvent::Modifiers modifiers = modifiersForEvent(event->modifiers());
173 double timestamp = WTF::currentTime();
174
175 const QList<QTouchEvent::TouchPoint>& points = event->touchPoints();
176
177 Vector<WebPlatformTouchPoint> m_touchPoints;
178 for (int i = 0; i < points.count(); ++i) {
179 id = static_cast<unsigned>(points.at(i).id());
180 switch (points.at(i).state()) {
181 case Qt::TouchPointReleased:
182 state = WebPlatformTouchPoint::TouchReleased;
183 break;
184 case Qt::TouchPointMoved:
185 state = WebPlatformTouchPoint::TouchMoved;
186 break;
187 case Qt::TouchPointPressed:
188 state = WebPlatformTouchPoint::TouchPressed;
189 break;
190 case Qt::TouchPointStationary:
191 state = WebPlatformTouchPoint::TouchStationary;
192 break;
193 default:
194 ASSERT_NOT_REACHED();
195 break;
196 }
197
198 m_touchPoints.append(WebPlatformTouchPoint(id, state, points.at(i).screenPos().toPoint(), points.at(i).pos().toPoint()));
199 }
200
201 bool m_ctrlKey = (event->modifiers() & Qt::ControlModifier);
202 bool m_altKey = (event->modifiers() & Qt::AltModifier);
203 bool m_shiftKey = (event->modifiers() & Qt::ShiftModifier);
204 bool m_metaKey = (event->modifiers() & Qt::MetaModifier);
205
206 return WebTouchEvent(type, m_touchPoints, m_ctrlKey, m_altKey, m_shiftKey, m_metaKey, modifiers, timestamp);
207 }
208 #endif
209
210 } // namespace WebKit
211