~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebKit/qt/WebCoreSupport/WebEventConversion.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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.
 
20
*/
 
21
 
 
22
#include "config.h"
 
23
#include "WebEventConversion.h"
 
24
 
 
25
#include "PlatformGestureEvent.h"
 
26
#include "PlatformMouseEvent.h"
 
27
#include "PlatformTouchEvent.h"
 
28
#include "PlatformTouchPoint.h"
 
29
#include "PlatformWheelEvent.h"
 
30
#include <QApplication>
 
31
#include <QGesture>
 
32
#include <QGestureEvent>
 
33
#include <QGraphicsSceneMouseEvent>
 
34
#include <QTouchEvent>
 
35
#include <QWheelEvent>
 
36
#include <QWidget>
 
37
#include <wtf/CurrentTime.h>
 
38
 
 
39
namespace WebCore {
 
40
 
 
41
static void mouseEventModifiersFromQtKeyboardModifiers(Qt::KeyboardModifiers keyboardModifiers, unsigned& modifiers)
 
42
{
 
43
    modifiers = 0;
 
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;
 
52
}
 
53
 
 
54
static void mouseEventTypeAndMouseButtonFromQEvent(const QEvent* event, PlatformEvent::Type& mouseEventType, MouseButton& mouseButton)
 
55
{
 
56
    enum { MouseEvent, GraphicsSceneMouseEvent } frameworkMouseEventType;
 
57
    switch (event->type()) {
 
58
    case QEvent::MouseButtonDblClick:
 
59
    case QEvent::MouseButtonPress:
 
60
        frameworkMouseEventType = MouseEvent;
 
61
        mouseEventType = PlatformEvent::MousePressed;
 
62
        break;
 
63
    case QEvent::MouseButtonRelease:
 
64
        frameworkMouseEventType = MouseEvent;
 
65
        mouseEventType = PlatformEvent::MouseReleased;
 
66
        break;
 
67
    case QEvent::MouseMove:
 
68
        frameworkMouseEventType = MouseEvent;
 
69
        mouseEventType = PlatformEvent::MouseMoved;
 
70
        break;
 
71
    case QEvent::GraphicsSceneMouseDoubleClick:
 
72
    case QEvent::GraphicsSceneMousePress:
 
73
        frameworkMouseEventType = GraphicsSceneMouseEvent;
 
74
        mouseEventType = PlatformEvent::MousePressed;
 
75
        break;
 
76
    case QEvent::GraphicsSceneMouseRelease:
 
77
        frameworkMouseEventType = GraphicsSceneMouseEvent;
 
78
        mouseEventType = PlatformEvent::MouseReleased;
 
79
        break;
 
80
    case QEvent::GraphicsSceneMouseMove:
 
81
        frameworkMouseEventType = GraphicsSceneMouseEvent;
 
82
        mouseEventType = PlatformEvent::MouseMoved;
 
83
        break;
 
84
    default:
 
85
        ASSERT_NOT_REACHED();
 
86
        frameworkMouseEventType = MouseEvent;
 
87
        mouseEventType = PlatformEvent::MouseMoved;
 
88
        break;
 
89
    }
 
90
 
 
91
    Qt::MouseButtons mouseButtons;
 
92
    switch (frameworkMouseEventType) {
 
93
    case MouseEvent: {
 
94
        const QMouseEvent* mouseEvent = static_cast<const QMouseEvent*>(event);
 
95
        mouseButtons = mouseEventType == PlatformEvent::MouseMoved ? mouseEvent->buttons() : mouseEvent->button();
 
96
        break;
 
97
    }
 
98
    case GraphicsSceneMouseEvent: {
 
99
        const QGraphicsSceneMouseEvent* mouseEvent = static_cast<const QGraphicsSceneMouseEvent*>(event);
 
100
        mouseButtons = mouseEventType == PlatformEvent::MouseMoved ? mouseEvent->buttons() : mouseEvent->button();
 
101
        break;
 
102
    }
 
103
    }
 
104
 
 
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;
 
111
    else
 
112
        mouseButton = NoButton;
 
113
}
 
114
 
 
115
class WebKitPlatformMouseEvent : public PlatformMouseEvent {
 
116
public:
 
117
    WebKitPlatformMouseEvent(QGraphicsSceneMouseEvent*, int clickCount);
 
118
    WebKitPlatformMouseEvent(QInputEvent*, int clickCount);
 
119
};
 
120
 
 
121
WebKitPlatformMouseEvent::WebKitPlatformMouseEvent(QGraphicsSceneMouseEvent* event, int clickCount)
 
122
{
 
123
    m_timestamp = WTF::currentTime();
 
124
 
 
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);
 
129
 
 
130
    m_type = type;
 
131
    m_position = IntPoint(event->pos().toPoint());
 
132
    m_globalPosition = IntPoint(event->screenPos());
 
133
 
 
134
    m_clickCount = clickCount;
 
135
    mouseEventModifiersFromQtKeyboardModifiers(event->modifiers(), m_modifiers);
 
136
}
 
