/*
* Copyright (C) 2010 Apple Inc. All rights reserved.
* Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "WebEventFactoryQt.h"
#include <qgraphicssceneevent.h>
#include <QApplication>
#include <QKeyEvent>
#include <WebCore/IntPoint.h>
#include <WebCore/FloatPoint.h>
#include <WebCore/PlatformKeyboardEvent.h>
#include <wtf/ASCIICType.h>
#include <wtf/CurrentTime.h>
using namespace WebCore;
namespace WebKit {
static WebMouseEvent::Button mouseButtonForEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton || (event->buttons() & Qt::LeftButton))
return WebMouseEvent::LeftButton;
else if (event->button() == Qt::RightButton || (event->buttons() & Qt::RightButton))
return WebMouseEvent::RightButton;
else if (event->button() == Qt::MidButton || (event->buttons() & Qt::MidButton))
return WebMouseEvent::MiddleButton;
return WebMouseEvent::NoButton;
}
static WebEvent::Type webEventTypeForEvent(QEvent* event)
{
switch (event->type()) {
case QEvent::GraphicsSceneMouseDoubleClick:
case QEvent::GraphicsSceneMousePress:
return WebEvent::MouseDown;
case QEvent::GraphicsSceneMouseRelease:
return WebEvent::MouseUp;
case QEvent::GraphicsSceneMouseMove:
return WebEvent::MouseMove;
case QEvent::Wheel:
return WebEvent::Wheel;
case QEvent::KeyPress:
return WebEvent::KeyDown;
case QEvent::KeyRelease:
return WebEvent::KeyUp;
#if ENABLE(TOUCH_EVENTS)
case QEvent::TouchBegin:
return WebEvent::TouchStart;
case QEvent::TouchUpdate:
return WebEvent::TouchMove;
case QEvent::TouchEnd:
return WebEvent::TouchEnd;
#endif
default:
// assert
return WebEvent::MouseMove;
}
}
static inline WebEvent::Modifiers modifiersForEvent(Qt::KeyboardModifiers modifiers)
{
unsigned result = 0;
if (modifiers & Qt::ShiftModifier)
result |= WebEvent::ShiftKey;
if (modifiers & Qt::ControlModifier)
result |= WebEvent::ControlKey;
if (modifiers & Qt::AltModifier)
result |= WebEvent::AltKey;
if (modifiers & Qt::MetaModifier)
result |= WebEvent::MetaKey;
return (WebEvent::Modifiers)result;
}
WebMouseEvent WebEventFactory::createWebMouseEvent(QGraphicsSceneMouseEvent* event, int eventClickCount)
{
FloatPoint delta(event->pos().x() - event->lastPos().x(), event->pos().y() - event->lastPos().y());
WebEvent::Type type = webEventTypeForEvent(event);
WebMouseEvent::Button button = mouseButtonForEvent(event);
float deltaX = delta.x();
float deltaY = delta.y();
int clickCount = eventClickCount;
WebEvent::Modifiers modifiers = modifiersForEvent(event->modifiers());
double timestamp = WTF::currentTime();
return WebMouseEvent(type, button, event->pos().toPoint(), event->screenPos(), deltaX, deltaY, 0.0f, clickCount, modifiers, timestamp);
}
WebWheelEvent WebEventFactory::createWebWheelEvent(QGraphicsSceneWheelEvent* e)
{
float deltaX = 0;
float deltaY = 0;
float wheelTicksX = 0;
float wheelTicksY = 0;
WebWheelEvent::Granularity granularity = WebWheelEvent::ScrollByPixelWheelEvent;
WebEvent::Modifiers modifiers = modifiersForEvent(e->modifiers());
double timestamp = WTF::currentTime();
// A delta that is not mod 120 indicates a device that is sending
// fine-resolution scroll events, so use the delta as number of wheel ticks
// and number of pixels to scroll.See also webkit.org/b/29601
bool fullTick = !(e->delta() % 120);
if (e->orientation() == Qt::Horizontal) {
deltaX = (fullTick) ? e->delta() / 120.0f : e->delta();
wheelTicksX = deltaX;
} else {
deltaY = (fullTick) ? e->delta() / 120.0f : e->delta();
wheelTicksY = deltaY;
}
// Use the same single scroll step as QTextEdit
// (in QTextEditPrivate::init [h,v]bar->setSingleStep)
static const float cDefaultQtScrollStep = 20.f;
#ifndef QT_NO_WHEELEVENT
deltaX *= (fullTick) ? QApplication::wheelScrollLines() * cDefaultQtScrollStep : 1;
deltaY *= (fullTick) ? QApplication::wheelScrollLines() * cDefaultQtScrollStep : 1;
#endif
return WebWheelEvent(WebEvent::Wheel, e->pos().toPoint(), e->screenPos(), FloatSize(deltaX, deltaY), FloatSize(wheelTicksX, wheelTicksY), granularity, modifiers, timestamp);
}
WebKeyboardEvent WebEventFactory::createWebKeyboardEvent(QKeyEvent* event)
{
const int state = event->modifiers();
WebEvent::Type type = webEventTypeForEvent(event);
const String text = event->text();
const String unmodifiedText = event->text();
bool isAutoRepeat = event->isAutoRepeat();
bool isSystemKey = false; // FIXME: No idea what that is.
bool isKeypad = (state & Qt::KeypadModifier);
const String keyIdentifier = keyIdentifierForQtKeyCode(event->key());
int windowsVirtualKeyCode = windowsKeyCodeForKeyEvent(event->key(), isKeypad);
int nativeVirtualKeyCode = event->nativeVirtualKey();
int macCharCode = 0;
WebEvent::Modifiers modifiers = modifiersForEvent(event->modifiers());
double timestamp = WTF::currentTime();
return WebKeyboardEvent(type, text, unmodifiedText, keyIdentifier, windowsVirtualKeyCode, nativeVirtualKeyCode, macCharCode, isAutoRepeat, isKeypad, isSystemKey, modifiers, timestamp);
}
#if ENABLE(TOUCH_EVENTS)
WebTouchEvent WebEventFactory::createWebTouchEvent(QTouchEvent* event)
{
WebEvent::Type type = webEventTypeForEvent(event);
WebPlatformTouchPoint::TouchPointState state = static_cast<WebPlatformTouchPoint::TouchPointState>(0);
unsigned int id;
WebEvent::Modifiers modifiers = modifiersForEvent(event->modifiers());
double timestamp = WTF::currentTime();
const QList<QTouchEvent::TouchPoint>& points = event->touchPoints();
Vector<WebPlatformTouchPoint> m_touchPoints;
for (int i = 0; i < points.count(); ++i) {
id = static_cast<unsigned>(points.at(i).id());
switch (points.at(i).state()) {
case Qt::TouchPointReleased:
state = WebPlatformTouchPoint::TouchReleased;
break;
case Qt::TouchPointMoved:
state = WebPlatformTouchPoint::TouchMoved;
break;
case Qt::TouchPointPressed:
state = WebPlatformTouchPoint::TouchPressed;
break;
case Qt::TouchPointStationary:
state = WebPlatformTouchPoint::TouchStationary;
break;
default:
ASSERT_NOT_REACHED();
break;
}
m_touchPoints.append(WebPlatformTouchPoint(id, state, points.at(i).screenPos().toPoint(), points.at(i).pos().toPoint()));
}
bool m_ctrlKey = (event->modifiers() & Qt::ControlModifier);
bool m_altKey = (event->modifiers() & Qt::AltModifier);
bool m_shiftKey = (event->modifiers() & Qt::ShiftModifier);
bool m_metaKey = (event->modifiers() & Qt::MetaModifier);
return WebTouchEvent(type, m_touchPoints, m_ctrlKey, m_altKey, m_shiftKey, m_metaKey, modifiers, timestamp);
}
#endif
} // namespace WebKit