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 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 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 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 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 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 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 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