137
 
 
138
WebKitPlatformMouseEvent::WebKitPlatformMouseEvent(QInputEvent* event, int clickCount)
 
139
{
 
140
    m_timestamp = WTF::currentTime();
 
141
 
 
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;
 
151
    }
 
152
#endif
 
153
    if (!isContextMenuEvent) {
 
154
        PlatformEvent::Type type;
 
155
        mouseEventTypeAndMouseButtonFromQEvent(event, type, m_button);
 
156
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
 
157
 
 
158
        m_type = type;
 
159
        m_position = IntPoint(mouseEvent->pos());
 
160
        m_globalPosition = IntPoint(mouseEvent->globalPos());
 
161
    }
 
162
 
 
163
    m_clickCount = clickCount;
 
164
    mouseEventModifiersFromQtKeyboardModifiers(event->modifiers(), m_modifiers);
 
165
}
 
166
 
 
167
PlatformMouseEvent convertMouseEvent(QInputEvent* event, int clickCount)
 
168
{
 
169
    return WebKitPlatformMouseEvent(event, clickCount);
 
170
}
 
171
 
 
172
PlatformMouseEvent convertMouseEvent(QGraphicsSceneMouseEvent* event, int clickCount)
 
173
{
 
174
    return WebKitPlatformMouseEvent(event, clickCount);
 
175
}
 
176
 
 
177
class WebKitPlatformWheelEvent : public PlatformWheelEvent {
 
178
public:
 
179
    WebKitPlatformWheelEvent(QGraphicsSceneWheelEvent*);
 
180
    WebKitPlatformWheelEvent(QWheelEvent*);
 
181
 
 
182
private:
 
183
    void applyDelta(int delta, Qt::Orientation);
 
184
};
 
185
 
 
186
void WebKitPlatformWheelEvent::applyDelta(int delta, Qt::Orientation orientation)
 
187
{
 
188
    if (orientation == Qt::Horizontal) {
 
189
        m_deltaX = delta;
 
190
        m_deltaY = 0;
 
191
    } else {
 
192
        m_deltaX = 0;
 
193
        m_deltaY = delta;
 
194
    }
 
195
    m_wheelTicksX = m_deltaX / 120.0f;
 
196
    m_wheelTicksY = m_deltaY / 120.0f;
 
197
 
 
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;
 
203
}
 
204
 
 
205
WebKitPlatformWheelEvent::WebKitPlatformWheelEvent(QGraphicsSceneWheelEvent* e)
 
206
{
 
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());
 
214
}
 
215
 
 
216
WebKitPlatformWheelEvent::WebKitPlatformWheelEvent(QWheelEvent* e)
 
217
{
 
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());
 
225
}
 
226
 
 
227
#if ENABLE(TOUCH_EVENTS)
 
228
class WebKitPlatformTouchEvent : public PlatformTouchEvent {
 
229
public:
 
230
    WebKitPlatformTouchEvent(QTouchEvent*);
 
231
};
 
232
 
 
233
class WebKitPlatformTouchPoint : public PlatformTouchPoint {
 
234
public:
 
235
    WebKitPlatformTouchPoint(const QTouchEvent::TouchPoint&, State);
 
236
};
 
237
 
 
238
WebKitPlatformTouchEvent::WebKitPlatformTouchEvent(QTouchEvent* event)
 
