2
Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3
Copyright (C) 2006 Zack Rusin <zack@kde.org>
4
Copyright (C) 2011 Research In Motion Limited.
6
This library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Library General Public
8
License as published by the Free Software Foundation; either
9
version 2 of the License, or (at your option) any later version.
11
This library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Library General Public License for more details.
16
You should have received a copy of the GNU Library General Public License
17
along with this library; see the file COPYING.LIB. If not, write to
18
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
Boston, MA 02110-1301, USA.
23
#include "WebEventConversion.h"
25
#include "PlatformGestureEvent.h"
26
#include "PlatformMouseEvent.h"
27
#include "PlatformTouchEvent.h"
28
#include "PlatformTouchPoint.h"
29
#include "PlatformWheelEvent.h"
30
#include <QApplication>
32
#include <QGestureEvent>
33
#include <QGraphicsSceneMouseEvent>
34
#include <QTouchEvent>
35
#include <QWheelEvent>
37
#include <wtf/CurrentTime.h>
41
static void mouseEventModifiersFromQtKeyboardModifiers(Qt::KeyboardModifiers keyboardModifiers, unsigned& modifiers)
44
if (keyboardModifiers & Qt::ShiftModifier)
45
modifiers |= PlatformEvent::ShiftKey;
46
if (keyboardModifiers & Qt::ControlModifier)
47
modifiers |= PlatformEvent::CtrlKey;
48
if (keyboardModifiers & Qt::AltModifier)
49
modifiers |= PlatformEvent::AltKey;
50
if (keyboardModifiers & Qt::MetaModifier)
51
modifiers |= PlatformEvent::MetaKey;
54
static void mouseEventTypeAndMouseButtonFromQEvent(const QEvent* event, PlatformEvent::Type& mouseEventType, MouseButton& mouseButton)
56
enum { MouseEvent, GraphicsSceneMouseEvent } frameworkMouseEventType;
57
switch (event->type()) {
58
case QEvent::MouseButtonDblClick:
59
case QEvent::MouseButtonPress:
60
frameworkMouseEventType = MouseEvent;
61
mouseEventType = PlatformEvent::MousePressed;
63
case QEvent::MouseButtonRelease:
64
frameworkMouseEventType = MouseEvent;
65
mouseEventType = PlatformEvent::MouseReleased;
67
case QEvent::MouseMove:
68
frameworkMouseEventType = MouseEvent;
69
mouseEventType = PlatformEvent::MouseMoved;
71
case QEvent::GraphicsSceneMouseDoubleClick:
72
case QEvent::GraphicsSceneMousePress:
73
frameworkMouseEventType = GraphicsSceneMouseEvent;
74
mouseEventType = PlatformEvent::MousePressed;
76
case QEvent::GraphicsSceneMouseRelease:
77
frameworkMouseEventType = GraphicsSceneMouseEvent;
78
mouseEventType = PlatformEvent::MouseReleased;
80
case QEvent::GraphicsSceneMouseMove:
81
frameworkMouseEventType = GraphicsSceneMouseEvent;
82
mouseEventType = PlatformEvent::MouseMoved;
86
frameworkMouseEventType = MouseEvent;
87
mouseEventType = PlatformEvent::MouseMoved;
91
Qt::MouseButtons mouseButtons;
92
switch (frameworkMouseEventType) {
94
const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
95
mouseButtons = mouseEventType == PlatformEvent::MouseMoved ? mouseEvent->buttons() : mouseEvent->button();
98
case GraphicsSceneMouseEvent: {
99
const QGraphicsSceneMouseEvent* mouseEvent = static_cast<const QGraphicsSceneMouseEvent*>(event);
100
mouseButtons = mouseEventType == PlatformEvent::MouseMoved ? mouseEvent->buttons() : mouseEvent->button();
105
if (mouseButtons & Qt::LeftButton)
106
mouseButton = LeftButton;
107
else if (mouseButtons & Qt::RightButton)
108
mouseButton = RightButton;
109
else if (mouseButtons & Qt::MidButton)
110
mouseButton = MiddleButton;
112
mouseButton = NoButton;
115
class WebKitPlatformMouseEvent : public PlatformMouseEvent {
117
WebKitPlatformMouseEvent(QGraphicsSceneMouseEvent*, int clickCount);
118
WebKitPlatformMouseEvent(QInputEvent*, int clickCount);
121
WebKitPlatformMouseEvent::WebKitPlatformMouseEvent(QGraphicsSceneMouseEvent* event, int clickCount)
123
m_timestamp = WTF::currentTime();
125
// FIXME: Why don't we handle a context menu event here as we do in PlatformMouseEvent(QInputEvent*, int)?
126
// See <https://bugs.webkit.org/show_bug.cgi?id=60728>.
127
PlatformEvent::Type type;
128
mouseEventTypeAndMouseButtonFromQEvent(event, type, m_button);
131
m_position = IntPoint(event->pos().toPoint());
132
m_globalPosition = IntPoint(event->screenPos());
134
m_clickCount = clickCount;
135
mouseEventModifiersFromQtKeyboardModifiers(event->modifiers(), m_modifiers);
138
WebKitPlatformMouseEvent::WebKitPlatformMouseEvent(QInputEvent* event, int clickCount)
140
m_timestamp = WTF::currentTime();
142
bool isContextMenuEvent = false;
143
#ifndef QT_NO_CONTEXTMENU
144
if (event->type() == QEvent::ContextMenu) {
145
isContextMenuEvent = true;
146
m_type = PlatformEvent::MousePressed;
147
QContextMenuEvent* ce = static_cast<QContextMenuEvent*>(event);
148
m_position = IntPoint(ce->pos());
149
m_globalPosition = IntPoint(ce->globalPos());
150
m_button = RightButton;
153
if (!isContextMenuEvent) {
154
PlatformEvent::Type type;
155
mouseEventTypeAndMouseButtonFromQEvent(event, type, m_button);
156
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
159
m_position = IntPoint(mouseEvent->pos());
160
m_globalPosition = IntPoint(mouseEvent->globalPos());
163
m_clickCount = clickCount;
164
mouseEventModifiersFromQtKeyboardModifiers(event->modifiers(), m_modifiers);
167
PlatformMouseEvent convertMouseEvent(QInputEvent* event, int clickCount)
169
return WebKitPlatformMouseEvent(event, clickCount);
172
PlatformMouseEvent convertMouseEvent(QGraphicsSceneMouseEvent* event, int clickCount)
174
return WebKitPlatformMouseEvent(event, clickCount);
177
class WebKitPlatformWheelEvent : public PlatformWheelEvent {
179
WebKitPlatformWheelEvent(QGraphicsSceneWheelEvent*);
180
WebKitPlatformWheelEvent(QWheelEvent*);
183
void applyDelta(int delta, Qt::Orientation);
186
void WebKitPlatformWheelEvent::applyDelta(int delta, Qt::Orientation orientation)
188
if (orientation == Qt::Horizontal) {
195
m_wheelTicksX = m_deltaX / 120.0f;
196
m_wheelTicksY = m_deltaY / 120.0f;
198
// Since we request the scroll delta by the pixel, convert the wheel delta to pixel delta using the standard scroll step.
199
// Use the same single scroll step as QTextEdit (in QTextEditPrivate::init [h,v]bar->setSingleStep)
200
static const float cDefaultQtScrollStep = 20.f;
201
m_deltaX = m_wheelTicksX * QApplication::wheelScrollLines() * cDefaultQtScrollStep;
202
m_deltaY = m_wheelTicksY * QApplication::wheelScrollLines() * cDefaultQtScrollStep;
205
WebKitPlatformWheelEvent::WebKitPlatformWheelEvent(QGraphicsSceneWheelEvent* e)
207
m_timestamp = WTF::currentTime();
208
mouseEventModifiersFromQtKeyboardModifiers(e->modifiers(), m_modifiers);
209
m_position = e->pos().toPoint();
210
m_globalPosition = e->screenPos();
211
m_granularity = ScrollByPixelWheelEvent;
212
m_directionInvertedFromDevice = false;
213
applyDelta(e->delta(), e->orientation());
216
WebKitPlatformWheelEvent::WebKitPlatformWheelEvent(QWheelEvent* e)
218
m_timestamp = WTF::currentTime();
219
mouseEventModifiersFromQtKeyboardModifiers(e->modifiers(), m_modifiers);
220
m_position = e->pos();
221
m_globalPosition = e->globalPos();
222
m_granularity = ScrollByPixelWheelEvent;
223
m_directionInvertedFromDevice = false;
224
applyDelta(e->delta(), e->orientation());
227
#if ENABLE(TOUCH_EVENTS)
228
class WebKitPlatformTouchEvent : public PlatformTouchEvent {
230
WebKitPlatformTouchEvent(QTouchEvent*);
233
class WebKitPlatformTouchPoint : public PlatformTouchPoint {
235
WebKitPlatformTouchPoint(const QTouchEvent::TouchPoint&, State);
238
WebKitPlatformTouchEvent::WebKitPlatformTouchEvent(QTouchEvent* event)
240
switch (event->type()) {
241
case QEvent::TouchBegin:
242
m_type = PlatformEvent::TouchStart;
244
case QEvent::TouchUpdate:
245
m_type = PlatformEvent::TouchMove;
247
case QEvent::TouchEnd:
248
m_type = PlatformEvent::TouchEnd;
251
case QEvent::TouchCancel:
252
m_type = PlatformEvent::TouchCancel;
257
const QList<QTouchEvent::TouchPoint>& points = event->touchPoints();
258
for (int i = 0; i < points.count(); ++i) {
259
PlatformTouchPoint::State state = PlatformTouchPoint::TouchStateEnd;
261
switch (points.at(i).state()) {
262
case Qt::TouchPointReleased:
263
state = PlatformTouchPoint::TouchReleased;
265
case Qt::TouchPointMoved:
266
state = PlatformTouchPoint::TouchMoved;
268
case Qt::TouchPointPressed:
269
state = PlatformTouchPoint::TouchPressed;
271
case Qt::TouchPointStationary:
272
state = PlatformTouchPoint::TouchStationary;
276
// Qt does not have a Qt::TouchPointCancelled point state, so if we receive a touch cancel event,
277
// simply cancel all touch points here.
278
if (m_type == PlatformEvent::TouchCancel)
279
state = PlatformTouchPoint::TouchCancelled;
281
m_touchPoints.append(WebKitPlatformTouchPoint(points.at(i), state));
284
mouseEventModifiersFromQtKeyboardModifiers(event->modifiers(), m_modifiers);
286
m_timestamp = WTF::currentTime();
289
WebKitPlatformTouchPoint::WebKitPlatformTouchPoint(const QTouchEvent::TouchPoint& point, State state)
291
// The QTouchEvent::TouchPoint API states that ids will be >= 0.
294
m_screenPos = point.screenPos().toPoint();
295
m_pos = point.pos().toPoint();
296
// Qt reports touch point size as rectangles, but we will pretend it is an oval.
297
QRect touchRect = point.rect().toAlignedRect();
298
if (touchRect.isValid()) {
299
m_radiusX = point.rect().width() / 2;
300
m_radiusY = point.rect().height() / 2;
302
// http://www.w3.org/TR/2011/WD-touch-events-20110505: 1 if no value is known.
306
m_force = point.pressure();
307
// FIXME: Support m_rotationAngle if QTouchEvent at some point supports it.
311
#if ENABLE(GESTURE_EVENTS)
312
class WebKitPlatformGestureEvent : public PlatformGestureEvent {
314
WebKitPlatformGestureEvent(const QGestureEvent*, const QGesture*);
317
WebKitPlatformGestureEvent::WebKitPlatformGestureEvent(const QGestureEvent* event, const QGesture* gesture)
319
switch (gesture->gestureType()) {
320
case Qt::TapGesture: {
321
m_type = PlatformEvent::GestureTap;
322
QPointF globalPos = static_cast<const QTapGesture*>(gesture)->position();
323
m_globalPosition = globalPos.toPoint();
324
m_position = event->widget()->mapFromGlobal(globalPos.toPoint());
327
case Qt::TapAndHoldGesture: {
328
m_type = PlatformEvent::GestureLongPress;
329
QPointF globalPos = static_cast<const QTapAndHoldGesture*>(gesture)->position();
330
m_globalPosition = globalPos.toPoint();
331
m_position = event->widget()->mapFromGlobal(globalPos.toPoint());
335
ASSERT_NOT_REACHED();
338
m_timestamp = WTF::currentTime();
343
PlatformWheelEvent convertWheelEvent(QWheelEvent* event)
345
return WebKitPlatformWheelEvent(event);
348
PlatformWheelEvent convertWheelEvent(QGraphicsSceneWheelEvent* event)
350
return WebKitPlatformWheelEvent(event);
353
#if ENABLE(TOUCH_EVENTS)
354
PlatformTouchEvent convertTouchEvent(QTouchEvent* event)
356
return WebKitPlatformTouchEvent(event);
360
#if ENABLE(GESTURE_EVENTS)
361
PlatformGestureEvent convertGesture(QGestureEvent* event, QGesture* gesture)
363
return WebKitPlatformGestureEvent(event, gesture);