summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/auto/macnativeevents/qnativeinput.cpp378
-rw-r--r--tests/auto/macnativeevents/qnativeinput.h228
-rw-r--r--tests/auto/macnativeevents/qnativeinput_mac.cpp382
-rw-r--r--tests/auto/macnativeevents/qnativeplayer.cpp139
-rw-r--r--tests/auto/macnativeevents/qnativeplayer.h92
-rw-r--r--tests/auto/macnativeevents/tst_macnativeevents.cpp81
-rw-r--r--tests/auto/macnativeevents/tst_macnativeevents.pro16
-rw-r--r--tests/auto/other.pro1
8 files changed, 1317 insertions, 0 deletions
diff --git a/tests/auto/macnativeevents/qnativeinput.cpp b/tests/auto/macnativeevents/qnativeinput.cpp
new file mode 100644
index 0000000..c9462a6
--- /dev/null
+++ b/tests/auto/macnativeevents/qnativeinput.cpp
@@ -0,0 +1,378 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnativeinput.h"
+
+QNativeInput::QNativeInput(bool subscribe)
+{
+ if (subscribe)
+ subscribeForNativeEvents();
+}
+
+QNativeInput::~QNativeInput()
+{
+ unsubscribeForNativeEvents();
+}
+
+void QNativeInput::notify(QNativeEvent *event)
+{
+ nativeEvent(event);
+}
+
+void QNativeInput::nativeEvent(QNativeEvent *event)
+{
+ switch (event->id()){
+ case QNativeMouseButtonEvent::eventId:{
+ QNativeMouseButtonEvent *e = static_cast<QNativeMouseButtonEvent *>(event);
+ (e->clickCount > 0) ? nativeMousePressEvent(e) : nativeMouseReleaseEvent(e);
+ break; }
+ case QNativeMouseMoveEvent::eventId:
+ nativeMouseMoveEvent(static_cast<QNativeMouseMoveEvent *>(event));
+ break;
+ case QNativeMouseDragEvent::eventId:
+ nativeMouseDragEvent(static_cast<QNativeMouseDragEvent *>(event));
+ break;
+ case QNativeMouseWheelEvent::eventId:
+ nativeMouseWheelEvent(static_cast<QNativeMouseWheelEvent *>(event));
+ break;
+ case QNativeKeyEvent::eventId:{
+ QNativeKeyEvent *e = static_cast<QNativeKeyEvent *>(event);
+ e->press ? nativeKeyPressEvent(e) : nativeKeyReleaseEvent(e);
+ break; }
+ case QNativeModifierEvent::eventId:
+ nativeModifierEvent(static_cast<QNativeModifierEvent *>(event));
+ break;
+ default:
+ break;
+ }
+}
+
+Qt::Native::Status QNativeInput::sendNativeEvent(const QNativeEvent &event, int pid)
+{
+ switch (event.id()){
+ case QNativeMouseMoveEvent::eventId:
+ return sendNativeMouseMoveEvent(static_cast<const QNativeMouseMoveEvent &>(event));
+ case QNativeMouseButtonEvent::eventId:
+ return sendNativeMouseButtonEvent(static_cast<const QNativeMouseButtonEvent &>(event));
+ case QNativeMouseDragEvent::eventId:
+ return sendNativeMouseDragEvent(static_cast<const QNativeMouseDragEvent &>(event));
+ case QNativeMouseWheelEvent::eventId:
+ return sendNativeMouseWheelEvent(static_cast<const QNativeMouseWheelEvent &>(event));
+ case QNativeKeyEvent::eventId:
+ return sendNativeKeyEvent(static_cast<const QNativeKeyEvent &>(event), pid);
+ case QNativeModifierEvent::eventId:
+ return sendNativeModifierEvent(static_cast<const QNativeModifierEvent &>(event));
+ case QNativeEvent::eventId:
+ qWarning() << "Warning: Cannot send a pure native event. Use a sub class.";
+ default:
+ return Qt::Native::Failure;
+ }
+}
+
+QNativeEvent::QNativeEvent(Qt::KeyboardModifiers modifiers)
+ : modifiers(modifiers){}
+
+QNativeMouseEvent::QNativeMouseEvent(QPoint pos, Qt::KeyboardModifiers modifiers)
+ : QNativeEvent(modifiers), globalPos(pos){}
+
+QNativeMouseMoveEvent::QNativeMouseMoveEvent(QPoint pos, Qt::KeyboardModifiers modifiers)
+ : QNativeMouseEvent(pos, modifiers){}
+
+QNativeMouseButtonEvent::QNativeMouseButtonEvent(QPoint globalPos, Qt::MouseButton button, int clickCount, Qt::KeyboardModifiers modifiers)
+ : QNativeMouseEvent(globalPos, modifiers), button(button), clickCount(clickCount){}
+
+QNativeMouseDragEvent::QNativeMouseDragEvent(QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers)
+ : QNativeMouseButtonEvent(globalPos, button, true, modifiers){}
+
+QNativeMouseWheelEvent::QNativeMouseWheelEvent(QPoint globalPos, int delta, Qt::KeyboardModifiers modifiers)
+ : QNativeMouseEvent(globalPos, modifiers), delta(delta){}
+
+QNativeKeyEvent::QNativeKeyEvent(int nativeKeyCode, bool press, Qt::KeyboardModifiers modifiers)
+ : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode), press(press), character(QChar()){}
+
+QNativeModifierEvent::QNativeModifierEvent(Qt::KeyboardModifiers modifiers, int nativeKeyCode)
+ : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode){}
+
+QNativeKeyEvent::QNativeKeyEvent(int nativeKeyCode, bool press, QChar character, Qt::KeyboardModifiers modifiers)
+ : QNativeEvent(modifiers), nativeKeyCode(nativeKeyCode), press(press), character(character){}
+
+static QString getButtonAsString(const QNativeMouseButtonEvent *e)
+{
+ switch (e->button){
+ case Qt::LeftButton:
+ return "button = LeftButton";
+ break;
+ case Qt::RightButton:
+ return "button = RightButton";
+ break;
+ case Qt::MidButton:
+ return "button = MidButton";
+ break;
+ default:
+ return "button = Other";
+ break;
+ }
+}
+
+static QString getModifiersAsString(const QNativeEvent *e)
+{
+ if (e->modifiers == 0)
+ return "modifiers = none";
+
+ QString tmp = "modifiers = ";
+ if (e->modifiers.testFlag(Qt::ShiftModifier))
+ tmp += "Shift";
+ if (e->modifiers.testFlag(Qt::ControlModifier))
+ tmp += "Control";
+ if (e->modifiers.testFlag(Qt::AltModifier))
+ tmp += "Alt";
+ if (e->modifiers.testFlag(Qt::MetaModifier))
+ tmp += "Meta";
+ return tmp;
+}
+
+static QString getPosAsString(QPoint pos)
+{
+ return QString("QPoint(%1, %2)").arg(pos.x()).arg(pos.y());
+}
+
+static QString getBoolAsString(bool b)
+{
+ return b ? QString("true") : QString("false");
+}
+
+QString QNativeMouseMoveEvent::toString() const
+{
+ return QString("QNativeMouseMoveEvent(globalPos = %1 %2)").arg(getPosAsString(globalPos))
+ .arg(getModifiersAsString(this));
+}
+
+QString QNativeMouseButtonEvent::toString() const
+{
+ return QString("QNativeMouseButtonEvent(globalPos = %1, %2, clickCount = %3, %4)").arg(getPosAsString(globalPos))
+ .arg(getButtonAsString(this)).arg(clickCount).arg(getModifiersAsString(this));
+}
+
+QString QNativeMouseDragEvent::toString() const
+{
+ return QString("QNativeMouseDragEvent(globalPos = %1, %2, clickCount = %3, %4)").arg(getPosAsString(globalPos))
+ .arg(getButtonAsString(this)).arg(clickCount).arg(getModifiersAsString(this));
+}
+
+QString QNativeMouseWheelEvent::toString() const
+{
+ return QString("QNativeMouseWheelEvent(globalPos = %1, delta = %2, %3)").arg(getPosAsString(globalPos))
+ .arg(delta).arg(getModifiersAsString(this));
+}
+
+QString QNativeKeyEvent::toString() const
+{
+ return QString("QNativeKeyEvent(press = %1, native key code = %2, character = %3, %4)").arg(getBoolAsString(press))
+ .arg(nativeKeyCode).arg(character.isPrint() ? character : QString("<no char>"))
+ .arg(getModifiersAsString(this));
+}
+
+QString QNativeModifierEvent::toString() const
+{
+ return QString("QNativeModifierEvent(%1, native key code = %2)").arg(getModifiersAsString(this))
+ .arg(nativeKeyCode);
+}
+
+QDebug operator<<(QDebug d, QNativeEvent *e)
+{
+ Q_UNUSED(e);
+ return d << e->toString();
+}
+
+QDebug operator<<(QDebug d, const QNativeEvent &e)
+{
+ Q_UNUSED(e);
+ return d << e.toString();
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeEvent *e)
+{
+ return s << e->eventId << " " << e->modifiers << " QNativeEvent";
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeMouseEvent *e)
+{
+ return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->modifiers << " " << e->toString();
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeMouseMoveEvent *e)
+{
+ return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->modifiers << " " << e->toString();
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeMouseButtonEvent *e)
+{
+ return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->button
+ << " " << e->clickCount << " " << e->modifiers << " " << e->toString();
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeMouseDragEvent *e)
+{
+ return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->button << " " << e->clickCount
+ << " " << e->modifiers << " " << e->toString();
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeMouseWheelEvent *e)
+{
+ return s << e->eventId << " " << e->globalPos.x() << " " << e->globalPos.y() << " " << e->delta
+ << " " << e->modifiers << " " << e->toString();
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeKeyEvent *e)
+{
+ return s << e->eventId << " " << e->press << " " << e->nativeKeyCode << " " << e->character
+ << " " << e->modifiers << " " << e->toString();
+}
+
+QTextStream &operator<<(QTextStream &s, QNativeModifierEvent *e)
+{
+ return s << e->eventId << " " << e->modifiers << " " << e->nativeKeyCode << " " << e->toString();
+}
+
+
+
+
+QTextStream &operator>>(QTextStream &s, QNativeMouseMoveEvent *e)
+{
+ // Skip reading eventId.
+ QString humanReadable;
+ int x, y, modifiers;
+ s >> x >> y >> modifiers >> humanReadable;
+ e->globalPos.setX(x);
+ e->globalPos.setY(y);
+ e->modifiers = Qt::KeyboardModifiers(modifiers);
+ return s;
+}
+
+QTextStream &operator>>(QTextStream &s, QNativeMouseButtonEvent *e)
+{
+ // Skip reading eventId.
+ QString humanReadable;
+ int x, y, button, clickCount, modifiers;
+ s >> x >> y >> button >> clickCount >> modifiers >> humanReadable;
+ e->globalPos.setX(x);
+ e->globalPos.setY(y);
+ e->clickCount = clickCount;
+ e->modifiers = Qt::KeyboardModifiers(modifiers);
+ switch (button){
+ case 1:
+ e->button = Qt::LeftButton;
+ break;
+ case 2:
+ e->button = Qt::RightButton;
+ break;
+ case 3:
+ e->button = Qt::MidButton;
+ break;
+ default:
+ e->button = Qt::NoButton;
+ break;
+ }
+ return s;
+}
+
+QTextStream &operator>>(QTextStream &s, QNativeMouseDragEvent *e)
+{
+ // Skip reading eventId.
+ QString humanReadable;
+ int x, y, button, clickCount, modifiers;
+ s >> x >> y >> button >> clickCount >> modifiers >> humanReadable;
+ e->globalPos.setX(x);
+ e->globalPos.setY(y);
+ e->clickCount = clickCount;
+ e->modifiers = Qt::KeyboardModifiers(modifiers);
+ switch (button){
+ case 1:
+ e->button = Qt::LeftButton;
+ break;
+ case 2:
+ e->button = Qt::RightButton;
+ break;
+ case 3:
+ e->button = Qt::MidButton;
+ break;
+ default:
+ e->button = Qt::NoButton;
+ break;
+ }
+ return s;
+}
+
+QTextStream &operator>>(QTextStream &s, QNativeMouseWheelEvent *e)
+{
+ // Skip reading eventId.
+ QString humanReadable;
+ int x, y, modifiers;
+ s >> x >> y >> e->delta >> modifiers >> humanReadable;
+ e->globalPos.setX(x);
+ e->globalPos.setY(y);
+ e->modifiers = Qt::KeyboardModifiers(modifiers);
+ return s;
+}
+
+QTextStream &operator>>(QTextStream &s, QNativeKeyEvent *e)
+{
+ // Skip reading eventId.
+ QString humanReadable;
+ int press, modifiers;
+ QString character;
+ s >> press >> e->nativeKeyCode >> character >> modifiers >> humanReadable;
+ e->press = bool(press);
+ e->character = character[0];
+ e->modifiers = Qt::KeyboardModifiers(modifiers);
+ return s;
+}
+
+QTextStream &operator>>(QTextStream &s, QNativeModifierEvent *e)
+{
+ // Skip reading eventId.
+ QString humanReadable;
+ int modifiers;
+ s >> modifiers >> e->nativeKeyCode >> humanReadable;
+ e->modifiers = Qt::KeyboardModifiers(modifiers);
+ return s;
+}
+
diff --git a/tests/auto/macnativeevents/qnativeinput.h b/tests/auto/macnativeevents/qnativeinput.h
new file mode 100644
index 0000000..a98e4e4
--- /dev/null
+++ b/tests/auto/macnativeevents/qnativeinput.h
@@ -0,0 +1,228 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q_NATIVE_INPUT
+#define Q_NATIVE_INPUT
+
+#include <QtCore>
+
+namespace Qt {
+namespace Native {
+ enum Status {Success, Failure};
+}}
+
+// ----------------------------------------------------------------------------
+// Declare a set of native events that can be used to communicate with
+// client applications in an platform independent way
+// ----------------------------------------------------------------------------
+
+class QNativeEvent
+{
+public:
+ static const int eventId = 1;
+
+ QNativeEvent(Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ virtual ~QNativeEvent(){};
+ virtual int id() const { return eventId; };
+ virtual QString toString() const = 0;
+ Qt::KeyboardModifiers modifiers; // Yields for mouse events too.
+};
+
+class QNativeMouseEvent : public QNativeEvent {
+public:
+ static const int eventId = 2;
+
+ QNativeMouseEvent(){};
+ QNativeMouseEvent(QPoint globalPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ virtual ~QNativeMouseEvent(){};
+ virtual int id() const { return eventId; };
+
+ QPoint globalPos;
+};
+
+class QNativeMouseMoveEvent : public QNativeMouseEvent {
+public:
+ static const int eventId = 4;
+
+ QNativeMouseMoveEvent(){};
+ QNativeMouseMoveEvent(QPoint globalPos, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ virtual ~QNativeMouseMoveEvent(){};
+ virtual int id() const { return eventId; };
+ virtual QString toString() const;
+};
+
+class QNativeMouseButtonEvent : public QNativeMouseEvent {
+public:
+ static const int eventId = 8;
+
+ QNativeMouseButtonEvent(){};
+ QNativeMouseButtonEvent(QPoint globalPos, Qt::MouseButton button, int clickCount, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ virtual ~QNativeMouseButtonEvent(){};
+ virtual int id() const { return eventId; };
+ virtual QString toString() const;
+
+ Qt::MouseButton button;
+ int clickCount;
+};
+
+class QNativeMouseDragEvent : public QNativeMouseButtonEvent {
+public:
+ static const int eventId = 16;
+
+ QNativeMouseDragEvent(){};
+ QNativeMouseDragEvent(QPoint globalPos, Qt::MouseButton button, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ virtual ~QNativeMouseDragEvent(){};
+ virtual int id() const { return eventId; };
+ virtual QString toString() const;
+};
+
+class QNativeMouseWheelEvent : public QNativeMouseEvent {
+public:
+ static const int eventId = 32;
+
+ QNativeMouseWheelEvent(){};
+ QNativeMouseWheelEvent(QPoint globalPos, int delta, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ virtual ~QNativeMouseWheelEvent(){};
+ virtual int id() const { return eventId; };
+ virtual QString toString() const;
+
+ int delta;
+};
+
+class QNativeKeyEvent : public QNativeEvent {
+ public:
+ static const int eventId = 64;
+
+ QNativeKeyEvent(){};
+ QNativeKeyEvent(int nativeKeyCode, bool press, Qt::KeyboardModifiers modifiers = Qt::NoModifier);
+ QNativeKeyEvent(int nativeKeyCode, bool press, QChar character, Qt::KeyboardModifiers modifiers);
+ virtual ~QNativeKeyEvent(){};
+ virtual int id() const { return eventId; };
+ virtual QString toString() const;
+
+ int nativeKeyCode;
+ bool press;
+ QChar character;
+
+ // Some Qt to Native mappings:
+ static int Key_A;
+ static int Key_B;
+ static int Key_C;
+ static int Key_1;
+ static int Key_Backspace;
+ static int Key_Enter;
+ static int Key_Del;
+};
+
+class QNativeModifierEvent : public QNativeEvent {
+public:
+ static const int eventId = 128;
+
+ QNativeModifierEvent(Qt::KeyboardModifiers modifiers = Qt::NoModifier, int nativeKeyCode = 0);
+ virtual ~QNativeModifierEvent(){};
+ virtual int id() const { return eventId; };
+ virtual QString toString() const;
+
+ int nativeKeyCode;
+};
+
+// ----------------------------------------------------------------------------
+// Declare a set of related output / input functions for convenience:
+// ----------------------------------------------------------------------------
+
+QDebug operator<<(QDebug d, QNativeEvent *e);
+QDebug operator<<(QDebug d, const QNativeEvent &e);
+
+QTextStream &operator<<(QTextStream &s, QNativeEvent *e);
+QTextStream &operator<<(QTextStream &s, QNativeMouseEvent *e);
+QTextStream &operator<<(QTextStream &s, QNativeMouseMoveEvent *e);
+QTextStream &operator<<(QTextStream &s, QNativeMouseButtonEvent *e);
+QTextStream &operator<<(QTextStream &s, QNativeMouseDragEvent *e);
+QTextStream &operator<<(QTextStream &s, QNativeMouseWheelEvent *e);
+QTextStream &operator<<(QTextStream &s, QNativeKeyEvent *e);
+QTextStream &operator<<(QTextStream &s, QNativeModifierEvent *e);
+
+QTextStream &operator>>(QTextStream &s, QNativeMouseMoveEvent *e);
+QTextStream &operator>>(QTextStream &s, QNativeMouseButtonEvent *e);
+QTextStream &operator>>(QTextStream &s, QNativeMouseDragEvent *e);
+QTextStream &operator>>(QTextStream &s, QNativeMouseWheelEvent *e);
+QTextStream &operator>>(QTextStream &s, QNativeKeyEvent *e);
+QTextStream &operator>>(QTextStream &s, QNativeModifierEvent *e);
+
+// ----------------------------------------------------------------------------
+// Declare the main class that is supposed to be sub-classed by components
+// that are to receive native events
+// ----------------------------------------------------------------------------
+
+class QNativeInput
+{
+ public:
+ QNativeInput(bool subscribe = true);
+ virtual ~QNativeInput();
+
+ // Callback methods. Should be implemented by interested sub-classes:
+ void notify(QNativeEvent *event);
+ virtual void nativeEvent(QNativeEvent *event);
+ virtual void nativeMousePressEvent(QNativeMouseButtonEvent *){};
+ virtual void nativeMouseReleaseEvent(QNativeMouseButtonEvent *){};
+ virtual void nativeMouseMoveEvent(QNativeMouseMoveEvent *){};
+ virtual void nativeMouseDragEvent(QNativeMouseDragEvent *){};
+ virtual void nativeMouseWheelEvent(QNativeMouseWheelEvent *){};
+ virtual void nativeKeyPressEvent(QNativeKeyEvent *){};
+ virtual void nativeKeyReleaseEvent(QNativeKeyEvent *){};
+ virtual void nativeModifierEvent(QNativeModifierEvent *){};
+
+ // The following methods will differ in implementation from OS to OS:
+ static Qt::Native::Status sendNativeMouseButtonEvent(const QNativeMouseButtonEvent &event);
+ static Qt::Native::Status sendNativeMouseMoveEvent(const QNativeMouseMoveEvent &event);
+ static Qt::Native::Status sendNativeMouseDragEvent(const QNativeMouseDragEvent &event);
+ static Qt::Native::Status sendNativeMouseWheelEvent(const QNativeMouseWheelEvent &event);
+ static Qt::Native::Status sendNativeKeyEvent(const QNativeKeyEvent &event, int pid = 0);
+ static Qt::Native::Status sendNativeModifierEvent(const QNativeModifierEvent &event);
+ // sendNativeEvent will NOT differ from OS to OS.
+ static Qt::Native::Status sendNativeEvent(const QNativeEvent &event, int pid = 0);
+
+ // The following methods will differ in implementation from OS to OS:
+ Qt::Native::Status subscribeForNativeEvents();
+ Qt::Native::Status unsubscribeForNativeEvents();
+};
+
+#endif // Q_NATIVE_INPUT
diff --git a/tests/auto/macnativeevents/qnativeinput_mac.cpp b/tests/auto/macnativeevents/qnativeinput_mac.cpp
new file mode 100644
index 0000000..143a633
--- /dev/null
+++ b/tests/auto/macnativeevents/qnativeinput_mac.cpp
@@ -0,0 +1,382 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnativeinput.h"
+#include <Carbon/Carbon.h>
+#include <QtCore>
+
+// ************************************************************
+// Quartz
+// ************************************************************
+
+static Qt::KeyboardModifiers getModifiersFromQuartzEvent(CGEventRef inEvent)
+{
+ Qt::KeyboardModifiers m;
+ CGEventFlags flags = CGEventGetFlags(inEvent);
+ if (flags & kCGEventFlagMaskShift || flags & kCGEventFlagMaskAlphaShift)
+ m |= Qt::ShiftModifier;
+ if (flags & kCGEventFlagMaskControl)
+ m |= Qt::MetaModifier;
+ if (flags & kCGEventFlagMaskAlternate)
+ m |= Qt::AltModifier;
+ if (flags & kCGEventFlagMaskCommand)
+ m |= Qt::ControlModifier;
+ return m;
+}
+
+static void setModifiersFromQNativeEvent(CGEventRef inEvent, const QNativeEvent &event)
+{
+ CGEventFlags flags = 0;
+ if (event.modifiers.testFlag(Qt::ShiftModifier))
+ flags |= kCGEventFlagMaskShift;
+ if (event.modifiers.testFlag(Qt::MetaModifier))
+ flags |= kCGEventFlagMaskControl;
+ if (event.modifiers.testFlag(Qt::AltModifier))
+ flags |= kCGEventFlagMaskAlternate;
+ if (event.modifiers.testFlag(Qt::ControlModifier))
+ flags |= kCGEventFlagMaskCommand;
+ CGEventSetFlags(inEvent, flags);
+}
+
+static QPoint getMouseLocationFromQuartzEvent(CGEventRef inEvent)
+{
+ CGPoint pos = CGEventGetLocation(inEvent);
+ QPoint tmp;
+ tmp.setX(pos.x);
+ tmp.setY(pos.y);
+ return tmp;
+}
+
+static QChar getCharFromQuartzEvent(CGEventRef inEvent)
+{
+ UniCharCount count = 0;
+ UniChar c;
+ CGEventKeyboardGetUnicodeString(inEvent, 1, &count, &c);
+ return QChar(c);
+}
+
+static CGEventRef EventHandler_Quartz(CGEventTapProxy proxy, CGEventType type, CGEventRef inEvent, void *refCon)
+{
+ Q_UNUSED(proxy);
+ QNativeInput *nativeInput = static_cast<QNativeInput *>(refCon);
+ switch (type){
+ case kCGEventKeyDown:{
+ QNativeKeyEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode);
+ e.character = getCharFromQuartzEvent(inEvent);
+ e.press = true;
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventKeyUp:{
+ QNativeKeyEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode);
+ e.character = getCharFromQuartzEvent(inEvent);
+ e.press = false;
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventLeftMouseDown:{
+ QNativeMouseButtonEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.globalPos = getMouseLocationFromQuartzEvent(inEvent);
+ e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState);
+ e.button = Qt::LeftButton;
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventLeftMouseUp:{
+ QNativeMouseButtonEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.globalPos = getMouseLocationFromQuartzEvent(inEvent);
+ e.clickCount = 0;
+ e.button = Qt::LeftButton;
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventRightMouseDown:{
+ QNativeMouseButtonEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.globalPos = getMouseLocationFromQuartzEvent(inEvent);
+ e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState);
+ e.button = Qt::RightButton;
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventRightMouseUp:{
+ QNativeMouseButtonEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.globalPos = getMouseLocationFromQuartzEvent(inEvent);
+ e.clickCount = 0;
+ e.button = Qt::RightButton;
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventMouseMoved:{
+ QNativeMouseMoveEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.globalPos = getMouseLocationFromQuartzEvent(inEvent);
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventLeftMouseDragged:{
+ QNativeMouseDragEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.globalPos = getMouseLocationFromQuartzEvent(inEvent);
+ e.clickCount = CGEventGetIntegerValueField(inEvent, kCGMouseEventClickState);
+ e.button = Qt::LeftButton;
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventScrollWheel:{
+ QNativeMouseWheelEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.delta = CGEventGetIntegerValueField(inEvent, kCGScrollWheelEventDeltaAxis1);
+ e.globalPos = getMouseLocationFromQuartzEvent(inEvent);
+ nativeInput->notify(&e);
+ break;
+ }
+ case kCGEventFlagsChanged:{
+ QNativeModifierEvent e;
+ e.modifiers = getModifiersFromQuartzEvent(inEvent);
+ e.nativeKeyCode = CGEventGetIntegerValueField(inEvent, kCGKeyboardEventKeycode);
+ nativeInput->notify(&e);
+ break;
+ }
+
+ }
+
+ return inEvent;
+}
+
+Qt::Native::Status insertEventHandler_Quartz(QNativeInput *nativeInput, int pid = 0)
+{
+ uid_t uid = geteuid();
+ if (uid != 0)
+ qWarning("MacNativeEvents: You must be root to listen for key events!");
+
+ CFMachPortRef port;
+ if (!pid){
+ port = CGEventTapCreate(kCGHIDEventTap,
+ kCGHeadInsertEventTap, kCGEventTapOptionListenOnly,
+ kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput);
+ } else {
+ ProcessSerialNumber psn;
+ GetProcessForPID(pid, &psn);
+ port = CGEventTapCreateForPSN(&psn,
+ kCGHeadInsertEventTap, kCGEventTapOptionListenOnly,
+ kCGEventMaskForAllEvents, EventHandler_Quartz, nativeInput);
+ }
+
+ CFRunLoopSourceRef eventSrc = CFMachPortCreateRunLoopSource(NULL, port, 0);
+ CFRunLoopAddSource((CFRunLoopRef) GetCFRunLoopFromEventLoop(GetMainEventLoop()),
+ eventSrc, kCFRunLoopCommonModes);
+
+ return Qt::Native::Success;
+}
+
+Qt::Native::Status removeEventHandler_Quartz()
+{
+ return Qt::Native::Success; // ToDo:
+}
+
+Qt::Native::Status sendNativeKeyEventToProcess_Quartz(const QNativeKeyEvent &event, int pid)
+{
+ ProcessSerialNumber psn;
+ GetProcessForPID(pid, &psn);
+
+ CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press);
+ setModifiersFromQNativeEvent(e, event);
+ SetFrontProcess(&psn);
+ CGEventPostToPSN(&psn, e);
+ CFRelease(e);
+ return Qt::Native::Success;
+}
+
+Qt::Native::Status sendNativeKeyEvent_Quartz(const QNativeKeyEvent &event)
+{
+ CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, event.press);
+ setModifiersFromQNativeEvent(e, event);
+ CGEventPost(kCGHIDEventTap, e);
+ CFRelease(e);
+ return Qt::Native::Success;
+}
+
+Qt::Native::Status sendNativeMouseMoveEvent_Quartz(const QNativeMouseMoveEvent &event)
+{
+ CGPoint pos;
+ pos.x = event.globalPos.x();
+ pos.y = event.globalPos.y();
+
+ CGEventRef e = CGEventCreateMouseEvent(0, kCGEventMouseMoved, pos, 0);
+ setModifiersFromQNativeEvent(e, event);
+ CGEventPost(kCGHIDEventTap, e);
+ CFRelease(e);
+ return Qt::Native::Success;
+}
+
+Qt::Native::Status sendNativeMouseButtonEvent_Quartz(const QNativeMouseButtonEvent &event)
+{
+ CGPoint pos;
+ pos.x = event.globalPos.x();
+ pos.y = event.globalPos.y();
+
+ CGEventType type = 0;
+ if (event.button == Qt::LeftButton)
+ type = (event.clickCount > 0) ? kCGEventLeftMouseDown : kCGEventLeftMouseUp;
+ else if (event.button == Qt::RightButton)
+ type = (event.clickCount > 0) ? kCGEventRightMouseDown : kCGEventRightMouseUp;
+ else
+ type = (event.clickCount > 0) ? kCGEventOtherMouseDown : kCGEventOtherMouseUp;
+
+ CGEventRef e = CGEventCreateMouseEvent(0, type, pos, event.button);
+ setModifiersFromQNativeEvent(e, event);
+ CGEventSetIntegerValueField(e, kCGMouseEventClickState, event.clickCount);
+ CGEventPost(kCGHIDEventTap, e);
+ CFRelease(e);
+ return Qt::Native::Success;
+}
+
+Qt::Native::Status sendNativeMouseDragEvent_Quartz(const QNativeMouseDragEvent &event)
+{
+ CGPoint pos;
+ pos.x = event.globalPos.x();
+ pos.y = event.globalPos.y();
+
+ CGEventType type = 0;
+ if (event.button == Qt::LeftButton)
+ type = kCGEventLeftMouseDragged;
+ else if (event.button == Qt::RightButton)
+ type = kCGEventRightMouseDragged;
+ else
+ type = kCGEventOtherMouseDragged;
+
+ CGEventRef e = CGEventCreateMouseEvent(0, type, pos, event.button);
+ setModifiersFromQNativeEvent(e, event);
+ CGEventPost(kCGHIDEventTap, e);
+ CFRelease(e);
+ return Qt::Native::Success;
+}
+
+Qt::Native::Status sendNativeMouseWheelEvent_Quartz(const QNativeMouseWheelEvent &event)
+{
+ CGPoint pos;
+ pos.x = event.globalPos.x();
+ pos.y = event.globalPos.y();
+
+ CGEventRef e = CGEventCreateScrollWheelEvent(0, kCGScrollEventUnitPixel, 1, 0);
+ CGEventSetIntegerValueField(e, kCGScrollWheelEventDeltaAxis1, event.delta);
+ CGEventSetLocation(e, pos);
+ setModifiersFromQNativeEvent(e, event);
+ CGEventPost(kCGHIDEventTap, e);
+ CFRelease(e);
+
+ return Qt::Native::Success;
+}
+
+Qt::Native::Status sendNativeModifierEvent_Quartz(const QNativeModifierEvent &event)
+{
+ CGEventRef e = CGEventCreateKeyboardEvent(0, (uint)event.nativeKeyCode, 0);
+ CGEventSetType(e, kCGEventFlagsChanged);
+ setModifiersFromQNativeEvent(e, event);
+ CGEventPost(kCGHIDEventTap, e);
+ CFRelease(e);
+ return Qt::Native::Success;
+}
+
+// ************************************************************
+// QNativeInput methods:
+// ************************************************************
+
+Qt::Native::Status QNativeInput::sendNativeMouseButtonEvent(const QNativeMouseButtonEvent &event)
+{
+ return sendNativeMouseButtonEvent_Quartz(event);
+}
+
+Qt::Native::Status QNativeInput::sendNativeMouseMoveEvent(const QNativeMouseMoveEvent &event)
+{
+ return sendNativeMouseMoveEvent_Quartz(event);
+}
+
+Qt::Native::Status QNativeInput::sendNativeMouseDragEvent(const QNativeMouseDragEvent &event)
+{
+ return sendNativeMouseDragEvent_Quartz(event);
+}
+
+Qt::Native::Status QNativeInput::sendNativeMouseWheelEvent(const QNativeMouseWheelEvent &event)
+{
+ return sendNativeMouseWheelEvent_Quartz(event);
+}
+
+Qt::Native::Status QNativeInput::sendNativeKeyEvent(const QNativeKeyEvent &event, int pid)
+{
+ if (!pid)
+ return sendNativeKeyEvent_Quartz(event);
+ else
+ return sendNativeKeyEventToProcess_Quartz(event, pid);
+}
+
+Qt::Native::Status QNativeInput::sendNativeModifierEvent(const QNativeModifierEvent &event)
+{
+ return sendNativeModifierEvent_Quartz(event);
+}
+
+Qt::Native::Status QNativeInput::subscribeForNativeEvents()
+{
+ return insertEventHandler_Quartz(this);
+}
+
+Qt::Native::Status QNativeInput::unsubscribeForNativeEvents()
+{
+ return removeEventHandler_Quartz();
+}
+
+// Some Qt to Mac mappings:
+int QNativeKeyEvent::Key_A = 0;
+int QNativeKeyEvent::Key_B = 11;
+int QNativeKeyEvent::Key_C = 8;
+int QNativeKeyEvent::Key_1 = 18;
+int QNativeKeyEvent::Key_Backspace = 51;
+int QNativeKeyEvent::Key_Enter = 36;
+int QNativeKeyEvent::Key_Del = 117;
+
diff --git a/tests/auto/macnativeevents/qnativeplayer.cpp b/tests/auto/macnativeevents/qnativeplayer.cpp
new file mode 100644
index 0000000..92298ef
--- /dev/null
+++ b/tests/auto/macnativeevents/qnativeplayer.cpp
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnativeplayer.h"
+
+QNativePlayer::QNativePlayer()
+{
+ currIndex = -1;
+ playbackMultiplier = 1.0;
+ wait = false;
+}
+
+QNativePlayer::~QNativePlayer()
+{
+ for (int i=0; i<eventList.size(); i++)
+ delete eventList.takeAt(i).second;
+}
+
+void QNativePlayer::sendNextEvent()
+{
+ QNativeEvent *e = eventList.at(currIndex).second;
+ if (e)
+ QNativeInput::sendNativeEvent(*e);
+ waitNextEvent();
+}
+
+void QNativePlayer::waitNextEvent()
+{
+ if (++currIndex >= eventList.size()){
+ emit done();
+ stop();
+ return;
+ }
+
+ int interval = eventList.at(currIndex).first;
+ QTimer::singleShot(interval * playbackMultiplier, this, SLOT(sendNextEvent()));
+}
+
+void QNativePlayer::append(int waitMs, QNativeEvent *event)
+{
+ eventList.append(QPair<int, QNativeEvent *>(waitMs, event));
+}
+
+void QNativePlayer::play(Playback playback)
+{
+ waitNextEvent();
+
+ wait = (playback == WaitUntilFinished);
+ while (wait)
+ QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents);
+}
+
+void QNativePlayer::stop()
+{
+ wait = false;
+ QAbstractEventDispatcher::instance()->interrupt();
+}
+
+// ************************************************************************
+
+QEventOutputList::QEventOutputList()
+{
+ wait = true;
+}
+
+QEventOutputList::~QEventOutputList()
+{
+ qDeleteAll(*this);
+}
+
+bool QEventOutputList::waitUntilEmpty(int maxEventWaitTime)
+{
+ int currSize = size();
+ QTime time;
+ time.restart();
+ while (wait){
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
+
+ if (isEmpty()){
+ return true;
+ }
+ else if (currSize == size()){
+ if (time.elapsed() > maxEventWaitTime){
+ return false;
+ }
+ }
+ else{
+ currSize = size();
+ time.restart();
+ }
+ }
+ return false;
+}
+
+void QEventOutputList::sleep(int sleepTime)
+{
+ QTime time;
+ time.restart();
+ while (time.elapsed() < sleepTime)
+ QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
+}
diff --git a/tests/auto/macnativeevents/qnativeplayer.h b/tests/auto/macnativeevents/qnativeplayer.h
new file mode 100644
index 0000000..61ee162
--- /dev/null
+++ b/tests/auto/macnativeevents/qnativeplayer.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef Q_NATIVE_PLAYBACK
+#define Q_NATIVE_PLAYBACK
+
+#include <QtCore>
+#include "qnativeinput.h"
+
+class QNativePlayer : public QObject
+{
+ Q_OBJECT;
+
+ public:
+ enum Playback {ReturnImmediately, WaitUntilFinished};
+
+ QNativePlayer();
+ ~QNativePlayer();
+
+ void append(int waitMs, QNativeEvent *event = 0);
+ void play(Playback playback = WaitUntilFinished);
+ void stop();
+ float playbackMultiplier;
+
+signals:
+ void done();
+
+private slots:
+ void sendNextEvent();
+
+ private:
+ void waitNextEvent();
+
+ QList<QPair<int, QNativeEvent *> > eventList;
+ int currIndex;
+ bool wait;
+};
+
+// ******************************************************************
+
+class QEventOutputList : public QList<QEvent *>
+{
+public:
+ QEventOutputList();
+ ~QEventOutputList();
+ bool waitUntilEmpty(int maxEventWaitTime = 1000);
+ bool wait;
+
+ // Useful method. Just sleep and process events:
+ static void sleep(int sleepTime);
+};
+
+
+#endif
diff --git a/tests/auto/macnativeevents/tst_macnativeevents.cpp b/tests/auto/macnativeevents/tst_macnativeevents.cpp
new file mode 100644
index 0000000..ccadd54
--- /dev/null
+++ b/tests/auto/macnativeevents/tst_macnativeevents.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QWidget>
+#include <QPushButton>
+#include <QtTest/QtTest>
+
+#include "qnativeinput.h"
+#include "qnativeplayer.h"
+
+#ifdef Q_OS_MAC
+
+QT_USE_NAMESPACE
+
+class tst_MacNativeEvents : public QObject
+{
+Q_OBJECT
+private slots:
+ void testLeftMousePressRelease();
+};
+
+void tst_MacNativeEvents::testLeftMousePressRelease()
+{
+ QPushButton w("click me");
+ w.show();
+ QPoint p = w.geometry().center();
+
+ QNativePlayer player;
+ player.append(50, new QNativeMouseButtonEvent(p, Qt::LeftButton, 1, Qt::NoModifier));
+ player.append(50, new QNativeMouseButtonEvent(p, Qt::LeftButton, 0, Qt::NoModifier));
+ player.play();
+}
+
+#include "tst_macnativeevents.moc"
+
+QTEST_MAIN(tst_MacNativeEvents)
+
+#else
+
+QTEST_NOOP_MAIN
+
+#endif
diff --git a/tests/auto/macnativeevents/tst_macnativeevents.pro b/tests/auto/macnativeevents/tst_macnativeevents.pro
new file mode 100644
index 0000000..a0293d4
--- /dev/null
+++ b/tests/auto/macnativeevents/tst_macnativeevents.pro
@@ -0,0 +1,16 @@
+######################################################################
+# Automatically generated by qmake (2.01a) Wed Nov 29 22:24:47 2006
+######################################################################
+
+load(qttest_p4)
+TEMPLATE = app
+DEPENDPATH += .
+INCLUDEPATH += .
+LIBS += -framework Carbon
+
+HEADERS += qnativeinput.h qnativeplayer.h
+SOURCES += qnativeinput.cpp qnativeplayer.cpp qnativeinput_mac.cpp
+
+SOURCES += tst_macnativeevents.cpp
+
+requires(mac)
diff --git a/tests/auto/other.pro b/tests/auto/other.pro
index e220d1a..3c8f856 100644
--- a/tests/auto/other.pro
+++ b/tests/auto/other.pro
@@ -37,6 +37,7 @@ SUBDIRS=\
contains(QT_CONFIG, OdfWriter):SUBDIRS += qzip qtextodfwriter
mac: {
SUBDIRS += macgui \
+ macnativeevents \
macplist \
qaccessibility_mac
}