239
{
 
240
    switch (event->type()) {
 
241
    case QEvent::TouchBegin:
 
242
        m_type = PlatformEvent::TouchStart;
 
243
        break;
 
244
    case QEvent::TouchUpdate:
 
245
        m_type = PlatformEvent::TouchMove;
 
246
        break;
 
247
    case QEvent::TouchEnd:
 
248
        m_type = PlatformEvent::TouchEnd;
 
249
        break;
 
250
#if HAVE(QT5)
 
251
    case QEvent::TouchCancel:
 
252
        m_type = PlatformEvent::TouchCancel;
 
253
        break;
 
254
#endif
 
255
    }
 
256
 
 
257
    const QList<QTouchEvent::TouchPoint>& points = event->touchPoints();
 
258
    for (int i = 0; i < points.count(); ++i) {
 
259
        PlatformTouchPoint::State state = PlatformTouchPoint::TouchStateEnd;
 
260
 
 
261
        switch (points.at(i).state()) {
 
262
        case Qt::TouchPointReleased:
 
263
            state = PlatformTouchPoint::TouchReleased;
 
264
            break;
 
265
        case Qt::TouchPointMoved:
 
266
            state = PlatformTouchPoint::TouchMoved;
 
267
            break;
 
268
        case Qt::TouchPointPressed:
 
269
            state = PlatformTouchPoint::TouchPressed;
 
270
            break;
 
271
        case Qt::TouchPointStationary:
 
272
            state = PlatformTouchPoint::TouchStationary;
 
273
            break;
 
274
        }
 
275
 
 
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;
 
280
 
 
281
        m_touchPoints.append(WebKitPlatformTouchPoint(points.at(i), state));
 
282
    }
 
283
 
 
284
    mouseEventModifiersFromQtKeyboardModifiers(event->modifiers(), m_modifiers);
 
285
 
 
286
    m_timestamp = WTF::currentTime();
 
287
}
 
288
 
 
289
WebKitPlatformTouchPoint::WebKitPlatformTouchPoint(const QTouchEvent::TouchPoint& point, State state)
 
290
{
 
291
    // The QTouchEvent::TouchPoint API states that ids will be >= 0.
 
292
    m_id = point.id();
 
293
    m_state = state;
 
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;
 
301
    } else {
 
302
        // http://www.w3.org/TR/2011/WD-touch-events-20110505: 1 if no value is known.
 
303
        m_radiusX = 1;
 
304
        m_radiusY = 1;
 
305
    }
 
306
    m_force = point.pressure();
 
307
    // FIXME: Support m_rotationAngle if QTouchEvent at some point supports it.
 
308
}
 
309
#endif
 
310
 
 
311
#if ENABLE(GESTURE_EVENTS)
 
312
class WebKitPlatformGestureEvent : public PlatformGestureEvent {
 
313
public:
 
314
    WebKitPlatformGestureEvent(const QGestureEvent*, const QGesture*);
 
315
};
 
316
 
 
317
WebKitPlatformGestureEvent::WebKitPlatformGestureEvent(const QGestureEvent* event, const QGesture* gesture)
 
318
{
 
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());
 
325
        break;
 
326
    }
 
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());
 
332
        break;
 
333
    }
 
334
    default:
 
335
        ASSERT_NOT_REACHED();
 
336
        break;
 
337
    }
 
338
    m_timestamp = WTF::currentTime();
 
339
}
 
340
 
 
341
#endif
 
342
 
 
343
PlatformWheelEvent convertWheelEvent(QWheelEvent* event)
 
344
{
 
345
    return WebKitPlatformWheelEvent(event);
 
346
}
 
347
 
 
348
PlatformWheelEvent convertWheelEvent(QGraphicsSceneWheelEvent* event)
 
349
{
 
350
    return WebKitPlatformWheelEvent(event);
 
351
}
 
352
 
 
353
#if ENABLE(TOUCH_EVENTS)
 
354
PlatformTouchEvent convertTouchEvent(QTouchEvent* event)
 
355
{
 
356
    return WebKitPlatformTouchEvent(event);
 
357
}
 
358
#endif
 
359
 
 
360
#if ENABLE(GESTURE_EVENTS)
 
361
PlatformGestureEvent convertGesture(QGestureEvent* event, QGesture* gesture)
 
362
{
 
363
    return WebKitPlatformGestureEvent(event, gesture);
 
364
}
 
365
#endif
 
366
 
 
367
}