summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/bearer/generic/qgenericengine.cpp3
-rw-r--r--src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp6
-rw-r--r--src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h3
-rw-r--r--src/plugins/generic/evdevmouse/evdevmouse.pro6
-rw-r--r--src/plugins/generic/evdevmouse/main.cpp4
-rw-r--r--src/plugins/generic/evdevmouse/qevdevmousehandler.cpp (renamed from src/plugins/generic/evdevmouse/qevdevmouse.cpp)81
-rw-r--r--src/plugins/generic/evdevmouse/qevdevmousehandler.h (renamed from src/plugins/generic/evdevmouse/qevdevmouse.h)19
-rw-r--r--src/plugins/generic/evdevmouse/qevdevmousemanager.cpp138
-rw-r--r--src/plugins/generic/evdevmouse/qevdevmousemanager.h (renamed from src/plugins/platforms/uikit/quikitintegration.h)44
-rw-r--r--src/plugins/generic/evdevtouch/qevdevtouch.cpp14
-rw-r--r--src/plugins/platforms/cocoa/cocoa.pro12
-rw-r--r--src/plugins/platforms/cocoa/qcocoaclipboard.h (renamed from src/plugins/platforms/uikit/quikitscreen.h)35
-rw-r--r--src/plugins/platforms/cocoa/qcocoaclipboard.mm (renamed from src/plugins/platforms/uikit/main.mm)57
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoahelpers.mm62
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.h (renamed from src/plugins/platforms/uikit/quikitsoftwareinputhandler.h)27
-rw-r--r--src/plugins/platforms/cocoa/qcocoainputcontext.mm122
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.h9
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm33
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.h21
-rw-r--r--src/plugins/platforms/cocoa/qcocoanativeinterface.mm15
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintersupport.h (renamed from src/plugins/platforms/uikit/quikiteventloop.h)36
-rw-r--r--src/plugins/platforms/cocoa/qcocoaprintersupport.mm116
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.h3
-rw-r--r--src/plugins/platforms/cocoa/qcocoatheme.mm2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h22
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm318
-rw-r--r--src/plugins/platforms/cocoa/qmacclipboard.mm100
-rw-r--r--src/plugins/platforms/cocoa/qmacmime.h3
-rw-r--r--src/plugins/platforms/cocoa/qmacmime.mm22
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h5
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm349
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm8
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac.mm1788
-rw-r--r--src/plugins/platforms/cocoa/qpaintengine_mac_p.h254
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac.mm817
-rw-r--r--src/plugins/platforms/cocoa/qprintengine_mac_p.h160
-rw-r--r--src/plugins/platforms/cocoa/qt_mac_p.h2
-rw-r--r--src/plugins/platforms/eglfs/eglfs.json3
-rw-r--r--src/plugins/platforms/eglfs/eglfs.pro6
-rw-r--r--src/plugins/platforms/eglfs/main.cpp6
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.h1
-rw-r--r--src/plugins/platforms/uikit/README45
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/main.mm78
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qml/main.qml112
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp110
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp179
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h80
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist28
-rwxr-xr-xsrc/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj491
-rw-r--r--src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch8
-rw-r--r--src/plugins/platforms/uikit/quikiteventloop.mm174
-rw-r--r--src/plugins/platforms/uikit/quikitintegration.mm104
-rw-r--r--src/plugins/platforms/uikit/quikitscreen.mm84
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.h131
-rw-r--r--src/plugins/platforms/uikit/quikitwindow.mm392
-rw-r--r--src/plugins/platforms/uikit/quikitwindowsurface.mm133
-rw-r--r--src/plugins/platforms/uikit/uikit.pro27
-rw-r--r--src/plugins/platforms/vnc/qvnccursor.cpp156
-rw-r--r--src/plugins/platforms/vnc/qvnccursor.h76
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.cpp255
-rw-r--r--src/plugins/platforms/vnc/qvncintegration.h111
-rw-r--r--src/plugins/platforms/vnc/qvncserver.cpp1935
-rw-r--r--src/plugins/platforms/vnc/qvncserver.h533
-rw-r--r--src/plugins/platforms/vnc/vnc.pro22
-rw-r--r--src/plugins/platforms/windows/accessible/accessible.pri19
-rw-r--r--src/plugins/platforms/windows/accessible/comutils.cpp641
-rw-r--r--src/plugins/platforms/windows/accessible/comutils.h (renamed from src/plugins/platforms/uikit/quikitwindowsurface.h)31
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp1467
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.h379
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp319
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsaccessibility.h (renamed from src/plugins/platforms/windows/qwindowsaccessibility.h)9
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp (renamed from src/plugins/platforms/windows/qwindowsaccessibility.cpp)526
-rw-r--r--src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h139
-rw-r--r--src/plugins/platforms/windows/qtwindows_additional.h10
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp5
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp12
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp13
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase_ft.h3
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.cpp14
-rw-r--r--src/plugins/platforms/windows/qwindowsintegration.h3
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp24
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.h5
-rw-r--r--src/plugins/platforms/windows/windows.pro3
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp18
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h8
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp5
-rw-r--r--src/plugins/platforms/xlib/qglxintegration.cpp1
-rw-r--r--src/plugins/platforms/xlib/qxlibkeyboard.cpp4
-rw-r--r--src/plugins/platforms/xlib/qxlibwindow.cpp10
-rw-r--r--src/plugins/platforms/xlib/xlib.pro1
-rw-r--r--src/plugins/plugins.pro2
-rw-r--r--src/plugins/printsupport/cocoa/cocoa.json3
-rw-r--r--src/plugins/printsupport/cocoa/cocoa.pro13
-rw-r--r--src/plugins/printsupport/cocoa/main.cpp (renamed from src/plugins/platforms/vnc/main.cpp)47
-rw-r--r--src/plugins/printsupport/printsupport.pro1
97 files changed, 7514 insertions, 6229 deletions
diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp
index 7b30b5d64c..5682d113ef 100644
--- a/src/plugins/bearer/generic/qgenericengine.cpp
+++ b/src/plugins/bearer/generic/qgenericengine.cpp
@@ -147,6 +147,9 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf
QGenericEngine::QGenericEngine(QObject *parent)
: QBearerEngineImpl(parent)
{
+ //workaround for deadlock in __cxa_guard_acquire with webkit on macos x
+ //initialise the Q_GLOBAL_STATIC in same thread as the AtomicallyInitializedStatic
+ (void)QNetworkInterface::interfaceFromIndex(0);
}
QGenericEngine::~QGenericEngine()
diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp
index f9237e3325..73aa6419d3 100644
--- a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp
+++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.cpp
@@ -62,8 +62,8 @@ QT_BEGIN_NAMESPACE
// simple builtin US keymap
#include "qevdevkeyboard_defaultmap.h"
-QEvdevKeyboardHandler::QEvdevKeyboardHandler(int deviceDescriptor, const QString &device, bool disableZap, bool enableCompose, const QString &keymapFile)
- : m_fd(deviceDescriptor), m_device(device),
+QEvdevKeyboardHandler::QEvdevKeyboardHandler(int deviceDescriptor, bool disableZap, bool enableCompose, const QString &keymapFile)
+ : m_fd(deviceDescriptor),
m_modifiers(0), m_composing(0), m_dead_unicode(0xffff),
m_no_zap(disableZap), m_do_compose(enableCompose),
m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0)
@@ -136,7 +136,7 @@ QEvdevKeyboardHandler *QEvdevKeyboardHandler::createLinuxInputKeyboardHandler(co
::ioctl(fd, EVIOCSREP, kbdrep);
}
- return new QEvdevKeyboardHandler(fd, device, disableZap, enableCompose, keymapFile);
+ return new QEvdevKeyboardHandler(fd, disableZap, enableCompose, keymapFile);
} else {
qWarning("Cannot open keyboard input device '%s': %s", qPrintable(device), strerror(errno));
return 0;
diff --git a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h
index 76b5c5703b..5a1253857f 100644
--- a/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h
+++ b/src/plugins/generic/evdevkeyboard/qevdevkeyboardhandler.h
@@ -125,7 +125,7 @@ class QEvdevKeyboardHandler : public QObject
{
Q_OBJECT
public:
- QEvdevKeyboardHandler(int deviceDescriptor, const QString &device, bool disableZap, bool enableCompose, const QString &keymapFile);
+ QEvdevKeyboardHandler(int deviceDescriptor, bool disableZap, bool enableCompose, const QString &keymapFile);
~QEvdevKeyboardHandler();
enum KeycodeAction {
@@ -174,7 +174,6 @@ private:
void switchLed(int, bool);
int m_fd;
- QString m_device;
// keymap handling
quint8 m_modifiers;
diff --git a/src/plugins/generic/evdevmouse/evdevmouse.pro b/src/plugins/generic/evdevmouse/evdevmouse.pro
index 781d901f28..f322a5bd1a 100644
--- a/src/plugins/generic/evdevmouse/evdevmouse.pro
+++ b/src/plugins/generic/evdevmouse/evdevmouse.pro
@@ -5,12 +5,14 @@ DESTDIR = $$QT.gui.plugins/generic
target.path = $$[QT_INSTALL_PLUGINS]/generic
INSTALLS += target
-HEADERS = qevdevmouse.h
+HEADERS = qevdevmousehandler.h \
+ qevdevmousemanager.h
QT += core-private platformsupport-private
SOURCES = main.cpp \
- qevdevmouse.cpp
+ qevdevmousehandler.cpp \
+ qevdevmousemanager.cpp
OTHER_FILES += \
evdevmouse.json
diff --git a/src/plugins/generic/evdevmouse/main.cpp b/src/plugins/generic/evdevmouse/main.cpp
index 47a4ddf56b..b49c183d7b 100644
--- a/src/plugins/generic/evdevmouse/main.cpp
+++ b/src/plugins/generic/evdevmouse/main.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include <qgenericplugin_qpa.h>
-#include "qevdevmouse.h"
+#include "qevdevmousemanager.h"
QT_BEGIN_NAMESPACE
@@ -71,7 +71,7 @@ QObject* QEvdevMousePlugin::create(const QString &key,
const QString &specification)
{
if (!key.compare(QLatin1String("EvdevMouse"), Qt::CaseInsensitive))
- return new QEvdevMouseHandler(key, specification);
+ return new QEvdevMouseManager(key, specification);
return 0;
}
diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.cpp b/src/plugins/generic/evdevmouse/qevdevmousehandler.cpp
index be779c68a5..1821c2b06b 100644
--- a/src/plugins/generic/evdevmouse/qevdevmouse.cpp
+++ b/src/plugins/generic/evdevmouse/qevdevmousehandler.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "qevdevmouse.h"
+#include "qevdevmousehandler.h"
#include <QSocketNotifier>
#include <QStringList>
@@ -48,7 +48,7 @@
#include <qplatformdefs.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
-#include <QtPlatformSupport/private/qudevhelper_p.h>
+#include <QtPlatformSupport/private/qudevicehelper_p.h>
#include <errno.h>
@@ -57,61 +57,82 @@
#include <qdebug.h>
+//#define QT_QPA_MOUSE_HANDLER_DEBUG
+
QT_BEGIN_NAMESPACE
-QEvdevMouseHandler::QEvdevMouseHandler(const QString &key,
- const QString &specification)
- : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0),
- m_xoffset(0), m_yoffset(0), m_buttons(0)
+QEvdevMouseHandler *QEvdevMouseHandler::createLinuxInputMouseHandler(const QString &key, const QString &specification)
{
- Q_UNUSED(key);
- setObjectName(QLatin1String("Evdev Mouse Handler"));
-
- QString dev;
- q_udev_devicePath(UDev_Mouse | UDev_Touchpad, &dev);
- if (dev.isEmpty())
- dev = QLatin1String("/dev/input/event0");
-
- m_compression = true;
- m_smooth = false;
+#ifdef QT_QPA_MOUSE_HANDLER_DEBUG
+ qWarning() << "Try to create mouse handler with" << key << specification;
+#else
+ Q_UNUSED(key)
+#endif
+
+ QString device = "/dev/input/event0";
+ bool compression = true;
+ bool smooth = false;
int jitterLimit = 0;
+ int xoffset = 0;
+ int yoffset = 0;
QStringList args = specification.split(QLatin1Char(':'));
foreach (const QString &arg, args) {
if (arg == "nocompress")
- m_compression = false;
+ compression = false;
else if (arg.startsWith("dejitter="))
jitterLimit = arg.mid(9).toInt();
else if (arg.startsWith("xoffset="))
- m_xoffset = arg.mid(8).toInt();
+ xoffset = arg.mid(8).toInt();
else if (arg.startsWith("yoffset="))
- m_yoffset = arg.mid(8).toInt();
+ yoffset = arg.mid(8).toInt();
else if (arg.startsWith(QLatin1String("/dev/")))
- dev = arg;
+ device = arg;
}
- m_jitterLimitSquared = jitterLimit*jitterLimit;
- qDebug("evdevmouse: Using device %s", qPrintable(dev));
- m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
- if (m_fd >= 0) {
- m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
- connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
+#ifdef QT_QPA_MOUSE_HANDLER_DEBUG
+ qDebug("evdevmouse: Using device %s", qPrintable(device));
+#endif
+
+ int fd;
+ fd = qt_safe_open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0);
+ if (fd >= 0) {
+ return new QEvdevMouseHandler(fd, compression, smooth, jitterLimit, xoffset, yoffset);
} else {
- qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno));
- return;
+ qWarning("Cannot open mouse input device '%s': %s", qPrintable(device), strerror(errno));
+ return 0;
}
}
+QEvdevMouseHandler::QEvdevMouseHandler(int deviceDescriptor, bool compression, bool smooth, int jitterLimit, int xoffset, int yoffset)
+ : m_notify(0), m_x(0), m_y(0), m_prevx(0), m_prevy(0),
+ m_fd(deviceDescriptor), m_compression(compression), m_smooth(smooth),
+ m_xoffset(xoffset), m_yoffset(yoffset), m_buttons(0)
+{
+ setObjectName(QLatin1String("Evdev Mouse Handler"));
+
+ m_jitterLimitSquared = jitterLimit * jitterLimit;
+
+ // socket notifier for events on the mouse device
+ QSocketNotifier *notifier;
+ notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), this, SLOT(readMouseData()));
+}
+
QEvdevMouseHandler::~QEvdevMouseHandler()
{
if (m_fd >= 0)
- QT_CLOSE(m_fd);
+ qt_safe_close(m_fd);
}
void QEvdevMouseHandler::sendMouseEvent()
{
QPoint pos(m_x + m_xoffset, m_y + m_yoffset);
- //qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(m_buttons));
+
+#ifdef QT_QPA_MOUSE_HANDLER_DEBUG
+ qDebug("mouse event %d %d %d", pos.x(), pos.y(), int(m_buttons));
+#endif
+
QWindowSystemInterface::handleMouseEvent(0, pos, pos, m_buttons);
m_prevx = m_x;
m_prevy = m_y;
diff --git a/src/plugins/generic/evdevmouse/qevdevmouse.h b/src/plugins/generic/evdevmouse/qevdevmousehandler.h
index 9542d133f2..7a74eaa701 100644
--- a/src/plugins/generic/evdevmouse/qevdevmouse.h
+++ b/src/plugins/generic/evdevmouse/qevdevmousehandler.h
@@ -39,8 +39,8 @@
**
****************************************************************************/
-#ifndef QEVDEVMOUSE_H
-#define QEVDEVMOUSE_H
+#ifndef QEVDEVMOUSEHANDLER_H
+#define QEVDEVMOUSEHANDLER_H
#include <QObject>
#include <QString>
@@ -55,25 +55,26 @@ class QEvdevMouseHandler : public QObject
{
Q_OBJECT
public:
- QEvdevMouseHandler(const QString &key, const QString &specification);
+ static QEvdevMouseHandler *createLinuxInputMouseHandler(const QString &key, const QString &specification);
~QEvdevMouseHandler();
private slots:
void readMouseData();
private:
+ QEvdevMouseHandler(int deviceDescriptor, bool compression, bool smooth, int jitterLimit, int xoffset, int yoffset);
+
void sendMouseEvent();
- void pathFromUdev(QString *path);
QSocketNotifier *m_notify;
- int m_fd;
int m_x, m_y;
int m_prevx, m_prevy;
- int m_xoffset, m_yoffset;
- int m_smoothx, m_smoothy;
- Qt::MouseButtons m_buttons;
+ int m_fd;
bool m_compression;
bool m_smooth;
+ int m_xoffset, m_yoffset;
+ Qt::MouseButtons m_buttons;
+ int m_smoothx, m_smoothy;
int m_jitterLimitSquared;
};
@@ -81,4 +82,4 @@ QT_END_NAMESPACE
QT_END_HEADER
-#endif // QEVDEVMOUSE_H
+#endif // QEVDEVMOUSEHANDLER_H
diff --git a/src/plugins/generic/evdevmouse/qevdevmousemanager.cpp b/src/plugins/generic/evdevmouse/qevdevmousemanager.cpp
new file mode 100644
index 0000000000..f8e77abe55
--- /dev/null
+++ b/src/plugins/generic/evdevmouse/qevdevmousemanager.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qevdevmousemanager.h"
+
+#include <QStringList>
+#include <QCoreApplication>
+
+//#define QT_QPA_MOUSEMANAGER_DEBUG
+
+#ifdef QT_QPA_MOUSEMANAGER_DEBUG
+#include <QDebug>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+QEvdevMouseManager::QEvdevMouseManager(const QString &key, const QString &specification)
+{
+ Q_UNUSED(key);
+
+ bool useUDev = true;
+ QStringList args = specification.split(QLatin1Char(':'));
+ QStringList devices;
+
+ foreach (const QString &arg, args) {
+ if (arg.startsWith("udev") && arg.contains("no")) {
+ useUDev = false;
+ } else if (arg.startsWith("/dev/")) {
+ // if device is specified try to use it
+ devices.append(arg);
+ args.removeAll(arg);
+ }
+ }
+
+ // build new specification without /dev/ elements
+ m_spec = args.join(":");
+
+ // add all mice for devices specified in the argument list
+ foreach (const QString &device, devices)
+ addMouse(device);
+
+ if (useUDev) {
+#ifdef QT_QPA_MOUSEMANAGER_DEBUG
+ qWarning() << "Use UDev for device discovery";
+#endif
+
+ m_udeviceHelper = QUDeviceHelper::createUDeviceHelper(QUDeviceHelper::UDev_Mouse | QUDeviceHelper::UDev_Touchpad, this);
+ if (m_udeviceHelper) {
+ // scan and add already connected keyboards
+ QStringList devices = m_udeviceHelper->scanConnectedDevices();
+ foreach (QString device, devices) {
+ addMouse(device);
+ }
+
+ connect(m_udeviceHelper, SIGNAL(deviceDetected(QString,QUDeviceTypes)), this, SLOT(addMouse(QString)));
+ connect(m_udeviceHelper, SIGNAL(deviceRemoved(QString,QUDeviceTypes)), this, SLOT(removeMouse(QString)));
+ }
+ }
+}
+
+QEvdevMouseManager::~QEvdevMouseManager()
+{
+ qDeleteAll(m_mice);
+ m_mice.clear();
+}
+
+void QEvdevMouseManager::addMouse(const QString &deviceNode)
+{
+#ifdef QT_QPA_MOUSEMANAGER_DEBUG
+ qWarning() << "Adding mouse at" << deviceNode;
+#endif
+
+ QString specification = m_spec;
+
+ if (!deviceNode.isEmpty()) {
+ specification.append(":");
+ specification.append(deviceNode);
+ }
+
+ QEvdevMouseHandler *handler;
+ handler = QEvdevMouseHandler::createLinuxInputMouseHandler("EvdevMouse", specification);
+ if (handler)
+ m_mice.insert(deviceNode, handler);
+ else
+ qWarning("Failed to open mouse");
+}
+
+void QEvdevMouseManager::removeMouse(const QString &deviceNode)
+{
+ if (m_mice.contains(deviceNode)) {
+#ifdef QT_QPA_MOUSEMANAGER_DEBUG
+ qWarning() << "Removing mouse at" << deviceNode;
+#endif
+ QEvdevMouseHandler *handler = m_mice.value(deviceNode);
+ m_mice.remove(deviceNode);
+ delete handler;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitintegration.h b/src/plugins/generic/evdevmouse/qevdevmousemanager.h
index 21ef9efb29..a42257b6a2 100644
--- a/src/plugins/platforms/uikit/quikitintegration.h
+++ b/src/plugins/generic/evdevmouse/qevdevmousemanager.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,34 +39,40 @@
**
****************************************************************************/
-#ifndef QPLATFORMINTEGRATION_UIKIT_H
-#define QPLATFORMINTEGRATION_UIKIT_H
+#ifndef QEVDEVMOUSEMANAGER_H
+#define QEVDEVMOUSEMANAGER_H
-#include <QtGui/QPlatformIntegration>
+#include "qevdevmousehandler.h"
-QT_BEGIN_NAMESPACE
+#include <QtPlatformSupport/private/qudevicehelper_p.h>
-class QUIKitIntegration : public QPlatformIntegration
-{
-public:
- QUIKitIntegration();
- ~QUIKitIntegration();
+#include <QObject>
+#include <QHash>
+#include <QSocketNotifier>
- QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
+QT_BEGIN_HEADER
- QList<QPlatformScreen *> screens() const;
+QT_BEGIN_NAMESPACE
- QPlatformFontDatabase *fontDatabase() const;
+class QEvdevMouseManager : public QObject
+{
+ Q_OBJECT
+public:
+ explicit QEvdevMouseManager(const QString &key, const QString &specification);
+ ~QEvdevMouseManager();
- QPlatformEventLoopIntegration *createEventLoopIntegration() const;
+private slots:
+ void addMouse(const QString &deviceNode = QString());
+ void removeMouse(const QString &deviceNode);
private:
- QList<QPlatformScreen *> mScreens;
+ QString m_spec;
+ QHash<QString,QEvdevMouseHandler*> m_mice;
+ QUDeviceHelper *m_udeviceHelper;
};
-QT_END_NAMESPACE
+QT_END_HEADER
-#endif
+QT_END_NAMESPACE
+#endif // QEVDEVMOUSEMANAGER_H
diff --git a/src/plugins/generic/evdevtouch/qevdevtouch.cpp b/src/plugins/generic/evdevtouch/qevdevtouch.cpp
index 9e6347457d..b702807cab 100644
--- a/src/plugins/generic/evdevtouch/qevdevtouch.cpp
+++ b/src/plugins/generic/evdevtouch/qevdevtouch.cpp
@@ -46,7 +46,7 @@
#include <QGuiApplication>
#include <QDebug>
#include <QtCore/private/qcore_unix_p.h>
-#include <QtPlatformSupport/private/qudevhelper_p.h>
+#include <QtPlatformSupport/private/qudevicehelper_p.h>
#include <linux/input.h>
#ifdef USE_MTDEV
@@ -146,7 +146,17 @@ QTouchScreenHandler::QTouchScreenHandler(const QString &spec)
setObjectName(QLatin1String("Evdev Touch Handler"));
QString dev;
- q_udev_devicePath(UDev_Touchpad | UDev_Touchscreen, &dev);
+
+ // try to let udev scan for already connected devices
+ QScopedPointer<QUDeviceHelper> udeviceHelper(QUDeviceHelper::createUDeviceHelper(QUDeviceHelper::UDev_Touchpad | QUDeviceHelper::UDev_Touchscreen, this));
+ if (udeviceHelper) {
+ QStringList devices = udeviceHelper->scanConnectedDevices();
+
+ // only the first device found is used for now
+ if (devices.size() > 0)
+ dev = devices[0];
+ }
+
if (dev.isEmpty())
dev = QLatin1String("/dev/input/event0");
diff --git a/src/plugins/platforms/cocoa/cocoa.pro b/src/plugins/platforms/cocoa/cocoa.pro
index b953210720..e861f48e7b 100644
--- a/src/plugins/platforms/cocoa/cocoa.pro
+++ b/src/plugins/platforms/cocoa/cocoa.pro
@@ -27,10 +27,15 @@ OBJECTIVE_SOURCES += main.mm \
qcocoafiledialoghelper.mm \
qcocoafontdialoghelper.mm \
qcocoacursor.mm \
+ qcocoaclipboard.mm \
qcocoadrag.mm \
qmacclipboard.mm \
qmacmime.mm \
qcocoasystemsettings.mm \
+ qcocoainputcontext.mm \
+ qpaintengine_mac.mm \
+ qprintengine_mac.mm \
+ qcocoaprintersupport.mm \
HEADERS += qcocoaintegration.h \
qcocoatheme.h \
@@ -55,17 +60,22 @@ HEADERS += qcocoaintegration.h \
qcocoafiledialoghelper.h \
qcocoafontdialoghelper.h \
qcocoacursor.h \
+ qcocoaclipboard.h \
qcocoadrag.h \
qmacclipboard.h \
qmacmime.h \
qcocoasystemsettings.h \
+ qcocoainputcontext.h \
+ qpaintengine_mac_p.h \
+ qprintengine_mac_p.h \
+ qcocoaprintersupport.h \
FORMS += $$PWD/../../../widgets/dialogs/qfiledialog.ui
RESOURCES += qcocoaresources.qrc
LIBS += -framework Cocoa
-QT += core-private gui-private widgets-private platformsupport-private
+QT += core-private gui-private widgets-private platformsupport-private printsupport
OTHER_FILES += cocoa.json
target.path += $$[QT_INSTALL_PLUGINS]/platforms
diff --git a/src/plugins/platforms/uikit/quikitscreen.h b/src/plugins/platforms/cocoa/qcocoaclipboard.h
index e53589b2c7..27505058bf 100644
--- a/src/plugins/platforms/uikit/quikitscreen.h
+++ b/src/plugins/platforms/cocoa/qcocoaclipboard.h
@@ -39,37 +39,32 @@
**
****************************************************************************/
-#ifndef QUIKITSCREEN_H
-#define QUIKITSCREEN_H
+#ifndef QCOCOACLIPBOARD_H
+#define QCOCOACLIPBOARD_H
-#include <UIKit/UIKit.h>
-
-#include <QtGui/QPlatformScreen>
+#include <qplatformclipboard_qpa.h>
+#include "qmacclipboard.h"
+#include <QtCore/QScopedPointer>
QT_BEGIN_NAMESPACE
-class QUIKitScreen : public QPlatformScreen
+class QCocoaClipboard : public QPlatformClipboard
{
public:
- QUIKitScreen(int screenIndex);
- ~QUIKitScreen();
-
- QRect geometry() const { return m_geometry; }
- int depth() const { return m_depth; }
- QImage::Format format() const { return m_format; }
- QSizeF physicalSize() const { return m_physicalSize; }
+ QCocoaClipboard();
- UIScreen *uiScreen() const;
+ QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard);
+ void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard);
+ bool supportsMode(QClipboard::Mode mode) const;
+ bool ownsMode(QClipboard::Mode mode) const;
+protected:
+ QMacPasteboard *pasteboardForMode(QClipboard::Mode mode) const;
private:
- QRect m_geometry;
- int m_depth;
- QImage::Format m_format;
- QSizeF m_physicalSize;
- int m_index;
+ QScopedPointer<QMacPasteboard> m_clipboard;
+ QScopedPointer<QMacPasteboard> m_find;
};
QT_END_NAMESPACE
-
#endif
diff --git a/src/plugins/platforms/uikit/main.mm b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
index db413c0775..799fb85183 100644
--- a/src/plugins/platforms/uikit/main.mm
+++ b/src/plugins/platforms/cocoa/qcocoaclipboard.mm
@@ -39,36 +39,55 @@
**
****************************************************************************/
-#include <UIKit/UIKit.h>
-
-#include <QtGui/QPlatformIntegrationPlugin>
-#include "quikitintegration.h"
+#include "QCocoaclipboard.h"
+#include "qmacmime.h"
+#include "qmacclipboard.h"
QT_BEGIN_NAMESPACE
-class QUIKitIntegrationPlugin : public QPlatformIntegrationPlugin
+QCocoaClipboard::QCocoaClipboard()
+ :m_clipboard(new QMacPasteboard(kPasteboardClipboard, QMacPasteboardMime::MIME_CLIP))
+ ,m_find(new QMacPasteboard(kPasteboardFind, QMacPasteboardMime::MIME_CLIP))
{
-public:
- QStringList keys() const;
- QPlatformIntegration *create(const QString&, const QStringList&);
-};
-QStringList QUIKitIntegrationPlugin::keys() const
+}
+
+QMimeData *QCocoaClipboard::mimeData(QClipboard::Mode mode)
{
- QStringList list;
- list << "UIKit";
- return list;
+ if (QMacPasteboard *pasteBoard = pasteboardForMode(mode)) {
+ pasteBoard->sync();
+ return pasteBoard->mimeData();
+ }
+ return 0;
}
-QPlatformIntegration * QUIKitIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+void QCocoaClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
{
- Q_UNUSED(paramList);
- if (system.toLower() == "uikit")
- return new QUIKitIntegration;
+ if (QMacPasteboard *pasteBoard = pasteboardForMode(mode)) {
+ pasteBoard->sync();
+ pasteBoard->setMimeData(data);
+ emitChanged(mode);
+ }
+}
- return 0;
+bool QCocoaClipboard::supportsMode(QClipboard::Mode mode) const
+{
+ return (mode == QClipboard::Clipboard || mode == QClipboard::FindBuffer);
+}
+
+bool QCocoaClipboard::ownsMode(QClipboard::Mode mode) const
+{
+ return false;
}
-Q_EXPORT_PLUGIN2(UIKit, QUIKitIntegrationPlugin)
+QMacPasteboard *QCocoaClipboard::pasteboardForMode(QClipboard::Mode mode) const
+{
+ if (mode == QClipboard::Clipboard)
+ return m_clipboard.data();
+ else if (mode == QClipboard::FindBuffer)
+ return m_find.data();
+ else
+ return 0;
+}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h
index 3e3e8fa507..5113aca3f7 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.h
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.h
@@ -74,6 +74,15 @@ NSImage *qt_mac_create_nsimage(const QPixmap &pm);
NSSize qt_mac_toNSSize(const QSize &qtSize);
+QColor qt_mac_toQColor(const NSColor *color);
+
+// Creates a mutable shape, it's the caller's responsibility to release.
+HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion &region);
+
+OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage);
+
+CGFloat qt_mac_get_scalefactor();
+
QChar qt_mac_qtKey2CocoaKey(Qt::Key key);
Qt::Key qt_mac_cocoaKey2QtKey(QChar keyCode);
diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm
index ec4399b66c..60590b966e 100644
--- a/src/plugins/platforms/cocoa/qcocoahelpers.mm
+++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm
@@ -132,11 +132,46 @@ NSImage *qt_mac_create_nsimage(const QPixmap &pm)
return qt_mac_cgimage_to_nsimage(qt_mac_image_to_cgimage(image));
}
+HIMutableShapeRef qt_mac_QRegionToHIMutableShape(const QRegion &region)
+{
+ HIMutableShapeRef shape = HIShapeCreateMutable();
+ QVector<QRect> rects = region.rects();
+ if (!rects.isEmpty()) {
+ int n = rects.count();
+ const QRect *qt_r = rects.constData();
+ while (n--) {
+ CGRect cgRect = CGRectMake(qt_r->x(), qt_r->y(), qt_r->width(), qt_r->height());
+ HIShapeUnionWithRect(shape, &cgRect);
+ ++qt_r;
+ }
+ }
+ return shape;
+}
+
NSSize qt_mac_toNSSize(const QSize &qtSize)
{
return NSMakeSize(qtSize.width(), qtSize.height());
}
+QColor qt_mac_toQColor(const NSColor *color)
+{
+ QColor qtColor;
+ NSString *colorSpace = [color colorSpaceName];
+ if (colorSpace == NSDeviceCMYKColorSpace) {
+ CGFloat cyan, magenta, yellow, black, alpha;
+ [color getCyan:&cyan magenta:&magenta yellow:&yellow black:&black alpha:&alpha];
+ qtColor.setCmykF(cyan, magenta, yellow, black, alpha);
+ } else {
+ NSColor *tmpColor;
+ tmpColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
+ CGFloat red, green, blue, alpha;
+ [tmpColor getRed:&red green:&green blue:&blue alpha:&alpha];
+ qtColor.setRgbF(red, green, blue, alpha);
+ }
+ return qtColor;
+}
+
+
// Use this method to keep all the information in the TextSegment. As long as it is ordered
// we are in OK shape, and we can influence that ourselves.
struct KeyPair
@@ -519,4 +554,31 @@ NSRect qt_mac_flipRect(const QRect &rect, QWindow *window)
return NSMakeRect(rect.x(), flippedY, rect.width(), rect.height());
}
+OSStatus qt_mac_drawCGImage(CGContextRef inContext, const CGRect *inBounds, CGImageRef inImage)
+{
+ // Verbatim copy if HIViewDrawCGImage (as shown on Carbon-Dev)
+ OSStatus err = noErr;
+
+ require_action(inContext != NULL, InvalidContext, err = paramErr);
+ require_action(inBounds != NULL, InvalidBounds, err = paramErr);
+ require_action(inImage != NULL, InvalidImage, err = paramErr);
+
+ CGContextSaveGState( inContext );
+ CGContextTranslateCTM (inContext, 0, inBounds->origin.y + CGRectGetMaxY(*inBounds));
+ CGContextScaleCTM(inContext, 1, -1);
+
+ CGContextDrawImage(inContext, *inBounds, inImage);
+
+ CGContextRestoreGState(inContext);
+InvalidImage:
+InvalidBounds:
+InvalidContext:
+ return err;
+}
+
+CGFloat qt_mac_get_scalefactor()
+{
+ return [[NSScreen mainScreen] userSpaceScaleFactor];
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitsoftwareinputhandler.h b/src/plugins/platforms/cocoa/qcocoainputcontext.h
index b4627c15ff..172c87e2dc 100644
--- a/src/plugins/platforms/uikit/quikitsoftwareinputhandler.h
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.h
@@ -1,5 +1,3 @@
-
-
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
@@ -41,21 +39,32 @@
**
****************************************************************************/
-#ifndef QUIKITSOFTWAREINPUTHANDLER_H
-#define QUIKITSOFTWAREINPUTHANDLER_H
+#ifndef QCOCOAINPUTCONTEXT_H
+#define QCOCOAINPUTCONTEXT_H
-#include <QtCore/QObject>
+#include <QtGui/QPlatformInputContext>
+#include <QtCore/QPointer>
QT_BEGIN_NAMESPACE
-class QUIKitSoftwareInputHandler : public QObject
+class QCocoaInputContext : public QPlatformInputContext
{
Q_OBJECT
-
public:
- bool eventFilter(QObject *obj, QEvent *event);
+ explicit QCocoaInputContext();
+ ~QCocoaInputContext();
+
+ virtual bool isValid() const { return true; }
+
+ virtual void reset();
+
+private Q_SLOTS:
+ void inputItemChanged();
+
+private:
+ QPointer<QWindow> mWindow;
};
QT_END_NAMESPACE
-#endif
+#endif // QCOCOAINPUTCONTEXT_H
diff --git a/src/plugins/platforms/cocoa/qcocoainputcontext.mm b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
new file mode 100644
index 0000000000..db3488a0f5
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoainputcontext.mm
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qnsview.h"
+#include "qcocoainputcontext.h"
+#include "qcocoanativeinterface.h"
+#include "qcocoaautoreleasepool.h"
+
+#include <QtCore/QRect>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QWindow>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QCocoaInputContext
+ \brief Cocoa Input context implementation
+
+ Handles input of foreign characters (particularly East Asian)
+ languages.
+
+ \section1 Testing
+
+ \list
+ \o Select input sources like 'Kotoeri' in Language & Text Preferences
+ \o Compile the \a mainwindows/mdi example and open a text window.
+ \o In the language bar, switch to 'Hiragana'.
+ \o In a text editor control, type the syllable \a 'la'.
+ Underlined characters show up, indicating that there is completion
+ available. Press the Space key two times. A completion popup occurs
+ which shows the options.
+ \endlist
+
+ \section1 Interaction
+
+ Input method support in Cocoa uses NSTextInput protorol. Therefore
+ almost all functionality is implemented in QNSView.
+
+ \ingroup qt-lighthouse-cocoa
+*/
+
+
+
+QCocoaInputContext::QCocoaInputContext()
+ : QPlatformInputContext()
+ , mWindow(QGuiApplication::focusWindow())
+{
+ connect(qApp->inputMethod(), SIGNAL(inputItemChanged()), this, SLOT(inputItemChanged()));
+}
+
+QCocoaInputContext::~QCocoaInputContext()
+{
+}
+
+/*!
+ \brief Cancels a composition.
+*/
+
+void QCocoaInputContext::reset()
+{
+ QPlatformInputContext::reset();
+
+ if (!mWindow) return;
+
+ QCocoaNativeInterface *nativeInterface = qobject_cast<QCocoaNativeInterface *>(QGuiApplication::platformNativeInterface());
+ if (!nativeInterface) return;
+
+ QNSView *view = static_cast<QNSView *>(nativeInterface->nativeResourceForWindow("nsview", mWindow));
+ if (!view) return;
+
+ QCocoaAutoReleasePool pool;
+ NSInputManager *currentIManager = [NSInputManager currentInputManager];
+ if (currentIManager) {
+ [currentIManager markedTextAbandoned:view];
+ [view unmarkText];
+ }
+}
+
+void QCocoaInputContext::inputItemChanged()
+{
+ mWindow = QGuiApplication::focusWindow();
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h
index bf54915365..97e7a7ffde 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.h
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.h
@@ -46,6 +46,7 @@
#include "qcocoaautoreleasepool.h"
#include "qcocoacursor.h"
+#include "qcocoaclipboard.h"
#include "qcocoadrag.h"
#include <QtCore/QScopedPointer>
@@ -89,18 +90,24 @@ public:
QPlatformFontDatabase *fontDatabase() const;
QPlatformNativeInterface *nativeInterface() const;
+ QPlatformInputContext *inputContext() const;
QPlatformAccessibility *accessibility() const;
+ QPlatformClipboard *clipboard() const;
QPlatformDrag *drag() const;
- QPlatformTheme *platformTheme() const;
+ QStringList themeNames() const;
+ QPlatformTheme *createPlatformTheme(const QString &name) const;
+
private:
QScopedPointer<QPlatformFontDatabase> mFontDb;
QAbstractEventDispatcher *mEventDispatcher;
+ QScopedPointer<QPlatformInputContext> mInputContext;
QScopedPointer<QPlatformAccessibility> mAccessibility;
QScopedPointer<QPlatformTheme> mPlatformTheme;
QList<QCocoaScreen *> mScreens;
+ QCocoaClipboard *mCocoaClipboard;
QScopedPointer<QCocoaDrag> mCocoaDrag;
};
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 8411a795c1..f5febd4a16 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -52,6 +52,7 @@
#include "qmenu_mac.h"
#include "qcocoafiledialoghelper.h"
#include "qcocoatheme.h"
+#include "qcocoainputcontext.h"
#include "qmacmime.h"
#include <QtGui/qplatformaccessibility_qpa.h>
@@ -90,8 +91,9 @@ QCocoaScreen::~QCocoaScreen()
QCocoaIntegration::QCocoaIntegration()
: mFontDb(new QCoreTextFontDatabase())
, mEventDispatcher(new QCocoaEventDispatcher())
+ , mInputContext(new QCocoaInputContext)
, mAccessibility(new QPlatformAccessibility)
- , mPlatformTheme(new QCocoaTheme)
+ , mCocoaClipboard(new QCocoaClipboard)
, mCocoaDrag(new QCocoaDrag)
{
QCocoaAutoReleasePool pool;
@@ -139,13 +141,19 @@ QCocoaIntegration::QCocoaIntegration()
screenAdded(screen);
}
- QMacPasteboardMime::initialize();
+ QMacPasteboardMime::initializeMimeTypes();
}
QCocoaIntegration::~QCocoaIntegration()
{
[[NSApplication sharedApplication] setDelegate: 0];
+ // Delete the clipboard integration and destroy mime type converters.
+ // Deleting the clipboard integration flushes promised pastes using
+ // the mime converters - the ordering here is important.
+ delete mCocoaClipboard;
+ QMacPasteboardMime::destroyMimeTypes();
+
// Delete screens in reverse order to avoid crash in case of multiple screens
while (!mScreens.isEmpty()) {
delete mScreens.takeLast();
@@ -195,19 +203,36 @@ QPlatformNativeInterface *QCocoaIntegration::nativeInterface() const
return new QCocoaNativeInterface();
}
+QPlatformInputContext *QCocoaIntegration::inputContext() const
+{
+ return mInputContext.data();
+}
+
QPlatformAccessibility *QCocoaIntegration::accessibility() const
{
return mAccessibility.data();
}
+QPlatformClipboard *QCocoaIntegration::clipboard() const
+{
+ return mCocoaClipboard;
+}
+
QPlatformDrag *QCocoaIntegration::drag() const
{
return mCocoaDrag.data();
}
-QPlatformTheme *QCocoaIntegration::platformTheme() const
+QStringList QCocoaIntegration::themeNames() const
+{
+ return QStringList(QLatin1String(QCocoaTheme::name));
+}
+
+QPlatformTheme *QCocoaIntegration::createPlatformTheme(const QString &name) const
{
- return mPlatformTheme.data();
+ if (name == QLatin1String(QCocoaTheme::name))
+ return new QCocoaTheme;
+ return QPlatformIntegration::createPlatformTheme(name);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.h b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
index 7c6fb38577..8856e90cf3 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.h
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.h
@@ -43,13 +43,34 @@
#define QCOCOANATIVEINTERFACE_H
#include <QtGui/QPlatformNativeInterface>
+#include <QtPrintSupport/QPlatformPrinterSupport>
class QWidget;
class QCocoaNativeInterface : public QPlatformNativeInterface
{
+ Q_OBJECT
public:
void *nativeResourceForWindow(const QByteArray &resourceString, QWindow *window);
+
+private:
+ /*
+ "Virtual" function to create the platform printer support
+ implementation.
+
+ We use an invokable function instead of a virtual one, we do not want
+ this in the QPlatform* API yet.
+
+ This was added here only because QPlatformNativeInterface is a QObject
+ and allow us to use QMetaObject::indexOfMethod() from the printsupport
+ plugin.
+ */
+ Q_INVOKABLE QPlatformPrinterSupport *createPlatformPrinterSupport();
+ /*
+ Function to return the NSPrintInfo * from QMacPaintEnginePrivate.
+ Needed by the native print dialog in the QtPrintSupport library.
+ */
+ Q_INVOKABLE void *NSPrintInfoForPrintEngine(QPrintEngine *printEngine);
};
#endif // QCOCOANATIVEINTERFACE_H
diff --git a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
index 443369df75..29c2e58959 100644
--- a/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
+++ b/src/plugins/platforms/cocoa/qcocoanativeinterface.mm
@@ -42,6 +42,8 @@
#include "qcocoanativeinterface.h"
#include "qcocoaglcontext.h"
#include "qcocoawindow.h"
+#include "qcocoaprintersupport.h"
+
#include <qbytearray.h>
#include <qwindow.h>
#include "qplatformwindow_qpa.h"
@@ -50,6 +52,8 @@
#include "qopenglcontext.h"
#include <qdebug.h>
+#include "qprintengine_mac_p.h"
+
void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceString, QWindow *window)
{
if (!window->handle()) {
@@ -66,3 +70,14 @@ void *QCocoaNativeInterface::nativeResourceForWindow(const QByteArray &resourceS
}
return 0;
}
+
+QPlatformPrinterSupport *QCocoaNativeInterface::createPlatformPrinterSupport()
+{
+ return new QCocoaPrinterSupport();
+}
+
+void *QCocoaNativeInterface::NSPrintInfoForPrintEngine(QPrintEngine *printEngine)
+{
+ QMacPrintEngine *macPrintEngine = static_cast<QMacPrintEngine *>(printEngine);
+ return macPrintEngine->d_func()->printInfo;
+}
diff --git a/src/plugins/platforms/uikit/quikiteventloop.h b/src/plugins/platforms/cocoa/qcocoaprintersupport.h
index e7f503c42a..db473dfabb 100644
--- a/src/plugins/platforms/uikit/quikiteventloop.h
+++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtPrintSupport module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,34 +39,22 @@
**
****************************************************************************/
-#ifndef QUIKITEVENTLOOP_H
-#define QUIKITEVENTLOOP_H
+#ifndef QCOCOAPRINTERSUPPORT_H
+#define QCOCOAPRINTERSUPPORT_H
-#include "quikitsoftwareinputhandler.h"
+#include <QtPrintSupport/QPlatformPrinterSupport>
-#include <QtCore/QEvent>
-#include <QtGui/QPlatformEventLoopIntegration>
-
-@class EventLoopHelper;
-@class NSTimer;
-
-QT_BEGIN_NAMESPACE
-
-class QUIKitEventLoop : public QPlatformEventLoopIntegration
+class QCocoaPrinterSupport : public QPlatformPrinterSupport
{
public:
- QUIKitEventLoop();
- ~QUIKitEventLoop();
+ QCocoaPrinterSupport();
+ ~QCocoaPrinterSupport();
- void startEventLoop();
- void quitEventLoop();
- void qtNeedsToProcessEvents();
+ Q_DECL_OVERRIDE QPrintEngine *createNativePrintEngine(QPrinter::PrinterMode printerMode);
+ Q_DECL_OVERRIDE QPaintEngine *createPaintEngine(QPrintEngine *, QPrinter::PrinterMode printerMode);
+ Q_DECL_OVERRIDE QList<QPrinter::PaperSize> supportedPaperSizes(const QPrinterInfo &) const;
- EventLoopHelper *mHelper;
- NSTimer *mTimer;
- QUIKitSoftwareInputHandler *mInputHandler;
+ Q_DECL_OVERRIDE QList<QPrinterInfo> availablePrinters();
};
-QT_END_NAMESPACE
-
-#endif
+#endif // QCOCOAPRINTERSUPPORT_H
diff --git a/src/plugins/platforms/cocoa/qcocoaprintersupport.mm b/src/plugins/platforms/cocoa/qcocoaprintersupport.mm
new file mode 100644
index 0000000000..6653c81a4a
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qcocoaprintersupport.mm
@@ -0,0 +1,116 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtPrintSupport module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qcocoaprintersupport.h"
+#include "qprintengine_mac_p.h"
+
+#include <QtPrintSupport/QPrinter>
+#include <QtPrintSupport/QPrinterInfo>
+
+QCocoaPrinterSupport::QCocoaPrinterSupport()
+{ }
+
+QCocoaPrinterSupport::~QCocoaPrinterSupport()
+{ }
+
+QPrintEngine *QCocoaPrinterSupport::createNativePrintEngine(QPrinter::PrinterMode printerMode)
+{
+ return new QMacPrintEngine(printerMode);
+}
+
+QPaintEngine *QCocoaPrinterSupport::createPaintEngine(QPrintEngine *printEngine, QPrinter::PrinterMode printerMode)
+{
+ Q_UNUSED(printerMode);
+ /*
+ QMacPrintEngine multiply inherits from QPrintEngine and QPaintEngine,
+ the cast here allows conversion of QMacPrintEngine* to QPaintEngine*
+ */
+ return static_cast<QMacPrintEngine *>(printEngine);
+}
+
+QList<QPrinter::PaperSize> QCocoaPrinterSupport::supportedPaperSizes(const QPrinterInfo &printerInfo) const
+{
+ QList<QPrinter::PaperSize> returnValue;
+ if (printerInfo.isNull())
+ return returnValue;
+
+ PMPrinter printer = PMPrinterCreateFromPrinterID(QCFString::toCFStringRef(printerInfo.printerName()));
+ if (!printer)
+ return returnValue;
+
+ CFArrayRef array;
+ if (PMPrinterGetPaperList(printer, &array) != noErr) {
+ PMRelease(printer);
+ return returnValue;
+ }
+
+ CFIndex count = CFArrayGetCount(array);
+ for (CFIndex i = 0; i < count; ++i) {
+ PMPaper paper = static_cast<PMPaper>(const_cast<void *>(CFArrayGetValueAtIndex(array, i)));
+ double width, height;
+ if (PMPaperGetWidth(paper, &width) == noErr
+ && PMPaperGetHeight(paper, &height) == noErr) {
+ // width and height are in points, convertQSizeFToPaperSize() expects millimeters
+ static const double OnePointInMillimeters = 1.0 / 72.0 * 25.4;
+ QSizeF size(width * OnePointInMillimeters, height * OnePointInMillimeters);
+ returnValue += QPlatformPrinterSupport::convertQSizeFToPaperSize(size);
+ }
+ }
+
+ PMRelease(printer);
+
+ return returnValue;
+}
+
+QList<QPrinterInfo> QCocoaPrinterSupport::availablePrinters()
+{
+ QList<QPrinterInfo> returnValue;
+ QCFType<CFArrayRef> printerList;
+ if (PMServerCreatePrinterList(kPMServerLocal, &printerList) == noErr) {
+ CFIndex count = CFArrayGetCount(printerList);
+ for (CFIndex i = 0; i < count; ++i) {
+ PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i)));
+ QString printerName = QCFString::toQString(PMPrinterGetName(printer));
+ returnValue += QPlatformPrinterSupport::printerInfo(printerName, PMPrinterIsDefault(printer));
+ }
+ }
+ return returnValue;
+}
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.h b/src/plugins/platforms/cocoa/qcocoatheme.h
index 030db1822c..5cb6f7437d 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.h
+++ b/src/plugins/platforms/cocoa/qcocoatheme.h
@@ -64,6 +64,9 @@ public:
const QFont *font(Font type = SystemFont) const;
QVariant themeHint(ThemeHint hint) const;
+
+ static const char *name;
+
private:
mutable QPalette *m_systemPalette;
mutable QHash<QPlatformTheme::Palette, QPalette*> m_palettes;
diff --git a/src/plugins/platforms/cocoa/qcocoatheme.mm b/src/plugins/platforms/cocoa/qcocoatheme.mm
index 8ec6e3801e..d17ee30096 100644
--- a/src/plugins/platforms/cocoa/qcocoatheme.mm
+++ b/src/plugins/platforms/cocoa/qcocoatheme.mm
@@ -49,6 +49,8 @@
QT_BEGIN_NAMESPACE
+const char *QCocoaTheme::name = "cocoa";
+
QCocoaTheme::QCocoaTheme()
:m_systemPalette(0)
{
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index ba56a8991d..8bdb5535d5 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -49,17 +49,17 @@
#include "qcocoaglcontext.h"
#include "qnsview.h"
+class QCocoaWindow;
@interface QNSWindow : NSWindow {
-
+ @public QCocoaWindow *m_cocoaPlatformWindow;
}
- (BOOL)canBecomeKeyWindow;
-
@end
@interface QNSPanel : NSPanel {
-
+ @public QCocoaWindow *m_cocoaPlatformWindow;
}
- (BOOL)canBecomeKeyWindow;
@end
@@ -93,6 +93,7 @@ public:
void setGeometry(const QRect &rect);
void setVisible(bool visible);
+ Qt::WindowFlags setWindowFlags(Qt::WindowFlags flags);
void setWindowTitle(const QString &title);
void raise();
void lower();
@@ -101,8 +102,11 @@ public:
bool setMouseGrabEnabled(bool grab);
WId winId() const;
+ void setParent(const QPlatformWindow *window);
+
NSView *contentView() const;
+ void windowWillMove();
void windowDidMove();
void windowDidResize();
void windowWillClose();
@@ -111,8 +115,12 @@ public:
QCocoaGLContext *currentContext() const;
protected:
- void determineWindowClass();
- NSWindow *createWindow();
+ // NSWindow handling. The QCocoaWindow/QNSView can either be displayed
+ // in an existing NSWindow or in one created by Qt.
+ NSWindow *createNSWindow();
+ void setNSWindow(NSWindow *window);
+ void clearNSWindow(NSWindow *window);
+
QRect windowGeometry() const;
QCocoaWindow *parentCocoaWindow() const;
@@ -123,9 +131,9 @@ public: // for QNSView
QNSView *m_contentView;
QNSWindow *m_nsWindow;
+ Qt::WindowFlags m_windowFlags;
+ QPointer<QWindow> m_activePopupWindow;
- quint32 m_windowAttributes;
- quint32 m_windowClass;
bool m_inConstructor;
QCocoaGLContext *m_glContext;
};
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 3f566ccb44..5c30e7f38b 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -58,73 +58,56 @@
- (BOOL)canBecomeKeyWindow
{
-
// The default implementation returns NO for title-bar less windows,
// override and return yes here to make sure popup windows such as
// the combobox popup can become the key window.
return YES;
}
+- (BOOL)canBecomeMainWindow
+{
+ BOOL canBecomeMain = YES; // By default, windows can become the main window
+
+ // Windows with a transient parent (such as combobox popup windows)
+ // cannot become the main window:
+ if (m_cocoaPlatformWindow->window()->transientParent())
+ canBecomeMain = NO;
+
+ return canBecomeMain;
+}
+
+
@end
@implementation QNSPanel
- (BOOL)canBecomeKeyWindow
{
- return YES;
+ return NO;
}
@end
QCocoaWindow::QCocoaWindow(QWindow *tlw)
: QPlatformWindow(tlw)
- , m_windowAttributes(0)
- , m_windowClass(0)
, m_glContext(0)
, m_inConstructor(true)
{
QCocoaAutoReleasePool pool;
- determineWindowClass();
- m_nsWindow = createWindow();
-
- QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
- [m_nsWindow setDelegate:delegate];
- [m_nsWindow setAcceptsMouseMovedEvents:YES];
-
- // Prevent Cocoa from releasing the window on close. Qt
- // handles the close event asynchronously and we want to
- // make sure that m_nsWindow stays valid until the
- // QCocoaWindow is deleted by Qt.
- [m_nsWindow setReleasedWhenClosed : NO];
-
m_contentView = [[QNSView alloc] initWithQWindow:tlw platformWindow:this];
-
- [[NSNotificationCenter defaultCenter] addObserver:m_contentView
- selector:@selector(windowDidBecomeKey)
- name:NSWindowDidBecomeKeyNotification
- object:m_nsWindow];
-
- [[NSNotificationCenter defaultCenter] addObserver:m_contentView
- selector:@selector(windowDidResignKey)
- name:NSWindowDidResignKeyNotification
- object:m_nsWindow];
-
- // ### Accept touch events by default.
- // Beware that enabling touch events has a negative impact on the overall performance.
- // We probably need a QWindowSystemInterface API to enable/disable touch events.
- [m_contentView setAcceptsTouchEvents:YES];
-
setGeometry(tlw->geometry());
- [m_nsWindow setContentView:m_contentView];
+ m_nsWindow = createNSWindow();
+ setNSWindow(m_nsWindow);
+
m_inConstructor = false;
}
QCocoaWindow::~QCocoaWindow()
{
- [[NSNotificationCenter defaultCenter] removeObserver:m_contentView];
[m_contentView release];
+ clearNSWindow(m_nsWindow);
[m_nsWindow release];
}
@@ -146,23 +129,44 @@ void QCocoaWindow::setVisible(bool visible)
{
QCocoaAutoReleasePool pool;
#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
- qDebug() << "QCocoaWindow::setVisible" << this << visible;
+ qDebug() << "QCocoaWindow::setVisible" << window() << visible;
#endif
if (visible) {
- // The parent window might have moved while this window was hidden,
- // update the window geometry if there is a parent.
- if (window()->transientParent())
+ if (window()->transientParent()) {
+ // The parent window might have moved while this window was hidden,
+ // update the window geometry if there is a parent.
setGeometry(window()->geometry());
+ // Register popup windows so that the parent window can
+ // close them when needed.
+ if (window()->windowType() == Qt::Popup) {
+ // qDebug() << "transientParent and popup" << window()->windowType() << Qt::Popup << (window()->windowType() & Qt::Popup);
+
+ QCocoaWindow *parentCocoaWindow = static_cast<QCocoaWindow *>(window()->transientParent()->handle());
+ parentCocoaWindow->m_activePopupWindow = window();
+ }
+
+ }
+
// Make sure the QWindow has a frame ready before we show the NSWindow.
QWindowSystemInterface::handleSynchronousExposeEvent(window(), QRect(QPoint(), geometry().size()));
- [m_nsWindow makeKeyAndOrderFront:nil];
+ if ([m_nsWindow canBecomeKeyWindow])
+ [m_nsWindow makeKeyAndOrderFront:nil];
+ else
+ [m_nsWindow orderFront: nil];
} else {
- [m_nsWindow orderOut:nil];
+ // qDebug() << "close" << this;
+ [m_nsWindow orderOut:m_nsWindow];
}
}
+Qt::WindowFlags QCocoaWindow::setWindowFlags(Qt::WindowFlags flags)
+{
+ m_windowFlags = flags;
+ return m_windowFlags;
+}
+
void QCocoaWindow::setWindowTitle(const QString &title)
{
QCocoaAutoReleasePool pool;
@@ -174,13 +178,14 @@ void QCocoaWindow::setWindowTitle(const QString &title)
void QCocoaWindow::raise()
{
+ //qDebug() << "raise" << this;
// ### handle spaces (see Qt 4 raise_sys in qwidget_mac.mm)
[m_nsWindow orderFront: m_nsWindow];
}
void QCocoaWindow::lower()
{
- [m_nsWindow orderFront: m_nsWindow];
+ [m_nsWindow orderBack: m_nsWindow];
}
void QCocoaWindow::propagateSizeHints()
@@ -229,11 +234,31 @@ WId QCocoaWindow::winId() const
return WId(m_nsWindow);
}
+void QCocoaWindow::setParent(const QPlatformWindow *window)
+{
+ // recreate the window for compatibility
+ clearNSWindow(m_nsWindow);
+ [m_nsWindow close];
+ [m_nsWindow release];
+
+ m_nsWindow = createNSWindow();
+ setNSWindow(m_nsWindow);
+}
+
NSView *QCocoaWindow::contentView() const
{
return [m_nsWindow contentView];
}
+void QCocoaWindow::windowWillMove()
+{
+ // Close any open popups on window move
+ if (m_activePopupWindow) {
+ QWindowSystemInterface::handleSynchronousCloseEvent(m_activePopupWindow);
+ m_activePopupWindow = 0;
+ }
+}
+
void QCocoaWindow::windowDidMove()
{
[m_contentView updateGeometry];
@@ -261,156 +286,95 @@ QCocoaGLContext *QCocoaWindow::currentContext() const
return m_glContext;
}
-/*
- Determine the window class based on the window type and
- window flags, and widget attr Sets m_windowAttributes
- and m_windowClass.
-*/
-void QCocoaWindow::determineWindowClass()
+NSWindow * QCocoaWindow::createNSWindow()
{
+ QCocoaAutoReleasePool pool;
+
+ NSRect frame = qt_mac_flipRect(window()->geometry(), window());
+
Qt::WindowType type = window()->windowType();
Qt::WindowFlags flags = window()->windowFlags();
- const bool popup = (type == Qt::Popup);
-
- if (type == Qt::ToolTip || type == Qt::SplashScreen || popup)
- flags |= Qt::FramelessWindowHint;
-
- m_windowClass = kSheetWindowClass;
-
- if (popup || type == Qt::SplashScreen)
- m_windowClass = kModalWindowClass;
- else if (type == Qt::ToolTip)
- m_windowClass = kHelpWindowClass;
- else if (type == Qt::Tool)
- m_windowClass = kFloatingWindowClass;
- else
- m_windowClass = kDocumentWindowClass;
-
- m_windowAttributes = (kWindowCompositingAttribute | kWindowStandardHandlerAttribute);
-
-// if(qt_mac_is_macsheet(window())) {
-// m_windowClass = kSheetWindowClass;
-// } else
-
- {
- // Shift things around a bit to get the correct window class based on the presence
- // (or lack) of the border.
-
- bool customize = flags & Qt::CustomizeWindowHint;
- bool framelessWindow = (flags & Qt::FramelessWindowHint || (customize && !(flags & Qt::WindowTitleHint)));
- if (framelessWindow) {
- if (m_windowClass == kDocumentWindowClass) {
- m_windowAttributes |= kWindowNoTitleBarAttribute;
- } else if (m_windowClass == kFloatingWindowClass) {
- m_windowAttributes |= kWindowNoTitleBarAttribute;
- } else if (m_windowClass == kMovableModalWindowClass) {
- m_windowClass = kModalWindowClass;
- }
- } else {
- m_windowAttributes |= NSTitledWindowMask;
- if (m_windowClass != kModalWindowClass)
- m_windowAttributes |= NSResizableWindowMask;
- }
+ NSUInteger styleMask;
+ NSWindow *createdWindow = 0;
- // Only add extra decorations (well, buttons) for widgets that can have them
- // and have an actual border we can put them on.
-
- if(m_windowClass != kModalWindowClass && m_windowClass != kMovableModalWindowClass
- && m_windowClass != kSheetWindowClass && m_windowClass != kPlainWindowClass
- && !framelessWindow && m_windowClass != kDrawerWindowClass
- && m_windowClass != kHelpWindowClass) {
- if (flags & Qt::WindowMinimizeButtonHint)
- m_windowAttributes |= NSMiniaturizableWindowMask;
- if (flags & Qt::WindowSystemMenuHint || flags & Qt::WindowCloseButtonHint)
- m_windowAttributes |= NSClosableWindowMask;
+ // Use NSPanel for popup-type windows. (Popup, Tool, ToolTip, SplashScreen)
+ if ((type & Qt::Popup) == Qt::Popup) {
+ if (type == Qt::Popup || type == Qt::ToolTip || type == Qt::SplashScreen) {
+ styleMask = NSBorderlessWindowMask;
} else {
- // Clear these hints so that we aren't call them on invalid windows
- flags &= ~(Qt::WindowMaximizeButtonHint | Qt::WindowMinimizeButtonHint
- | Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint);
+ styleMask = (NSUtilityWindowMask | NSResizableWindowMask | NSClosableWindowMask |
+ NSMiniaturizableWindowMask | NSTitledWindowMask);
}
+ QNSPanel *window;
+ window = [[QNSPanel alloc] initWithContentRect:frame
+ styleMask: styleMask
+ backing:NSBackingStoreBuffered
+ defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
+ // before the window is shown and needs a proper window.).
+ [window setHasShadow:YES];
+ createdWindow = window;
+ } else {
+ styleMask = (NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask);
+ QNSWindow *window;
+ window = [[QNSWindow alloc] initWithContentRect:frame
+ styleMask: styleMask
+ backing:NSBackingStoreBuffered
+ defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
+ // before the window is shown and needs a proper window.).
+ window->m_cocoaPlatformWindow = this;
+ createdWindow = window;
}
-
- if((popup || type == Qt::Tool) && !window()->isModal())
- m_windowAttributes |= kWindowHideOnSuspendAttribute;
- m_windowAttributes |= kWindowLiveResizeAttribute;
+ return createdWindow;
}
-/*
-
-*/
-NSWindow * QCocoaWindow::createWindow()
+void QCocoaWindow::setNSWindow(NSWindow *window)
{
- // Determine if we need to add in our "custom window" attribute. Cocoa is rather clever
- // in deciding if we need the maximize button or not (i.e., it's resizable, so you
- // must need a maximize button). So, the only buttons we have control over are the
- // close and minimize buttons. If someone wants to customize and NOT have the maximize
- // button, then we have to do our hack. We only do it for these cases because otherwise
- // the window looks different when activated. This "QtMacCustomizeWindow" attribute is
- // intruding on a public space and WILL BREAK in the future.
- // One can hope that there is a more public API available by that time.
-/*
- Qt::WindowFlags flags = widget ? widget->windowFlags() : Qt::WindowFlags(0);
- if ((flags & Qt::CustomizeWindowHint)) {
- if ((flags & (Qt::WindowCloseButtonHint | Qt::WindowSystemMenuHint
- | Qt::WindowMinimizeButtonHint | Qt::WindowTitleHint))
- && !(flags & Qt::WindowMaximizeButtonHint))
- wattr |= QtMacCustomizeWindow;
- }
-*/
- NSRect frame = qt_mac_flipRect(window()->geometry(), window());
- QCocoaAutoReleasePool pool;
- NSWindow *window;
-
- switch (m_windowClass) {
- case kMovableModalWindowClass:
- case kModalWindowClass:
- case kSheetWindowClass:
- case kFloatingWindowClass:
- case kOverlayWindowClass:
- case kHelpWindowClass: {
- NSPanel *panel;
-
- BOOL needFloating = NO;
- //BOOL worksWhenModal = (this->window()->windowType() == Qt::Popup);
-
- // Add in the extra flags if necessary.
- switch (m_windowClass) {
- case kSheetWindowClass:
- m_windowAttributes |= NSDocModalWindowMask;
- break;
- case kFloatingWindowClass:
- case kHelpWindowClass:
- needFloating = YES;
- m_windowAttributes |= NSUtilityWindowMask;
- break;
- default:
- break;
- }
+ QNSWindowDelegate *delegate = [[QNSWindowDelegate alloc] initWithQCocoaWindow:this];
+ [window setDelegate:delegate];
+ [window setAcceptsMouseMovedEvents:YES];
- panel = [[QNSPanel alloc] initWithContentRect:frame
- styleMask:m_windowAttributes
- backing:NSBackingStoreBuffered
- defer:NO]; // see window case below
-// ### crashes
-// [panel setFloatingPanel:needFloating];
-// [panel setWorksWhenModal:worksWhenModal];
- window = static_cast<NSWindow *>(panel);
- break;
- }
- default:
- window = [[QNSWindow alloc] initWithContentRect:frame
- styleMask:(NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTitledWindowMask)
- backing:NSBackingStoreBuffered
- defer:NO]; // Deferring window creation breaks OpenGL (the GL context is set up
- // before the window is shown and needs a proper window.).
- break;
- }
+ // Prevent Cocoa from releasing the window on close. Qt
+ // handles the close event asynchronously and we want to
+ // make sure that m_nsWindow stays valid until the
+ // QCocoaWindow is deleted by Qt.
+ [window setReleasedWhenClosed : NO];
- //qt_syncCocoaTitleBarButtons(window, widget);
- return window;
+ [[NSNotificationCenter defaultCenter] addObserver:m_contentView
+ selector:@selector(windowDidBecomeKey)
+ name:NSWindowDidBecomeKeyNotification
+ object:m_nsWindow];
+
+ [[NSNotificationCenter defaultCenter] addObserver:m_contentView
+ selector:@selector(windowDidResignKey)
+ name:NSWindowDidResignKeyNotification
+ object:m_nsWindow];
+
+ [[NSNotificationCenter defaultCenter] addObserver:m_contentView
+ selector:@selector(windowDidBecomeMain)
+ name:NSWindowDidBecomeMainNotification
+ object:m_nsWindow];
+
+ [[NSNotificationCenter defaultCenter] addObserver:m_contentView
+ selector:@selector(windowDidResignMain)
+ name:NSWindowDidResignMainNotification
+ object:m_nsWindow];
+
+
+ // ### Accept touch events by default.
+ // Beware that enabling touch events has a negative impact on the overall performance.
+ // We probably need a QWindowSystemInterface API to enable/disable touch events.
+ [m_contentView setAcceptsTouchEvents:YES];
+
+ [window setContentView:m_contentView];
+}
+
+void QCocoaWindow::clearNSWindow(NSWindow *window)
+{
+ [[NSNotificationCenter defaultCenter] removeObserver:m_contentView];
}
+
// Returns the current global screen geometry for the nswindow associated with this window.
QRect QCocoaWindow::windowGeometry() const
{
diff --git a/src/plugins/platforms/cocoa/qmacclipboard.mm b/src/plugins/platforms/cocoa/qmacclipboard.mm
index d5af6de69c..eff2c5b07a 100644
--- a/src/plugins/platforms/cocoa/qmacclipboard.mm
+++ b/src/plugins/platforms/cocoa/qmacclipboard.mm
@@ -63,106 +63,6 @@ QT_USE_NAMESPACE
*****************************************************************************/
//#define DEBUG_PASTEBOARD
-#ifndef QT_NO_CLIPBOARD
-
-/*****************************************************************************
- QClipboard member functions for mac.
- *****************************************************************************/
-
-static QMacPasteboard *qt_mac_pasteboards[2] = {0, 0};
-
-static inline QMacPasteboard *qt_mac_pasteboard(QClipboard::Mode mode)
-{
- Q_ASSERT(mode == QClipboard::Clipboard || mode == QClipboard::FindBuffer);
- if (mode == QClipboard::Clipboard)
- return qt_mac_pasteboards[0];
- else
- return qt_mac_pasteboards[1];
-}
-
-static void qt_mac_cleanupPasteboard() {
- delete qt_mac_pasteboards[0];
- delete qt_mac_pasteboards[1];
- qt_mac_pasteboards[0] = 0;
- qt_mac_pasteboards[1] = 0;
-}
-
-static bool qt_mac_updateScrap(QClipboard::Mode mode)
-{
- if (!qt_mac_pasteboards[0]) {
- qt_mac_pasteboards[0] = new QMacPasteboard(kPasteboardClipboard, QMacPasteboardMime::MIME_CLIP);
- qt_mac_pasteboards[1] = new QMacPasteboard(kPasteboardFind, QMacPasteboardMime::MIME_CLIP);
- qAddPostRoutine(qt_mac_cleanupPasteboard);
- return true;
- }
- return qt_mac_pasteboard(mode)->sync();
-}
-
-void QClipboard::clear(Mode mode)
-{
- if (!supportsMode(mode))
- return;
- qt_mac_updateScrap(mode);
- qt_mac_pasteboard(mode)->clear();
- setMimeData(0, mode);
-}
-
-void QClipboard::ownerDestroyed()
-{
-}
-
-
-void QClipboard::connectNotify(const char *signal)
-{
- Q_UNUSED(signal);
-}
-
-bool QClipboard::event(QEvent *e)
-{
- if (e->type() != QEvent::Clipboard)
- return QObject::event(e);
-
- if (qt_mac_updateScrap(QClipboard::Clipboard)) {
- emitChanged(QClipboard::Clipboard);
- }
-
- if (qt_mac_updateScrap(QClipboard::FindBuffer)) {
- emitChanged(QClipboard::FindBuffer);
- }
-
- return QObject::event(e);
-}
-
-const QMimeData *QClipboard::mimeData(Mode mode) const
-{
- if (!supportsMode(mode))
- return 0;
- qt_mac_updateScrap(mode);
- return qt_mac_pasteboard(mode)->mimeData();
-}
-
-void QClipboard::setMimeData(QMimeData *src, Mode mode)
-{
- if (!supportsMode(mode))
- return;
- qt_mac_updateScrap(mode);
- qt_mac_pasteboard(mode)->setMimeData(src);
- emitChanged(mode);
-}
-
-bool QClipboard::supportsMode(Mode mode) const
-{
- return (mode == Clipboard || mode == FindBuffer);
-}
-
-bool QClipboard::ownsMode(Mode mode) const
-{
- Q_UNUSED(mode);
- return false;
-}
-
-#endif // QT_NO_CLIPBOARD
-
/*****************************************************************************
QMacPasteboard code
*****************************************************************************/
diff --git a/src/plugins/platforms/cocoa/qmacmime.h b/src/plugins/platforms/cocoa/qmacmime.h
index 842caa5f2f..7226caef28 100644
--- a/src/plugins/platforms/cocoa/qmacmime.h
+++ b/src/plugins/platforms/cocoa/qmacmime.h
@@ -58,7 +58,8 @@ public:
explicit QMacPasteboardMime(char);
virtual ~QMacPasteboardMime();
- static void initialize();
+ static void initializeMimeTypes();
+ static void destroyMimeTypes();
static QList<QMacPasteboardMime*> all(uchar);
static QMacPasteboardMime *convertor(uchar, const QString &mime, QString flav);
diff --git a/src/plugins/platforms/cocoa/qmacmime.mm b/src/plugins/platforms/cocoa/qmacmime.mm
index db86deb91c..8cb684fbea 100644
--- a/src/plugins/platforms/cocoa/qmacmime.mm
+++ b/src/plugins/platforms/cocoa/qmacmime.mm
@@ -64,14 +64,6 @@ extern CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage
typedef QList<QMacPasteboardMime*> MimeList;
Q_GLOBAL_STATIC(MimeList, globalMimeList)
-
-static void cleanup_mimes()
-{
- MimeList *mimes = globalMimeList();
- while (!mimes->isEmpty())
- delete mimes->takeFirst();
-}
-
Q_GLOBAL_STATIC(QStringList, globalDraggedTypesList)
/*!
@@ -791,11 +783,9 @@ QList<QByteArray> QMacPasteboardMimeVCard::convertFromMime(const QString &mime,
This is an internal function.
*/
-void QMacPasteboardMime::initialize()
+void QMacPasteboardMime::initializeMimeTypes()
{
if (globalMimeList()->isEmpty()) {
- qAddPostRoutine(cleanup_mimes);
-
//standard types that we wrap
new QMacPasteboardMimeTiff;
new QMacPasteboardMimeUnicodeText;
@@ -811,6 +801,16 @@ void QMacPasteboardMime::initialize()
}
/*!
+ \internal
+*/
+void QMacPasteboardMime::destroyMimeTypes()
+{
+ MimeList *mimes = globalMimeList();
+ while (!mimes->isEmpty())
+ delete mimes->takeFirst();
+}
+
+/*!
Returns the most-recently created QMacPasteboardMime of type \a t that can convert
between the \a mime and \a flav formats. Returns 0 if no such convertor
exists.
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index 1a1a1cd3b9..f09c9331f6 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -44,6 +44,7 @@
#include <Cocoa/Cocoa.h>
+#include <QtCore/QPointer>
#include <QtGui/QImage>
#include <QtGui/QAccessible>
@@ -51,12 +52,14 @@ QT_BEGIN_NAMESPACE
class QCocoaWindow;
QT_END_NAMESPACE
-@interface QNSView : NSView {
+@interface QNSView : NSView <NSTextInput> {
CGImageRef m_cgImage;
QWindow *m_window;
QCocoaWindow *m_platformWindow;
Qt::MouseButtons m_buttons;
QAccessibleInterface *m_accessibleRoot;
+ QString m_composingText;
+ bool m_keyEventsAccepted;
QStringList *currentCustomDragTypes;
}
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 9ed3332ba5..a28c5959ce 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -51,6 +51,7 @@
#include "qcocoadrag.h"
#include <QtGui/QWindowSystemInterface>
+#include <QtGui/QTextFormat>
#include <QtCore/QDebug>
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
@@ -94,6 +95,7 @@ static QTouchDevice *touchDevice = 0;
m_window = window;
m_platformWindow = platformWindow;
m_accessibleRoot = 0;
+ m_keyEventsAccepted = false;
#ifdef QT_COCOA_ENABLE_ACCESSIBILITY_INSPECTOR
// prevent rift in space-time continuum, disable
@@ -144,14 +146,27 @@ static QTouchDevice *touchDevice = 0;
- (void)windowDidBecomeKey
{
- QWindowSystemInterface::handleWindowActivated(m_window);
+// QWindowSystemInterface::handleWindowActivated(m_window);
}
- (void)windowDidResignKey
{
+// QWindowSystemInterface::handleWindowActivated(0);
+}
+
+- (void)windowDidBecomeMain
+{
+// qDebug() << "window did become main" << m_window;
+ QWindowSystemInterface::handleWindowActivated(m_window);
+}
+
+- (void)windowDidResignMain
+{
+// qDebug() << "window did resign main" << m_window;
QWindowSystemInterface::handleWindowActivated(0);
}
+
- (void) setImage:(QImage *)image
{
CGImageRelease(m_cgImage);
@@ -266,14 +281,24 @@ static QTouchDevice *touchDevice = 0;
qtScreenPoint = QPoint(screenPoint.x, qt_mac_flipYCoordinate(screenPoint.y));
}
ulong timestamp = [theEvent timestamp] * 1000;
-
QWindowSystemInterface::handleMouseEvent(m_window, timestamp, qtWindowPoint, qtScreenPoint, m_buttons);
}
- (void)mouseDown:(NSEvent *)theEvent
{
- m_buttons |= Qt::LeftButton;
- [self handleMouseEvent:theEvent];
+ if (m_platformWindow->m_activePopupWindow) {
+ QWindowSystemInterface::handleSynchronousCloseEvent(m_platformWindow->m_activePopupWindow);
+ m_platformWindow->m_activePopupWindow = 0;
+ }
+ if ([self hasMarkedText]) {
+ NSInputManager* inputManager = [NSInputManager currentInputManager];
+ if ([inputManager wantsToHandleMouseEvents]) {
+ [inputManager handleMouseEvent:theEvent];
+ }
+ } else {
+ m_buttons |= Qt::LeftButton;
+ [self handleMouseEvent:theEvent];
+ }
}
- (void)mouseDragged:(NSEvent *)theEvent
@@ -327,7 +352,53 @@ static QTouchDevice *touchDevice = 0;
- (void)otherMouseDown:(NSEvent *)theEvent
{
- m_buttons |= Qt::RightButton;
+ switch ([theEvent buttonNumber]) {
+ case 3:
+ m_buttons |= Qt::MiddleButton;
+ break;
+ case 4:
+ m_buttons |= Qt::ExtraButton1; // AKA Qt::BackButton
+ break;
+ case 5:
+ m_buttons |= Qt::ExtraButton2; // AKA Qt::ForwardButton
+ break;
+ case 6:
+ m_buttons |= Qt::ExtraButton3;
+ break;
+ case 7:
+ m_buttons |= Qt::ExtraButton4;
+ break;
+ case 8:
+ m_buttons |= Qt::ExtraButton5;
+ break;
+ case 9:
+ m_buttons |= Qt::ExtraButton6;
+ break;
+ case 10:
+ m_buttons |= Qt::ExtraButton7;
+ break;
+ case 11:
+ m_buttons |= Qt::ExtraButton8;
+ break;
+ case 12:
+ m_buttons |= Qt::ExtraButton9;
+ break;
+ case 13:
+ m_buttons |= Qt::ExtraButton10;
+ break;
+ case 14:
+ m_buttons |= Qt::ExtraButton11;
+ break;
+ case 15:
+ m_buttons |= Qt::ExtraButton12;
+ break;
+ case 16:
+ m_buttons |= Qt::ExtraButton13;
+ break;
+ default:
+ m_buttons |= Qt::MiddleButton;
+ break;
+ }
[self handleMouseEvent:theEvent];
}
@@ -340,7 +411,53 @@ static QTouchDevice *touchDevice = 0;
- (void)otherMouseUp:(NSEvent *)theEvent
{
- m_buttons &= QFlag(~int(Qt::MiddleButton));
+ switch ([theEvent buttonNumber]) {
+ case 3:
+ m_buttons &= QFlag(~int(Qt::MiddleButton));
+ break;
+ case 4:
+ m_buttons &= QFlag(~int(Qt::ExtraButton1)); // AKA Qt::BackButton
+ break;
+ case 5:
+ m_buttons &= QFlag(~int(Qt::ExtraButton2)); // AKA Qt::ForwardButton
+ break;
+ case 6:
+ m_buttons &= QFlag(~int(Qt::ExtraButton3));
+ break;
+ case 7:
+ m_buttons &= QFlag(~int(Qt::ExtraButton4));
+ break;
+ case 8:
+ m_buttons &= QFlag(~int(Qt::ExtraButton5));
+ break;
+ case 9:
+ m_buttons &= QFlag(~int(Qt::ExtraButton6));
+ break;
+ case 10:
+ m_buttons &= QFlag(~int(Qt::ExtraButton7));
+ break;
+ case 11:
+ m_buttons &= QFlag(~int(Qt::ExtraButton8));
+ break;
+ case 12:
+ m_buttons &= QFlag(~int(Qt::ExtraButton9));
+ break;
+ case 13:
+ m_buttons &= QFlag(~int(Qt::ExtraButton10));
+ break;
+ case 14:
+ m_buttons &= QFlag(~int(Qt::ExtraButton11));
+ break;
+ case 15:
+ m_buttons &= QFlag(~int(Qt::ExtraButton12));
+ break;
+ case 16:
+ m_buttons &= QFlag(~int(Qt::ExtraButton13));
+ break;
+ default:
+ m_buttons &= QFlag(~int(Qt::MiddleButton));
+ break;
+ }
[self handleMouseEvent:theEvent];
}
@@ -467,12 +584,228 @@ static QTouchDevice *touchDevice = 0;
- (void)keyDown:(NSEvent *)theEvent
{
- [self handleKeyEvent : theEvent eventType :int(QEvent::KeyPress)];
+ QObject *fo = QGuiApplication::focusObject();
+ m_keyEventsAccepted = false;
+ if (fo) {
+ QInputMethodQueryEvent queryEvent(Qt::ImHints);
+ if (QCoreApplication::sendEvent(fo, &queryEvent)) {
+ Qt::InputMethodHints hints = static_cast<Qt::InputMethodHints>(queryEvent.value(Qt::ImHints).toUInt());
+ if (!(hints & Qt::ImhDigitsOnly || hints & Qt::ImhFormattedNumbersOnly || hints & Qt::ImhHiddenText)) {
+ [self interpretKeyEvents:[NSArray arrayWithObject: theEvent]];
+ }
+ }
+ }
+
+ if (!m_keyEventsAccepted && m_composingText.isEmpty()) {
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyPress)];
+ }
}
- (void)keyUp:(NSEvent *)theEvent
{
- [self handleKeyEvent : theEvent eventType :int(QEvent::KeyRelease)];
+ if (!m_keyEventsAccepted && m_composingText.isEmpty()) {
+ [self handleKeyEvent : theEvent eventType :int(QEvent::KeyRelease)];
+ }
+}
+
+- (void) doCommandBySelector:(SEL)aSelector
+{
+ [self tryToPerform:aSelector with:self];
+}
+
+- (void) insertText:(id)aString
+{
+ QString commitString;
+ if ([aString length]) {
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ commitString = QCFString::toQString(reinterpret_cast<CFStringRef>([aString string]));
+ } else {
+ commitString = QCFString::toQString(reinterpret_cast<CFStringRef>(aString));
+ };
+ }
+ QObject *fo = QGuiApplication::focusObject();
+ if (fo) {
+ QInputMethodEvent e;
+ e.setCommitString(commitString);
+ QCoreApplication::sendEvent(fo, &e);
+ m_keyEventsAccepted = true;
+ }
+
+ m_composingText.clear();
+ }
+
+- (void) setMarkedText:(id)aString selectedRange:(NSRange)selRange
+{
+ QString preeditString;
+
+ QList<QInputMethodEvent::Attribute> attrs;
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, selRange.location + selRange.length, 1, QVariant());
+
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ // Preedit string has attribution
+ preeditString = QCFString::toQString(reinterpret_cast<CFStringRef>([aString string]));
+ int composingLength = preeditString.length();
+ int index = 0;
+ // Create attributes for individual sections of preedit text
+ while (index < composingLength) {
+ NSRange effectiveRange;
+ NSRange range = NSMakeRange(index, composingLength-index);
+ NSDictionary *attributes = [aString attributesAtIndex:index
+ longestEffectiveRange:&effectiveRange
+ inRange:range];
+ NSNumber *underlineStyle = [attributes objectForKey:NSUnderlineStyleAttributeName];
+ if (underlineStyle) {
+ QColor clr (Qt::black);
+ NSColor *color = [attributes objectForKey:NSUnderlineColorAttributeName];
+ if (color) {
+ clr = qt_mac_toQColor(color);
+ }
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ format.setUnderlineColor(clr);
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ effectiveRange.location,
+ effectiveRange.length,
+ format);
+ }
+ index = effectiveRange.location + effectiveRange.length;
+ }
+ } else {
+ // No attributes specified, take only the preedit text.
+ preeditString = QCFString::toQString(reinterpret_cast<CFStringRef>(aString));
+ }
+
+ if (attrs.isEmpty()) {
+ QTextCharFormat format;
+ format.setFontUnderline(true);
+ attrs<<QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat,
+ 0, preeditString.length(), format);
+ }
+
+ m_composingText = preeditString;
+
+ QObject *fo = QGuiApplication::focusObject();
+ if (fo) {
+ QInputMethodEvent e(preeditString, attrs);
+ QCoreApplication::sendEvent(fo, &e);
+ m_keyEventsAccepted = true;
+ }
+}
+
+- (void) unmarkText
+{
+ if (!m_composingText.isEmpty()) {
+ QObject *fo = QGuiApplication::focusObject();
+ if (fo) {
+ QInputMethodEvent e;
+ e.setCommitString(m_composingText);
+ QCoreApplication::sendEvent(fo, &e);
+ }
+ }
+ m_composingText.clear();
+}
+
+- (BOOL) hasMarkedText
+{
+ return (m_composingText.isEmpty() ? NO: YES);
+}
+
+- (NSInteger) conversationIdentifier
+{
+ return (NSInteger)self;
+}
+
+- (NSAttributedString *) attributedSubstringFromRange:(NSRange)theRange
+{
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return nil;
+ QInputMethodQueryEvent queryEvent(Qt::ImCurrentSelection);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return nil;
+
+ QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
+ if (selectedText.isEmpty())
+ return nil;
+
+ QCFString string(selectedText.mid(theRange.location, theRange.length));
+ const NSString *tmpString = reinterpret_cast<const NSString *>((CFStringRef)string);
+ return [[[NSAttributedString alloc] initWithString:const_cast<NSString *>(tmpString)] autorelease];
+}
+
+- (NSRange) markedRange
+{
+ NSRange range;
+ if (!m_composingText.isEmpty()) {
+ range.location = 0;
+ range.length = m_composingText.length();
+ } else {
+ range.location = NSNotFound;
+ range.length = 0;
+ }
+ return range;
+}
+
+
+- (NSRange) selectedRange
+{
+ NSRange selRange = {NSNotFound, 0};
+ selRange.location = NSNotFound;
+ selRange.length = 0;
+
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return selRange;
+ QInputMethodQueryEvent queryEvent(Qt::ImCurrentSelection);
+ if (!QCoreApplication::sendEvent(fo, &queryEvent))
+ return selRange;
+ QString selectedText = queryEvent.value(Qt::ImCurrentSelection).toString();
+
+ if (!selectedText.isEmpty()) {
+ selRange.location = 0;
+ selRange.length = selectedText.length();
+ }
+ return selRange;
+}
+
+- (NSRect) firstRectForCharacterRange:(NSRange)theRange
+{
+ Q_UNUSED(theRange);
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return NSZeroRect;
+
+ if (!m_window)
+ return NSZeroRect;
+
+ // The returned rect is always based on the internal cursor.
+ QRect mr = qApp->inputMethod()->cursorRectangle().toRect();
+ QPoint mp = m_window->mapToGlobal(mr.bottomLeft());
+
+ NSRect rect;
+ rect.origin.x = mp.x();
+ rect.origin.y = qt_mac_flipYCoordinate(mp.y());
+ rect.size.width = mr.width();
+ rect.size.height = mr.height();
+ return rect;
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
+{
+ // We dont support cursor movements using mouse while composing.
+ Q_UNUSED(thePoint);
+ return NSNotFound;
+}
+
+- (NSArray*) validAttributesForMarkedText
+{
+ QObject *fo = QGuiApplication::focusObject();
+ if (!fo)
+ return nil;
+
+ // Support only underline color/style.
+ return [NSArray arrayWithObjects:NSUnderlineColorAttributeName,
+ NSUnderlineStyleAttributeName, nil];
}
-(void)registerDragTypes
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index a0e98e0ed1..2548fb4a9d 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -64,6 +64,14 @@
}
}
+- (void)windowWillMove:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowWillMove();
+ }
+}
+
- (void)windowDidMove:(NSNotification *)notification
{
Q_UNUSED(notification);
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac.mm b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
new file mode 100644
index 0000000000..8b8445c995
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac.mm
@@ -0,0 +1,1788 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qpaintengine_mac_p.h"
+#include "qprintengine_mac_p.h"
+
+#include <qbitmap.h>
+#include <qpaintdevice.h>
+#include <qpainterpath.h>
+#include <qpixmapcache.h>
+#include <private/qpaintengine_raster_p.h>
+#include <qprinter.h>
+#include <qstack.h>
+#include <qtextcodec.h>
+#include <qwidget.h>
+#include <qvarlengtharray.h>
+#include <qdebug.h>
+#include <qcoreapplication.h>
+#include <qmath.h>
+
+#include <QtGui/qplatformpixmap_qpa.h>
+
+#include <private/qfont_p.h>
+#include <private/qfontengine_p.h>
+#include <private/qfontengine_coretext_p.h>
+#include <private/qnumeric_p.h>
+#include <private/qpainter_p.h>
+#include <private/qpainterpath_p.h>
+#include <private/qtextengine_p.h>
+#include <private/qwidget_p.h>
+
+#include "qcocoahelpers.h"
+
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+extern int qt_antialiasing_threshold; // from qcoretextfontdatabase.mm
+
+/*****************************************************************************
+ QCoreGraphicsPaintEngine utility functions
+ *****************************************************************************/
+
+void qt_mac_clip_cg(CGContextRef hd, const QRegion &rgn, CGAffineTransform *orig_xform)
+{
+ CGAffineTransform old_xform = CGAffineTransformIdentity;
+ if (orig_xform) { //setup xforms
+ old_xform = CGContextGetCTM(hd);
+ CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
+ CGContextConcatCTM(hd, *orig_xform);
+ }
+
+ //do the clipping
+ CGContextBeginPath(hd);
+ if (rgn.isEmpty()) {
+ CGContextAddRect(hd, CGRectMake(0, 0, 0, 0));
+ } else {
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ QCFType<HIMutableShapeRef> shape = qt_mac_QRegionToHIMutableShape(rgn);
+ Q_ASSERT(!HIShapeIsEmpty(shape));
+ HIShapeReplacePathInCGContext(shape, hd);
+ } else
+#endif
+ {
+ QVector<QRect> rects = rgn.rects();
+ const int count = rects.size();
+ for (int i = 0; i < count; i++) {
+ const QRect &r = rects[i];
+ CGRect mac_r = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ CGContextAddRect(hd, mac_r);
+ }
+ }
+
+ }
+ CGContextClip(hd);
+
+ if (orig_xform) {//reset xforms
+ CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
+ CGContextConcatCTM(hd, old_xform);
+ }
+}
+
+CGColorSpaceRef qt_mac_colorSpaceForDeviceType(const QPaintDevice *paintDevice)
+{
+ bool isWidget = (paintDevice->devType() == QInternal::Widget);
+ return QCoreGraphicsPaintEngine::macDisplayColorSpace(isWidget ? static_cast<const QWidget *>(paintDevice)
+ : 0);
+}
+
+// Implemented for qt_mac_p.h
+QMacCGContext::QMacCGContext(QPainter *p)
+{
+ QPaintEngine *pe = p->paintEngine();
+ if (pe->type() == QPaintEngine::MacPrinter)
+ pe = static_cast<QMacPrintEngine*>(pe)->paintEngine();
+ pe->syncState();
+ context = 0;
+ if (pe->type() == QPaintEngine::CoreGraphics)
+ context = static_cast<QCoreGraphicsPaintEngine*>(pe)->handle();
+
+ int devType = p->device()->devType();
+ if (pe->type() == QPaintEngine::Raster
+ && (devType == QInternal::Widget || devType == QInternal::Pixmap || devType == QInternal::Image)) {
+
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pe->paintDevice());
+ uint flags = kCGImageAlphaPremultipliedFirst;
+#ifdef kCGBitmapByteOrder32Host //only needed because CGImage.h added symbols in the minor version
+ flags |= kCGBitmapByteOrder32Host;
+#endif
+ const QImage *image = (const QImage *) pe->paintDevice();
+
+ context = CGBitmapContextCreate((void *) image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+
+ CGContextTranslateCTM(context, 0, image->height());
+ CGContextScaleCTM(context, 1, -1);
+
+ if (devType == QInternal::Widget) {
+ QRegion clip = p->paintEngine()->systemClip();
+ QTransform native = p->deviceTransform();
+ QTransform logical = p->combinedTransform();
+
+ if (p->hasClipping()) {
+ QRegion r = p->clipRegion();
+ r.translate(native.dx(), native.dy());
+ if (clip.isEmpty())
+ clip = r;
+ else
+ clip &= r;
+ }
+ qt_mac_clip_cg(context, clip, 0);
+
+ CGContextTranslateCTM(context, native.dx(), native.dy());
+ }
+ } else {
+ CGContextRetain(context);
+ }
+}
+
+void qt_mac_cgimage_data_free(void *, const void *memoryToFree, size_t)
+{
+ free(const_cast<void *>(memoryToFree));
+}
+
+CGImageRef qt_mac_create_imagemask(const QPixmap &pixmap, const QRectF &sr)
+{
+ QImage image = pixmap.toImage();
+ if (image.format() != QImage::Format_ARGB32_Premultiplied)
+ image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied);
+
+ const int sx = qRound(sr.x()), sy = qRound(sr.y()), sw = qRound(sr.width()), sh = qRound(sr.height());
+ const int sbpr = image.bytesPerLine();
+ const uint nbytes = sw * sh;
+ // alpha is always 255 for bitmaps, ignore it in this case.
+ const quint32 mask = pixmap.depth() == 1 ? 0x00ffffff : 0xffffffff;
+ quint8 *dptr = static_cast<quint8 *>(malloc(nbytes));
+ quint32 *sptr = reinterpret_cast<quint32 *>(image.scanLine(0)), *srow;
+ for (int y = sy, offset=0; y < sh; ++y) {
+ srow = sptr + (y * (sbpr / 4));
+ for (int x = sx; x < sw; ++x)
+ *(dptr+(offset++)) = (*(srow+x) & mask) ? 255 : 0;
+ }
+ QCFType<CGDataProviderRef> provider = CGDataProviderCreateWithData(0, dptr, nbytes, qt_mac_cgimage_data_free);
+ return CGImageMaskCreate(sw, sh, 8, 8, nbytes / sh, provider, 0, 0);
+}
+
+//conversion
+inline static float qt_mac_convert_color_to_cg(int c) { return ((float)c * 1000 / 255) / 1000; }
+inline static int qt_mac_convert_color_from_cg(float c) { return qRound(c * 255); }
+CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &t) {
+ return CGAffineTransformMake(t.m11(), t.m12(), t.m21(), t.m22(), t.dx(), t.dy());
+}
+
+/*! \internal
+
+ Returns the CoreGraphics CGContextRef of the paint device. 0 is
+ returned if it can't be obtained. It is the caller's responsibility to
+ CGContextRelease the context when finished using it.
+
+ \warning This function is only available on Mac OS X.
+ \warning This function is duplicated in qmacstyle_mac.mm
+*/
+CGContextRef qt_mac_cg_context(const QPaintDevice *pdev)
+{
+ if (pdev->devType() == QInternal::Pixmap) {
+ const QPixmap *pm = static_cast<const QPixmap*>(pdev);
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
+ uint flags = kCGImageAlphaPremultipliedFirst;
+ flags |= kCGBitmapByteOrder32Host;
+ CGContextRef ret = 0;
+
+ QPlatformPixmap *data = const_cast<QPixmap *>(pm)->data_ptr().data();
+ if (data->classId() == QPlatformPixmap::RasterClass) {
+ QImage *image = data->buffer();
+ ret = CGBitmapContextCreate(image->bits(), image->width(), image->height(),
+ 8, image->bytesPerLine(), colorspace, flags);
+ } else {
+ qDebug() << "qt_mac_cg_context: Unsupported pixmap class";
+ }
+
+ CGContextTranslateCTM(ret, 0, pm->height());
+ CGContextScaleCTM(ret, 1, -1);
+ return ret;
+ } else if (pdev->devType() == QInternal::Widget) {
+ //CGContextRef ret = static_cast<CGContextRef>(static_cast<const QWidget *>(pdev)->macCGHandle());
+ ///CGContextRetain(ret);
+ //return ret;
+ qDebug() << "qt_mac_cg_context: not implemented: Widget class";
+ return 0;
+ }
+ return 0;
+}
+
+inline static QCFType<CGColorRef> cgColorForQColor(const QColor &col, QPaintDevice *pdev)
+{
+ CGFloat components[] = {
+ qt_mac_convert_color_to_cg(col.red()),
+ qt_mac_convert_color_to_cg(col.green()),
+ qt_mac_convert_color_to_cg(col.blue()),
+ qt_mac_convert_color_to_cg(col.alpha())
+ };
+ return CGColorCreate(qt_mac_colorSpaceForDeviceType(pdev), components);
+}
+
+// There's architectural problems with using native gradients
+// on the Mac at the moment, so disable them.
+// #define QT_MAC_USE_NATIVE_GRADIENTS
+
+#ifdef QT_MAC_USE_NATIVE_GRADIENTS
+static bool drawGradientNatively(const QGradient *gradient)
+{
+ return gradient->spread() == QGradient::PadSpread;
+}
+
+// gradiant callback
+static void qt_mac_color_gradient_function(void *info, const CGFloat *in, CGFloat *out)
+{
+ QBrush *brush = static_cast<QBrush *>(info);
+ Q_ASSERT(brush && brush->gradient());
+
+ const QGradientStops stops = brush->gradient()->stops();
+ const int n = stops.count();
+ Q_ASSERT(n >= 1);
+ const QGradientStop *begin = stops.constBegin();
+ const QGradientStop *end = begin + n;
+
+ qreal p = in[0];
+ const QGradientStop *i = begin;
+ while (i != end && i->first < p)
+ ++i;
+
+ QRgb c;
+ if (i == begin) {
+ c = begin->second.rgba();
+ } else if (i == end) {
+ c = (end - 1)->second.rgba();
+ } else {
+ const QGradientStop &s1 = *(i - 1);
+ const QGradientStop &s2 = *i;
+ qreal p1 = s1.first;
+ qreal p2 = s2.first;
+ QRgb c1 = s1.second.rgba();
+ QRgb c2 = s2.second.rgba();
+ int idist = 256 * (p - p1) / (p2 - p1);
+ int dist = 256 - idist;
+ c = qRgba(INTERPOLATE_PIXEL_256(qRed(c1), dist, qRed(c2), idist),
+ INTERPOLATE_PIXEL_256(qGreen(c1), dist, qGreen(c2), idist),
+ INTERPOLATE_PIXEL_256(qBlue(c1), dist, qBlue(c2), idist),
+ INTERPOLATE_PIXEL_256(qAlpha(c1), dist, qAlpha(c2), idist));
+ }
+
+ out[0] = qt_mac_convert_color_to_cg(qRed(c));
+ out[1] = qt_mac_convert_color_to_cg(qGreen(c));
+ out[2] = qt_mac_convert_color_to_cg(qBlue(c));
+ out[3] = qt_mac_convert_color_to_cg(qAlpha(c));
+}
+#endif
+
+//clipping handling
+void QCoreGraphicsPaintEnginePrivate::resetClip()
+{
+ static bool inReset = false;
+ if (inReset)
+ return;
+ inReset = true;
+
+ CGAffineTransform old_xform = CGContextGetCTM(hd);
+
+ //setup xforms
+ CGContextConcatCTM(hd, CGAffineTransformInvert(old_xform));
+ while (stackCount > 0) {
+ restoreGraphicsState();
+ }
+ saveGraphicsState();
+ inReset = false;
+ //reset xforms
+ CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
+ CGContextConcatCTM(hd, old_xform);
+}
+
+static CGRect qt_mac_compose_rect(const QRectF &r, float off=0)
+{
+ return CGRectMake(r.x()+off, r.y()+off, r.width(), r.height());
+}
+
+static CGMutablePathRef qt_mac_compose_path(const QPainterPath &p, float off=0)
+{
+ CGMutablePathRef ret = CGPathCreateMutable();
+ QPointF startPt;
+ for (int i=0; i<p.elementCount(); ++i) {
+ const QPainterPath::Element &elm = p.elementAt(i);
+ switch (elm.type) {
+ case QPainterPath::MoveToElement:
+ if (i > 0
+ && p.elementAt(i - 1).x == startPt.x()
+ && p.elementAt(i - 1).y == startPt.y())
+ CGPathCloseSubpath(ret);
+ startPt = QPointF(elm.x, elm.y);
+ CGPathMoveToPoint(ret, 0, elm.x+off, elm.y+off);
+ break;
+ case QPainterPath::LineToElement:
+ CGPathAddLineToPoint(ret, 0, elm.x+off, elm.y+off);
+ break;
+ case QPainterPath::CurveToElement:
+ Q_ASSERT(p.elementAt(i+1).type == QPainterPath::CurveToDataElement);
+ Q_ASSERT(p.elementAt(i+2).type == QPainterPath::CurveToDataElement);
+ CGPathAddCurveToPoint(ret, 0,
+ elm.x+off, elm.y+off,
+ p.elementAt(i+1).x+off, p.elementAt(i+1).y+off,
+ p.elementAt(i+2).x+off, p.elementAt(i+2).y+off);
+ i+=2;
+ break;
+ default:
+ qFatal("QCoreGraphicsPaintEngine::drawPath(), unhandled type: %d", elm.type);
+ break;
+ }
+ }
+ if (!p.isEmpty()
+ && p.elementAt(p.elementCount() - 1).x == startPt.x()
+ && p.elementAt(p.elementCount() - 1).y == startPt.y())
+ CGPathCloseSubpath(ret);
+ return ret;
+}
+
+CGColorSpaceRef QCoreGraphicsPaintEngine::m_genericColorSpace = 0;
+QHash<CGDirectDisplayID, CGColorSpaceRef> QCoreGraphicsPaintEngine::m_displayColorSpaceHash;
+bool QCoreGraphicsPaintEngine::m_postRoutineRegistered = false;
+
+CGColorSpaceRef QCoreGraphicsPaintEngine::macGenericColorSpace()
+{
+#if 0
+ if (!m_genericColorSpace) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ m_genericColorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
+ } else
+#endif
+ {
+ m_genericColorSpace = CGColorSpaceCreateDeviceRGB();
+ }
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
+ }
+ }
+ return m_genericColorSpace;
+#else
+ // Just return the main display colorspace for the moment.
+ return macDisplayColorSpace();
+#endif
+}
+
+/*
+ Ideally, we should pass the widget in here, and use CGGetDisplaysWithRect() etc.
+ to support multiple displays correctly.
+*/
+CGColorSpaceRef QCoreGraphicsPaintEngine::macDisplayColorSpace(const QWidget *widget)
+{
+ CGColorSpaceRef colorSpace;
+
+ CGDirectDisplayID displayID;
+ CMProfileRef displayProfile = 0;
+ if (widget == 0) {
+ displayID = CGMainDisplayID();
+ } else {
+ const QRect &qrect = widget->window()->geometry();
+ CGRect rect = CGRectMake(qrect.x(), qrect.y(), qrect.width(), qrect.height());
+ CGDisplayCount throwAway;
+ CGDisplayErr dErr = CGGetDisplaysWithRect(rect, 1, &displayID, &throwAway);
+ if (dErr != kCGErrorSuccess)
+ return macDisplayColorSpace(0); // fall back on main display
+ }
+ if ((colorSpace = m_displayColorSpaceHash.value(displayID)))
+ return colorSpace;
+
+ CMError err = CMGetProfileByAVID((CMDisplayIDType)displayID, &displayProfile);
+ if (err == noErr) {
+ colorSpace = CGColorSpaceCreateWithPlatformColorSpace(displayProfile);
+ } else if (widget) {
+ return macDisplayColorSpace(0); // fall back on main display
+ }
+
+ if (colorSpace == 0)
+ colorSpace = CGColorSpaceCreateDeviceRGB();
+
+ m_displayColorSpaceHash.insert(displayID, colorSpace);
+ CMCloseProfile(displayProfile);
+ if (!m_postRoutineRegistered) {
+ m_postRoutineRegistered = true;
+ qAddPostRoutine(QCoreGraphicsPaintEngine::cleanUpMacColorSpaces);
+ }
+ return colorSpace;
+}
+
+void QCoreGraphicsPaintEngine::cleanUpMacColorSpaces()
+{
+ if (m_genericColorSpace) {
+ CFRelease(m_genericColorSpace);
+ m_genericColorSpace = 0;
+ }
+ QHash<CGDirectDisplayID, CGColorSpaceRef>::const_iterator it = m_displayColorSpaceHash.constBegin();
+ while (it != m_displayColorSpaceHash.constEnd()) {
+ if (it.value())
+ CFRelease(it.value());
+ ++it;
+ }
+ m_displayColorSpaceHash.clear();
+}
+
+//pattern handling (tiling)
+#if 1
+# define QMACPATTERN_MASK_MULTIPLIER 32
+#else
+# define QMACPATTERN_MASK_MULTIPLIER 1
+#endif
+class QMacPattern
+{
+public:
+ QMacPattern() : as_mask(false), pdev(0), image(0) { data.bytes = 0; }
+ ~QMacPattern() { CGImageRelease(image); }
+ int width() {
+ if (image)
+ return CGImageGetWidth(image);
+ if (data.bytes)
+ return 8*QMACPATTERN_MASK_MULTIPLIER;
+ return data.pixmap.width();
+ }
+ int height() {
+ if (image)
+ return CGImageGetHeight(image);
+ if (data.bytes)
+ return 8*QMACPATTERN_MASK_MULTIPLIER;
+ return data.pixmap.height();
+ }
+
+ //input
+ QColor foreground;
+ bool as_mask;
+ struct {
+ QPixmap pixmap;
+ const uchar *bytes;
+ } data;
+ QPaintDevice *pdev;
+ //output
+ CGImageRef image;
+};
+static void qt_mac_draw_pattern(void *info, CGContextRef c)
+{
+ QMacPattern *pat = (QMacPattern*)info;
+ int w = 0, h = 0;
+ bool isBitmap = (pat->data.pixmap.depth() == 1);
+ if (!pat->image) { //lazy cache
+ if (pat->as_mask) {
+ Q_ASSERT(pat->data.bytes);
+ w = h = 8;
+#if (QMACPATTERN_MASK_MULTIPLIER == 1)
+ CGDataProviderRef provider = CGDataProviderCreateWithData(0, pat->data.bytes, w*h, 0);
+ pat->image = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
+ CGDataProviderRelease(provider);
+#else
+ const int numBytes = (w*h)/sizeof(uchar);
+ uchar xor_bytes[numBytes];
+ for (int i = 0; i < numBytes; ++i)
+ xor_bytes[i] = pat->data.bytes[i] ^ 0xFF;
+ CGDataProviderRef provider = CGDataProviderCreateWithData(0, xor_bytes, w*h, 0);
+ CGImageRef swatch = CGImageMaskCreate(w, h, 1, 1, 1, provider, 0, false);
+ CGDataProviderRelease(provider);
+
+ const QColor c0(0, 0, 0, 0), c1(255, 255, 255, 255);
+ QPixmap pm(w*QMACPATTERN_MASK_MULTIPLIER, h*QMACPATTERN_MASK_MULTIPLIER);
+ pm.fill(c0);
+ CGContextRef pm_ctx = qt_mac_cg_context(&pm);
+ CGContextSetFillColorWithColor(c, cgColorForQColor(c1, pat->pdev));
+ CGRect rect = CGRectMake(0, 0, w, h);
+ for (int x = 0; x < QMACPATTERN_MASK_MULTIPLIER; ++x) {
+ rect.origin.x = x * w;
+ for (int y = 0; y < QMACPATTERN_MASK_MULTIPLIER; ++y) {
+ rect.origin.y = y * h;
+ qt_mac_drawCGImage(pm_ctx, &rect, swatch);
+ }
+ }
+ pat->image = qt_mac_create_imagemask(pm, pm.rect());
+ CGImageRelease(swatch);
+ CGContextRelease(pm_ctx);
+ w *= QMACPATTERN_MASK_MULTIPLIER;
+ h *= QMACPATTERN_MASK_MULTIPLIER;
+#endif
+ } else {
+ w = pat->data.pixmap.width();
+ h = pat->data.pixmap.height();
+ if (isBitmap)
+ pat->image = qt_mac_create_imagemask(pat->data.pixmap, pat->data.pixmap.rect());
+ else
+ pat->image = qt_mac_image_to_cgimage(pat->data.pixmap.toImage());
+ }
+ } else {
+ w = CGImageGetWidth(pat->image);
+ h = CGImageGetHeight(pat->image);
+ }
+
+ //draw
+ bool needRestore = false;
+ if (CGImageIsMask(pat->image)) {
+ CGContextSaveGState(c);
+ CGContextSetFillColorWithColor(c, cgColorForQColor(pat->foreground, pat->pdev));
+ }
+ CGRect rect = CGRectMake(0, 0, w, h);
+ qt_mac_drawCGImage(c, &rect, pat->image);
+ if (needRestore)
+ CGContextRestoreGState(c);
+}
+static void qt_mac_dispose_pattern(void *info)
+{
+ QMacPattern *pat = (QMacPattern*)info;
+ delete pat;
+}
+
+/*****************************************************************************
+ QCoreGraphicsPaintEngine member functions
+ *****************************************************************************/
+
+inline static QPaintEngine::PaintEngineFeatures qt_mac_cg_features()
+{
+ return QPaintEngine::PaintEngineFeatures(QPaintEngine::AllFeatures & ~QPaintEngine::PaintOutsidePaintEvent
+ & ~QPaintEngine::PerspectiveTransform
+ & ~QPaintEngine::ConicalGradientFill
+ & ~QPaintEngine::LinearGradientFill
+ & ~QPaintEngine::RadialGradientFill
+ & ~QPaintEngine::BrushStroke);
+}
+
+QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine()
+: QPaintEngine(*(new QCoreGraphicsPaintEnginePrivate), qt_mac_cg_features())
+{
+}
+
+QCoreGraphicsPaintEngine::QCoreGraphicsPaintEngine(QPaintEnginePrivate &dptr)
+: QPaintEngine(dptr, qt_mac_cg_features())
+{
+}
+
+QCoreGraphicsPaintEngine::~QCoreGraphicsPaintEngine()
+{
+}
+
+bool
+QCoreGraphicsPaintEngine::begin(QPaintDevice *pdev)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ if (isActive()) { // already active painting
+ qWarning("QCoreGraphicsPaintEngine::begin: Painter already active");
+ return false;
+ }
+
+ //initialization
+ d->pdev = pdev;
+ d->complexXForm = false;
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth;
+ d->cosmeticPenSize = 1;
+ d->current.clipEnabled = false;
+ d->pixelSize = QPoint(1,1);
+ d->hd = qt_mac_cg_context(pdev);
+ if (d->hd) {
+ d->saveGraphicsState();
+ d->orig_xform = CGContextGetCTM(d->hd);
+ if (d->shading) {
+ CGShadingRelease(d->shading);
+ d->shading = 0;
+ }
+ d->setClip(0); //clear the context's clipping
+ }
+
+ setActive(true);
+
+ if (d->pdev->devType() == QInternal::Widget) { // device is a widget
+ QWidget *w = (QWidget*)d->pdev;
+ bool unclipped = w->testAttribute(Qt::WA_PaintUnclipped);
+
+ if ((w->windowType() == Qt::Desktop)) {
+ if (!unclipped)
+ qWarning("QCoreGraphicsPaintEngine::begin: Does not support clipped desktop on Mac OS X");
+ // ## need to do [qt_mac_window_for(w) makeKeyAndOrderFront]; (need to rename the file)
+ } else if (unclipped) {
+ qWarning("QCoreGraphicsPaintEngine::begin: Does not support unclipped painting");
+ }
+ } else if (d->pdev->devType() == QInternal::Pixmap) { // device is a pixmap
+ QPixmap *pm = (QPixmap*)d->pdev;
+ if (pm->isNull()) {
+ qWarning("QCoreGraphicsPaintEngine::begin: Cannot paint null pixmap");
+ end();
+ return false;
+ }
+ }
+
+ setDirty(QPaintEngine::DirtyPen);
+ setDirty(QPaintEngine::DirtyBrush);
+ setDirty(QPaintEngine::DirtyBackground);
+ setDirty(QPaintEngine::DirtyHints);
+ return true;
+}
+
+bool
+QCoreGraphicsPaintEngine::end()
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ setActive(false);
+ if (d->pdev->devType() == QInternal::Widget && static_cast<QWidget*>(d->pdev)->windowType() == Qt::Desktop) {
+ // ### need to do [qt_mac_window_for(static_cast<QWidget *>(d->pdev)) orderOut]; (need to rename)
+ }
+ if (d->shading) {
+ CGShadingRelease(d->shading);
+ d->shading = 0;
+ }
+ d->pdev = 0;
+ if (d->hd) {
+ d->restoreGraphicsState();
+ CGContextSynchronize(d->hd);
+ CGContextRelease(d->hd);
+ d->hd = 0;
+ }
+ return true;
+}
+
+void
+QCoreGraphicsPaintEngine::updateState(const QPaintEngineState &state)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ QPaintEngine::DirtyFlags flags = state.state();
+
+ if (flags & DirtyTransform)
+ updateMatrix(state.transform());
+
+ if (flags & DirtyClipEnabled) {
+ if (state.isClipEnabled())
+ updateClipPath(painter()->clipPath(), Qt::ReplaceClip);
+ else
+ updateClipPath(QPainterPath(), Qt::NoClip);
+ }
+
+ if (flags & DirtyClipPath) {
+ updateClipPath(state.clipPath(), state.clipOperation());
+ } else if (flags & DirtyClipRegion) {
+ updateClipRegion(state.clipRegion(), state.clipOperation());
+ }
+
+ // If the clip has changed we need to update all other states
+ // too, since they are included in the system context on OSX,
+ // and changing the clip resets that context back to scratch.
+ if (flags & (DirtyClipPath | DirtyClipRegion | DirtyClipEnabled))
+ flags |= AllDirty;
+
+ if (flags & DirtyPen)
+ updatePen(state.pen());
+ if (flags & (DirtyBrush|DirtyBrushOrigin))
+ updateBrush(state.brush(), state.brushOrigin());
+ if (flags & DirtyFont)
+ updateFont(state.font());
+ if (flags & DirtyOpacity)
+ updateOpacity(state.opacity());
+ if (flags & DirtyHints)
+ updateRenderHints(state.renderHints());
+ if (flags & DirtyCompositionMode)
+ updateCompositionMode(state.compositionMode());
+
+ if (flags & (DirtyPen | DirtyTransform)) {
+ if (!d->current.pen.isCosmetic()) {
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticNone;
+ } else if (d->current.transform.m11() < d->current.transform.m22()-1.0 ||
+ d->current.transform.m11() > d->current.transform.m22()+1.0) {
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath;
+ d->cosmeticPenSize = d->adjustPenWidth(d->current.pen.widthF());
+ if (!d->cosmeticPenSize)
+ d->cosmeticPenSize = 1.0;
+ } else {
+ d->cosmeticPen = QCoreGraphicsPaintEnginePrivate::CosmeticSetPenWidth;
+ static const float sqrt2 = sqrt(2);
+ qreal width = d->current.pen.widthF();
+ if (!width)
+ width = 1;
+ d->cosmeticPenSize = sqrt(pow(d->pixelSize.y(), 2) + pow(d->pixelSize.x(), 2)) / sqrt2 * width;
+ }
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::updatePen(const QPen &pen)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ d->current.pen = pen;
+ d->setStrokePen(pen);
+}
+
+void
+QCoreGraphicsPaintEngine::updateBrush(const QBrush &brush, const QPointF &brushOrigin)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ d->current.brush = brush;
+
+#ifdef QT_MAC_USE_NATIVE_GRADIENTS
+ // Quartz supports only pad spread
+ if (const QGradient *gradient = brush.gradient()) {
+ if (drawGradientNatively(gradient)) {
+ gccaps |= QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill;
+ } else {
+ gccaps &= ~(QPaintEngine::LinearGradientFill | QPaintEngine::RadialGradientFill);
+ }
+ }
+#endif
+
+ if (d->shading) {
+ CGShadingRelease(d->shading);
+ d->shading = 0;
+ }
+ d->setFillBrush(brushOrigin);
+}
+
+void
+QCoreGraphicsPaintEngine::updateOpacity(qreal opacity)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ CGContextSetAlpha(d->hd, opacity);
+}
+
+void
+QCoreGraphicsPaintEngine::updateFont(const QFont &)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ updatePen(d->current.pen);
+}
+
+void
+QCoreGraphicsPaintEngine::updateMatrix(const QTransform &transform)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (qt_is_nan(transform.m11()) || qt_is_nan(transform.m12()) || qt_is_nan(transform.m13())
+ || qt_is_nan(transform.m21()) || qt_is_nan(transform.m22()) || qt_is_nan(transform.m23())
+ || qt_is_nan(transform.m31()) || qt_is_nan(transform.m32()) || qt_is_nan(transform.m33()))
+ return;
+
+ d->current.transform = transform;
+ d->setTransform(transform.isIdentity() ? 0 : &transform);
+ d->complexXForm = (transform.m11() != 1 || transform.m22() != 1
+ || transform.m12() != 0 || transform.m21() != 0);
+ d->pixelSize = d->devicePixelSize(d->hd);
+}
+
+void
+QCoreGraphicsPaintEngine::updateClipPath(const QPainterPath &p, Qt::ClipOperation op)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ if (op == Qt::NoClip) {
+ if (d->current.clipEnabled) {
+ d->current.clipEnabled = false;
+ d->current.clip = QRegion();
+ d->setClip(0);
+ }
+ } else {
+ if (!d->current.clipEnabled)
+ op = Qt::ReplaceClip;
+ d->current.clipEnabled = true;
+ QRegion clipRegion(p.toFillPolygon().toPolygon(), p.fillRule());
+ if (op == Qt::ReplaceClip) {
+ d->current.clip = clipRegion;
+ d->setClip(0);
+ if (p.isEmpty()) {
+ CGRect rect = CGRectMake(0, 0, 0, 0);
+ CGContextClipToRect(d->hd, rect);
+ } else {
+ CGMutablePathRef path = qt_mac_compose_path(p);
+ CGContextBeginPath(d->hd);
+ CGContextAddPath(d->hd, path);
+ if (p.fillRule() == Qt::WindingFill)
+ CGContextClip(d->hd);
+ else
+ CGContextEOClip(d->hd);
+ CGPathRelease(path);
+ }
+ } else if (op == Qt::IntersectClip) {
+ d->current.clip = d->current.clip.intersected(clipRegion);
+ d->setClip(&d->current.clip);
+ }
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::updateClipRegion(const QRegion &clipRegion, Qt::ClipOperation op)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+ if (op == Qt::NoClip) {
+ d->current.clipEnabled = false;
+ d->current.clip = QRegion();
+ d->setClip(0);
+ } else {
+ if (!d->current.clipEnabled)
+ op = Qt::ReplaceClip;
+ d->current.clipEnabled = true;
+ if (op == Qt::IntersectClip)
+ d->current.clip = d->current.clip.intersected(clipRegion);
+ else if (op == Qt::ReplaceClip)
+ d->current.clip = clipRegion;
+ d->setClip(&d->current.clip);
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::drawPath(const QPainterPath &p)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = qt_mac_compose_path(p);
+ uchar ops = QCoreGraphicsPaintEnginePrivate::CGStroke;
+ if (p.fillRule() == Qt::WindingFill)
+ ops |= QCoreGraphicsPaintEnginePrivate::CGFill;
+ else
+ ops |= QCoreGraphicsPaintEnginePrivate::CGEOFill;
+ CGContextBeginPath(d->hd);
+ d->drawPath(ops, path);
+ CGPathRelease(path);
+}
+
+void
+QCoreGraphicsPaintEngine::drawRects(const QRectF *rects, int rectCount)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ for (int i=0; i<rectCount; ++i) {
+ QRectF r = rects[i];
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ CGPathAddRect(path, 0, qt_mac_compose_rect(r));
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill|QCoreGraphicsPaintEnginePrivate::CGStroke,
+ path);
+ CGPathRelease(path);
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::drawPoints(const QPointF *points, int pointCount)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ if (d->current.pen.capStyle() == Qt::FlatCap)
+ CGContextSetLineCap(d->hd, kCGLineCapSquare);
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ for (int i=0; i < pointCount; i++) {
+ float x = points[i].x(), y = points[i].y();
+ CGPathMoveToPoint(path, 0, x, y);
+ CGPathAddLineToPoint(path, 0, x+0.001, y);
+ }
+
+ bool doRestore = false;
+ if (d->cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticNone && !(state->renderHints() & QPainter::Antialiasing)) {
+ //we don't want adjusted pens for point rendering
+ doRestore = true;
+ d->saveGraphicsState();
+ CGContextSetLineWidth(d->hd, d->current.pen.widthF());
+ }
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path);
+ if (doRestore)
+ d->restoreGraphicsState();
+ CGPathRelease(path);
+ if (d->current.pen.capStyle() == Qt::FlatCap)
+ CGContextSetLineCap(d->hd, kCGLineCapButt);
+}
+
+void
+QCoreGraphicsPaintEngine::drawEllipse(const QRectF &r)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ CGAffineTransform transform = CGAffineTransformMakeScale(r.width() / r.height(), 1);
+ CGPathAddArc(path, &transform,(r.x() + (r.width() / 2)) / (r.width() / r.height()),
+ r.y() + (r.height() / 2), r.height() / 2, 0, (2 * M_PI), false);
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGFill | QCoreGraphicsPaintEnginePrivate::CGStroke,
+ path);
+ CGPathRelease(path);
+}
+
+void
+QCoreGraphicsPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ CGPathMoveToPoint(path, 0, points[0].x(), points[0].y());
+ for (int x = 1; x < pointCount; ++x)
+ CGPathAddLineToPoint(path, 0, points[x].x(), points[x].y());
+ if (mode != PolylineMode && points[0] != points[pointCount-1])
+ CGPathAddLineToPoint(path, 0, points[0].x(), points[0].y());
+ uint op = QCoreGraphicsPaintEnginePrivate::CGStroke;
+ if (mode != PolylineMode)
+ op |= mode == OddEvenMode ? QCoreGraphicsPaintEnginePrivate::CGEOFill
+ : QCoreGraphicsPaintEnginePrivate::CGFill;
+ d->drawPath(op, path);
+ CGPathRelease(path);
+}
+
+void
+QCoreGraphicsPaintEngine::drawLines(const QLineF *lines, int lineCount)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ CGMutablePathRef path = CGPathCreateMutable();
+ for (int i = 0; i < lineCount; i++) {
+ const QPointF start = lines[i].p1(), end = lines[i].p2();
+ CGPathMoveToPoint(path, 0, start.x(), start.y());
+ CGPathAddLineToPoint(path, 0, end.x(), end.y());
+ }
+ d->drawPath(QCoreGraphicsPaintEnginePrivate::CGStroke, path);
+ CGPathRelease(path);
+}
+
+void QCoreGraphicsPaintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ if (pm.isNull())
+ return;
+
+ bool differentSize = (QRectF(0, 0, pm.width(), pm.height()) != sr), doRestore = false;
+ CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ QCFType<CGImageRef> image;
+ bool isBitmap = (pm.depth() == 1);
+ if (isBitmap) {
+ doRestore = true;
+ d->saveGraphicsState();
+
+ const QColor &col = d->current.pen.color();
+ CGContextSetFillColorWithColor(d->hd, cgColorForQColor(col, d->pdev));
+ image = qt_mac_create_imagemask(pm, sr);
+ } else if (differentSize) {
+ QCFType<CGImageRef> img = qt_mac_image_to_cgimage(pm.toImage());
+ image = CGImageCreateWithImageInRect(img, CGRectMake(qRound(sr.x()), qRound(sr.y()), qRound(sr.width()), qRound(sr.height())));
+ } else {
+ image = qt_mac_image_to_cgimage(pm.toImage());
+ }
+ qt_mac_drawCGImage(d->hd, &rect, image);
+ if (doRestore)
+ d->restoreGraphicsState();
+}
+
+static void drawImageReleaseData (void *info, const void *, size_t)
+{
+ delete static_cast<QImage *>(info);
+}
+
+CGImageRef qt_mac_createCGImageFromQImage(const QImage &img, const QImage **imagePtr = 0)
+{
+ QImage *image;
+ if (img.depth() != 32)
+ image = new QImage(img.convertToFormat(QImage::Format_ARGB32_Premultiplied));
+ else
+ image = new QImage(img);
+
+ uint cgflags = kCGImageAlphaNone;
+ switch (image->format()) {
+ case QImage::Format_ARGB32_Premultiplied:
+ cgflags = kCGImageAlphaPremultipliedFirst;
+ break;
+ case QImage::Format_ARGB32:
+ cgflags = kCGImageAlphaFirst;
+ break;
+ case QImage::Format_RGB32:
+ cgflags = kCGImageAlphaNoneSkipFirst;
+ default:
+ break;
+ }
+#if defined(kCGBitmapByteOrder32Host) //only needed because CGImage.h added symbols in the minor version
+ cgflags |= kCGBitmapByteOrder32Host;
+#endif
+ QCFType<CGDataProviderRef> dataProvider = CGDataProviderCreateWithData(image,
+ static_cast<const QImage *>(image)->bits(),
+ image->byteCount(),
+ drawImageReleaseData);
+ if (imagePtr)
+ *imagePtr = image;
+ return CGImageCreate(image->width(), image->height(), 8, 32,
+ image->bytesPerLine(),
+ QCoreGraphicsPaintEngine::macGenericColorSpace(),
+ cgflags, dataProvider, 0, false, kCGRenderingIntentDefault);
+
+}
+
+void QCoreGraphicsPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr,
+ Qt::ImageConversionFlags flags)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_UNUSED(flags);
+ Q_ASSERT(isActive());
+
+ if (img.isNull() || state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ const QImage *image;
+ QCFType<CGImageRef> cgimage = qt_mac_createCGImageFromQImage(img, &image);
+ CGRect rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ if (QRectF(0, 0, img.width(), img.height()) != sr)
+ cgimage = CGImageCreateWithImageInRect(cgimage, CGRectMake(sr.x(), sr.y(),
+ sr.width(), sr.height()));
+ qt_mac_drawCGImage(d->hd, &rect, cgimage);
+}
+
+void QCoreGraphicsPaintEngine::initialize()
+{
+}
+
+void QCoreGraphicsPaintEngine::cleanup()
+{
+}
+
+CGContextRef
+QCoreGraphicsPaintEngine::handle() const
+{
+ return d_func()->hd;
+}
+
+void
+QCoreGraphicsPaintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap,
+ const QPointF &p)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ Q_ASSERT(isActive());
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ //save the old state
+ d->saveGraphicsState();
+
+ //setup the pattern
+ QMacPattern *qpattern = new QMacPattern;
+ qpattern->data.pixmap = pixmap;
+ qpattern->foreground = d->current.pen.color();
+ qpattern->pdev = d->pdev;
+ CGPatternCallbacks callbks;
+ callbks.version = 0;
+ callbks.drawPattern = qt_mac_draw_pattern;
+ callbks.releaseInfo = qt_mac_dispose_pattern;
+ const int width = qpattern->width(), height = qpattern->height();
+ CGAffineTransform trans = CGContextGetCTM(d->hd);
+ CGPatternRef pat = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height),
+ trans, width, height,
+ kCGPatternTilingNoDistortion, true, &callbks);
+ CGColorSpaceRef cs = CGColorSpaceCreatePattern(0);
+ CGContextSetFillColorSpace(d->hd, cs);
+ CGFloat component = 1.0; //just one
+ CGContextSetFillPattern(d->hd, pat, &component);
+ CGSize phase = CGSizeApplyAffineTransform(CGSizeMake(-(p.x()-r.x()), -(p.y()-r.y())), trans);
+ CGContextSetPatternPhase(d->hd, phase);
+
+ //fill the rectangle
+ CGRect mac_rect = CGRectMake(r.x(), r.y(), r.width(), r.height());
+ CGContextFillRect(d->hd, mac_rect);
+
+ //restore the state
+ d->restoreGraphicsState();
+ //cleanup
+ CGColorSpaceRelease(cs);
+ CGPatternRelease(pat);
+}
+
+void QCoreGraphicsPaintEngine::drawTextItem(const QPointF &pos, const QTextItem &item)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ if (d->current.transform.type() == QTransform::TxProject
+#ifndef QMAC_NATIVE_GRADIENTS
+ || painter()->pen().brush().gradient() //Just let the base engine "emulate" the gradient
+#endif
+ ) {
+ QPaintEngine::drawTextItem(pos, item);
+ return;
+ }
+
+ if (state->compositionMode() == QPainter::CompositionMode_Destination)
+ return;
+
+ const QTextItemInt &ti = static_cast<const QTextItemInt &>(item);
+
+ QPen oldPen = painter()->pen();
+ QBrush oldBrush = painter()->brush();
+ QPointF oldBrushOrigin = painter()->brushOrigin();
+ updatePen(Qt::NoPen);
+ updateBrush(oldPen.brush(), QPointF(0, 0));
+
+ Q_ASSERT(type() == QPaintEngine::CoreGraphics);
+
+ QFontEngine *fe = ti.fontEngine;
+
+ const bool textAA = state->renderHints() & QPainter::TextAntialiasing && fe->fontDef.pointSize > qt_antialiasing_threshold && !(fe->fontDef.styleStrategy & QFont::NoAntialias);
+ const bool lineAA = state->renderHints() & QPainter::Antialiasing;
+ if (textAA != lineAA)
+ CGContextSetShouldAntialias(d->hd, textAA);
+
+ if (ti.glyphs.numGlyphs) {
+ switch (fe->type()) {
+ case QFontEngine::Mac:
+ static_cast<QCoreTextFontEngine *>(fe)->draw(d->hd, pos.x(), pos.y(), ti, paintDevice()->height());
+ break;
+ case QFontEngine::Box:
+ d->drawBoxTextItem(pos, ti);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (textAA != lineAA)
+ CGContextSetShouldAntialias(d->hd, !textAA);
+
+ updatePen(oldPen);
+ updateBrush(oldBrush, oldBrushOrigin);
+}
+
+QPainter::RenderHints
+QCoreGraphicsPaintEngine::supportedRenderHints() const
+{
+ return QPainter::RenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform);
+}
+enum CGCompositeMode {
+ kCGCompositeModeClear = 0,
+ kCGCompositeModeCopy = 1,
+ kCGCompositeModeSourceOver = 2,
+ kCGCompositeModeSourceIn = 3,
+ kCGCompositeModeSourceOut = 4,
+ kCGCompositeModeSourceAtop = 5,
+ kCGCompositeModeDestinationOver = 6,
+ kCGCompositeModeDestinationIn = 7,
+ kCGCompositeModeDestinationOut = 8,
+ kCGCompositeModeDestinationAtop = 9,
+ kCGCompositeModeXOR = 10,
+ kCGCompositeModePlusDarker = 11, // (max (0, (1-d) + (1-s)))
+ kCGCompositeModePlusLighter = 12, // (min (1, s + d))
+ };
+extern "C" {
+ extern void CGContextSetCompositeOperation(CGContextRef, int);
+} // private function, but is in all versions of OS X.
+void
+QCoreGraphicsPaintEngine::updateCompositionMode(QPainter::CompositionMode mode)
+{
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
+ int cg_mode = kCGBlendModeNormal;
+ switch (mode) {
+ case QPainter::CompositionMode_Multiply:
+ cg_mode = kCGBlendModeMultiply;
+ break;
+ case QPainter::CompositionMode_Screen:
+ cg_mode = kCGBlendModeScreen;
+ break;
+ case QPainter::CompositionMode_Overlay:
+ cg_mode = kCGBlendModeOverlay;
+ break;
+ case QPainter::CompositionMode_Darken:
+ cg_mode = kCGBlendModeDarken;
+ break;
+ case QPainter::CompositionMode_Lighten:
+ cg_mode = kCGBlendModeLighten;
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ cg_mode = kCGBlendModeColorDodge;
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ cg_mode = kCGBlendModeColorBurn;
+ break;
+ case QPainter::CompositionMode_HardLight:
+ cg_mode = kCGBlendModeHardLight;
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ cg_mode = kCGBlendModeSoftLight;
+ break;
+ case QPainter::CompositionMode_Difference:
+ cg_mode = kCGBlendModeDifference;
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ cg_mode = kCGBlendModeExclusion;
+ break;
+ case QPainter::CompositionMode_Plus:
+ cg_mode = kCGBlendModePlusLighter;
+ break;
+ case QPainter::CompositionMode_SourceOver:
+ cg_mode = kCGBlendModeNormal;
+ break;
+ case QPainter::CompositionMode_DestinationOver:
+ cg_mode = kCGBlendModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_Clear:
+ cg_mode = kCGBlendModeClear;
+ break;
+ case QPainter::CompositionMode_Source:
+ cg_mode = kCGBlendModeCopy;
+ break;
+ case QPainter::CompositionMode_Destination:
+ cg_mode = -1;
+ break;
+ case QPainter::CompositionMode_SourceIn:
+ cg_mode = kCGBlendModeSourceIn;
+ break;
+ case QPainter::CompositionMode_DestinationIn:
+ cg_mode = kCGCompositeModeDestinationIn;
+ break;
+ case QPainter::CompositionMode_SourceOut:
+ cg_mode = kCGBlendModeSourceOut;
+ break;
+ case QPainter::CompositionMode_DestinationOut:
+ cg_mode = kCGBlendModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_SourceAtop:
+ cg_mode = kCGBlendModeSourceAtop;
+ break;
+ case QPainter::CompositionMode_DestinationAtop:
+ cg_mode = kCGBlendModeDestinationAtop;
+ break;
+ case QPainter::CompositionMode_Xor:
+ cg_mode = kCGBlendModeXOR;
+ break;
+ default:
+ break;
+ }
+ if (cg_mode > -1) {
+ CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
+ }
+ } else
+#endif
+ // The standard porter duff ops.
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_3
+ && mode <= QPainter::CompositionMode_Xor) {
+ int cg_mode = kCGCompositeModeCopy;
+ switch (mode) {
+ case QPainter::CompositionMode_SourceOver:
+ cg_mode = kCGCompositeModeSourceOver;
+ break;
+ case QPainter::CompositionMode_DestinationOver:
+ cg_mode = kCGCompositeModeDestinationOver;
+ break;
+ case QPainter::CompositionMode_Clear:
+ cg_mode = kCGCompositeModeClear;
+ break;
+ default:
+ qWarning("QCoreGraphicsPaintEngine: Unhandled composition mode %d", (int)mode);
+ break;
+ case QPainter::CompositionMode_Source:
+ cg_mode = kCGCompositeModeCopy;
+ break;
+ case QPainter::CompositionMode_Destination:
+ cg_mode = CGCompositeMode(-1);
+ break;
+ case QPainter::CompositionMode_SourceIn:
+ cg_mode = kCGCompositeModeSourceIn;
+ break;
+ case QPainter::CompositionMode_DestinationIn:
+ cg_mode = kCGCompositeModeDestinationIn;
+ break;
+ case QPainter::CompositionMode_SourceOut:
+ cg_mode = kCGCompositeModeSourceOut;
+ break;
+ case QPainter::CompositionMode_DestinationOut:
+ cg_mode = kCGCompositeModeDestinationOut;
+ break;
+ case QPainter::CompositionMode_SourceAtop:
+ cg_mode = kCGCompositeModeSourceAtop;
+ break;
+ case QPainter::CompositionMode_DestinationAtop:
+ cg_mode = kCGCompositeModeDestinationAtop;
+ break;
+ case QPainter::CompositionMode_Xor:
+ cg_mode = kCGCompositeModeXOR;
+ break;
+ }
+ if (cg_mode > -1)
+ CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
+ } else {
+#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
+ bool needPrivateAPI = false;
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_4) {
+ int cg_mode = kCGBlendModeNormal;
+ switch (mode) {
+ case QPainter::CompositionMode_Multiply:
+ cg_mode = kCGBlendModeMultiply;
+ break;
+ case QPainter::CompositionMode_Screen:
+ cg_mode = kCGBlendModeScreen;
+ break;
+ case QPainter::CompositionMode_Overlay:
+ cg_mode = kCGBlendModeOverlay;
+ break;
+ case QPainter::CompositionMode_Darken:
+ cg_mode = kCGBlendModeDarken;
+ break;
+ case QPainter::CompositionMode_Lighten:
+ cg_mode = kCGBlendModeLighten;
+ break;
+ case QPainter::CompositionMode_ColorDodge:
+ cg_mode = kCGBlendModeColorDodge;
+ break;
+ case QPainter::CompositionMode_ColorBurn:
+ cg_mode = kCGBlendModeColorBurn;
+ break;
+ case QPainter::CompositionMode_HardLight:
+ cg_mode = kCGBlendModeHardLight;
+ break;
+ case QPainter::CompositionMode_SoftLight:
+ cg_mode = kCGBlendModeSoftLight;
+ break;
+ case QPainter::CompositionMode_Difference:
+ cg_mode = kCGBlendModeDifference;
+ break;
+ case QPainter::CompositionMode_Exclusion:
+ cg_mode = kCGBlendModeExclusion;
+ break;
+ case QPainter::CompositionMode_Plus:
+ needPrivateAPI = true;
+ cg_mode = kCGCompositeModePlusLighter;
+ break;
+ default:
+ break;
+ }
+ if (!needPrivateAPI)
+ CGContextSetBlendMode(d_func()->hd, CGBlendMode(cg_mode));
+ else
+ CGContextSetCompositeOperation(d_func()->hd, CGCompositeMode(cg_mode));
+ }
+#endif
+ }
+}
+
+void
+QCoreGraphicsPaintEngine::updateRenderHints(QPainter::RenderHints hints)
+{
+ Q_D(QCoreGraphicsPaintEngine);
+ CGContextSetShouldAntialias(d->hd, hints & QPainter::Antialiasing);
+ static const CGFloat ScaleFactor = qt_mac_get_scalefactor();
+ if (ScaleFactor > 1.) {
+ CGContextSetInterpolationQuality(d->hd, kCGInterpolationHigh);
+ } else {
+ CGContextSetInterpolationQuality(d->hd, (hints & QPainter::SmoothPixmapTransform) ?
+ kCGInterpolationHigh : kCGInterpolationNone);
+ }
+ bool textAntialiasing = (hints & QPainter::TextAntialiasing) == QPainter::TextAntialiasing;
+ if (!textAntialiasing || d->disabledSmoothFonts) {
+ d->disabledSmoothFonts = !textAntialiasing;
+ CGContextSetShouldSmoothFonts(d->hd, textAntialiasing);
+ }
+}
+
+/*
+ Returns the size of one device pixel in user-space coordinates.
+*/
+QPointF QCoreGraphicsPaintEnginePrivate::devicePixelSize(CGContextRef)
+{
+ QPointF p1 = current.transform.inverted().map(QPointF(0, 0));
+ QPointF p2 = current.transform.inverted().map(QPointF(1, 1));
+ return QPointF(qAbs(p2.x() - p1.x()), qAbs(p2.y() - p1.y()));
+}
+
+/*
+ Adjusts the pen width so we get correct line widths in the
+ non-transformed, aliased case.
+*/
+float QCoreGraphicsPaintEnginePrivate::adjustPenWidth(float penWidth)
+{
+ Q_Q(QCoreGraphicsPaintEngine);
+ float ret = penWidth;
+ if (!complexXForm && !(q->state->renderHints() & QPainter::Antialiasing)) {
+ if (penWidth < 2)
+ ret = 1;
+ else if (penWidth < 3)
+ ret = 1.5;
+ else
+ ret = penWidth -1;
+ }
+ return ret;
+}
+
+void
+QCoreGraphicsPaintEnginePrivate::setStrokePen(const QPen &pen)
+{
+ //pencap
+ CGLineCap cglinecap = kCGLineCapButt;
+ if (pen.capStyle() == Qt::SquareCap)
+ cglinecap = kCGLineCapSquare;
+ else if (pen.capStyle() == Qt::RoundCap)
+ cglinecap = kCGLineCapRound;
+ CGContextSetLineCap(hd, cglinecap);
+ CGContextSetLineWidth(hd, adjustPenWidth(pen.widthF()));
+
+ //join
+ CGLineJoin cglinejoin = kCGLineJoinMiter;
+ if (pen.joinStyle() == Qt::BevelJoin)
+ cglinejoin = kCGLineJoinBevel;
+ else if (pen.joinStyle() == Qt::RoundJoin)
+ cglinejoin = kCGLineJoinRound;
+ CGContextSetLineJoin(hd, cglinejoin);
+// CGContextSetMiterLimit(hd, pen.miterLimit());
+
+ //pen style
+ QVector<CGFloat> linedashes;
+ if (pen.style() == Qt::CustomDashLine) {
+ QVector<qreal> customs = pen.dashPattern();
+ for (int i = 0; i < customs.size(); ++i)
+ linedashes.append(customs.at(i));
+ } else if (pen.style() == Qt::DashLine) {
+ linedashes.append(4);
+ linedashes.append(2);
+ } else if (pen.style() == Qt::DotLine) {
+ linedashes.append(1);
+ linedashes.append(2);
+ } else if (pen.style() == Qt::DashDotLine) {
+ linedashes.append(4);
+ linedashes.append(2);
+ linedashes.append(1);
+ linedashes.append(2);
+ } else if (pen.style() == Qt::DashDotDotLine) {
+ linedashes.append(4);
+ linedashes.append(2);
+ linedashes.append(1);
+ linedashes.append(2);
+ linedashes.append(1);
+ linedashes.append(2);
+ }
+ const CGFloat cglinewidth = pen.widthF() <= 0.0f ? 1.0f : float(pen.widthF());
+ for (int i = 0; i < linedashes.size(); ++i) {
+ linedashes[i] *= cglinewidth;
+ if (cglinewidth < 3 && (cglinecap == kCGLineCapSquare || cglinecap == kCGLineCapRound)) {
+ if ((i%2))
+ linedashes[i] += cglinewidth/2;
+ else
+ linedashes[i] -= cglinewidth/2;
+ }
+ }
+ CGContextSetLineDash(hd, pen.dashOffset() * cglinewidth, linedashes.data(), linedashes.size());
+
+ // color
+ CGContextSetStrokeColorWithColor(hd, cgColorForQColor(pen.color(), pdev));
+}
+
+// Add our own patterns here to deal with the fact that the coordinate system
+// is flipped vertically with Quartz2D.
+static const uchar *qt_mac_patternForBrush(int brushStyle)
+{
+ Q_ASSERT(brushStyle > Qt::SolidPattern && brushStyle < Qt::LinearGradientPattern);
+ static const uchar dense1_pat[] = { 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x44, 0x00 };
+ static const uchar dense2_pat[] = { 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00, 0x88 };
+ static const uchar dense3_pat[] = { 0x11, 0xaa, 0x44, 0xaa, 0x11, 0xaa, 0x44, 0xaa };
+ static const uchar dense4_pat[] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
+ static const uchar dense5_pat[] = { 0xee, 0x55, 0xbb, 0x55, 0xee, 0x55, 0xbb, 0x55 };
+ static const uchar dense6_pat[] = { 0xff, 0xdd, 0xff, 0x77, 0xff, 0xdd, 0xff, 0x77 };
+ static const uchar dense7_pat[] = { 0xff, 0xff, 0xbb, 0xff, 0xff, 0xff, 0xbb, 0xff };
+ static const uchar hor_pat[] = { 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff };
+ static const uchar ver_pat[] = { 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef };
+ static const uchar cross_pat[] = { 0xef, 0xef, 0xef, 0xef, 0x00, 0xef, 0xef, 0xef };
+ static const uchar fdiag_pat[] = { 0x7f, 0xbf, 0xdf, 0xef, 0xf7, 0xfb, 0xfd, 0xfe };
+ static const uchar bdiag_pat[] = { 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f };
+ static const uchar dcross_pat[] = { 0x7e, 0xbd, 0xdb, 0xe7, 0xe7, 0xdb, 0xbd, 0x7e };
+ static const uchar *const pat_tbl[] = {
+ dense1_pat, dense2_pat, dense3_pat, dense4_pat, dense5_pat,
+ dense6_pat, dense7_pat,
+ hor_pat, ver_pat, cross_pat, bdiag_pat, fdiag_pat, dcross_pat };
+ return pat_tbl[brushStyle - Qt::Dense1Pattern];
+}
+
+void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset)
+{
+ // pattern
+ Qt::BrushStyle bs = current.brush.style();
+#ifdef QT_MAC_USE_NATIVE_GRADIENTS
+ if (bs == Qt::LinearGradientPattern || bs == Qt::RadialGradientPattern) {
+ const QGradient *grad = static_cast<const QGradient*>(current.brush.gradient());
+ if (drawGradientNatively(grad)) {
+ Q_ASSERT(grad->spread() == QGradient::PadSpread);
+
+ static const CGFloat domain[] = { 0.0f, +1.0f };
+ static const CGFunctionCallbacks callbacks = { 0, qt_mac_color_gradient_function, 0 };
+ CGFunctionRef fill_func = CGFunctionCreate(reinterpret_cast<void *>(&current.brush),
+ 1, domain, 4, 0, &callbacks);
+
+ CGColorSpaceRef colorspace = qt_mac_colorSpaceForDeviceType(pdev);
+ if (bs == Qt::LinearGradientPattern) {
+ const QLinearGradient *linearGrad = static_cast<const QLinearGradient *>(grad);
+ const QPointF start(linearGrad->start());
+ const QPointF stop(linearGrad->finalStop());
+ shading = CGShadingCreateAxial(colorspace, CGPointMake(start.x(), start.y()),
+ CGPointMake(stop.x(), stop.y()), fill_func, true, true);
+ } else {
+ Q_ASSERT(bs == Qt::RadialGradientPattern);
+ const QRadialGradient *radialGrad = static_cast<const QRadialGradient *>(grad);
+ QPointF center(radialGrad->center());
+ QPointF focal(radialGrad->focalPoint());
+ qreal radius = radialGrad->radius();
+ qreal focalRadius = radialGrad->focalRadius();
+ shading = CGShadingCreateRadial(colorspace, CGPointMake(focal.x(), focal.y()),
+ focalRadius, CGPointMake(center.x(), center.y()), radius, fill_func, false, true);
+ }
+
+ CGFunctionRelease(fill_func);
+ }
+ } else
+#endif
+ if (bs != Qt::SolidPattern && bs != Qt::NoBrush
+#ifndef QT_MAC_USE_NATIVE_GRADIENTS
+ && (bs < Qt::LinearGradientPattern || bs > Qt::ConicalGradientPattern)
+#endif
+ )
+ {
+ QMacPattern *qpattern = new QMacPattern;
+ qpattern->pdev = pdev;
+ CGFloat components[4] = { 1.0, 1.0, 1.0, 1.0 };
+ CGColorSpaceRef base_colorspace = 0;
+ if (bs == Qt::TexturePattern) {
+ qpattern->data.pixmap = current.brush.texture();
+ if (qpattern->data.pixmap.isQBitmap()) {
+ const QColor &col = current.brush.color();
+ components[0] = qt_mac_convert_color_to_cg(col.red());
+ components[1] = qt_mac_convert_color_to_cg(col.green());
+ components[2] = qt_mac_convert_color_to_cg(col.blue());
+ base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
+ }
+ } else {
+ qpattern->as_mask = true;
+
+ qpattern->data.bytes = qt_mac_patternForBrush(bs);
+ const QColor &col = current.brush.color();
+ components[0] = qt_mac_convert_color_to_cg(col.red());
+ components[1] = qt_mac_convert_color_to_cg(col.green());
+ components[2] = qt_mac_convert_color_to_cg(col.blue());
+ base_colorspace = QCoreGraphicsPaintEngine::macGenericColorSpace();
+ }
+ int width = qpattern->width(), height = qpattern->height();
+ qpattern->foreground = current.brush.color();
+
+ CGColorSpaceRef fill_colorspace = CGColorSpaceCreatePattern(base_colorspace);
+ CGContextSetFillColorSpace(hd, fill_colorspace);
+
+ CGAffineTransform xform = CGContextGetCTM(hd);
+ xform = CGAffineTransformConcat(qt_mac_convert_transform_to_cg(current.brush.transform()), xform);
+ xform = CGAffineTransformTranslate(xform, offset.x(), offset.y());
+
+ CGPatternCallbacks callbks;
+ callbks.version = 0;
+ callbks.drawPattern = qt_mac_draw_pattern;
+ callbks.releaseInfo = qt_mac_dispose_pattern;
+ CGPatternRef fill_pattern = CGPatternCreate(qpattern, CGRectMake(0, 0, width, height),
+ xform, width, height, kCGPatternTilingNoDistortion,
+ !base_colorspace, &callbks);
+ CGContextSetFillPattern(hd, fill_pattern, components);
+
+ CGPatternRelease(fill_pattern);
+ CGColorSpaceRelease(fill_colorspace);
+ } else if (bs != Qt::NoBrush) {
+ CGContextSetFillColorWithColor(hd, cgColorForQColor(current.brush.color(), pdev));
+ }
+}
+
+void
+QCoreGraphicsPaintEnginePrivate::setClip(const QRegion *rgn)
+{
+ Q_Q(QCoreGraphicsPaintEngine);
+ if (hd) {
+ resetClip();
+ QRegion sysClip = q->systemClip();
+ if (!sysClip.isEmpty())
+ qt_mac_clip_cg(hd, sysClip, &orig_xform);
+ if (rgn)
+ qt_mac_clip_cg(hd, *rgn, 0);
+ }
+}
+
+struct qt_mac_cg_transform_path {
+ CGMutablePathRef path;
+ CGAffineTransform transform;
+};
+
+void qt_mac_cg_transform_path_apply(void *info, const CGPathElement *element)
+{
+ Q_ASSERT(info && element);
+ qt_mac_cg_transform_path *t = (qt_mac_cg_transform_path*)info;
+ switch (element->type) {
+ case kCGPathElementMoveToPoint:
+ CGPathMoveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y);
+ break;
+ case kCGPathElementAddLineToPoint:
+ CGPathAddLineToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y);
+ break;
+ case kCGPathElementAddQuadCurveToPoint:
+ CGPathAddQuadCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y,
+ element->points[1].x, element->points[1].y);
+ break;
+ case kCGPathElementAddCurveToPoint:
+ CGPathAddCurveToPoint(t->path, &t->transform, element->points[0].x, element->points[0].y,
+ element->points[1].x, element->points[1].y,
+ element->points[2].x, element->points[2].y);
+ break;
+ case kCGPathElementCloseSubpath:
+ CGPathCloseSubpath(t->path);
+ break;
+ default:
+ qDebug() << "Unhandled path transform type: " << element->type;
+ }
+}
+
+void QCoreGraphicsPaintEnginePrivate::drawPath(uchar ops, CGMutablePathRef path)
+{
+ Q_Q(QCoreGraphicsPaintEngine);
+ Q_ASSERT((ops & (CGFill | CGEOFill)) != (CGFill | CGEOFill)); //can't really happen
+ if ((ops & (CGFill | CGEOFill))) {
+ if (shading) {
+ Q_ASSERT(path);
+ CGContextBeginPath(hd);
+ CGContextAddPath(hd, path);
+ saveGraphicsState();
+ if (ops & CGFill)
+ CGContextClip(hd);
+ else if (ops & CGEOFill)
+ CGContextEOClip(hd);
+ if (current.brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode) {
+ CGRect boundingBox = CGPathGetBoundingBox(path);
+ CGContextConcatCTM(hd,
+ CGAffineTransformMake(boundingBox.size.width, 0,
+ 0, boundingBox.size.height,
+ boundingBox.origin.x, boundingBox.origin.y));
+ }
+ CGContextDrawShading(hd, shading);
+ restoreGraphicsState();
+ ops &= ~CGFill;
+ ops &= ~CGEOFill;
+ } else if (current.brush.style() == Qt::NoBrush) {
+ ops &= ~CGFill;
+ ops &= ~CGEOFill;
+ }
+ }
+ if ((ops & CGStroke) && current.pen.style() == Qt::NoPen)
+ ops &= ~CGStroke;
+
+ if (ops & (CGEOFill | CGFill)) {
+ CGContextBeginPath(hd);
+ CGContextAddPath(hd, path);
+ if (ops & CGEOFill) {
+ CGContextEOFillPath(hd);
+ } else {
+ CGContextFillPath(hd);
+ }
+ }
+
+ // Avoid saving and restoring the context if we can.
+ const bool needContextSave = (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone ||
+ !(q->state->renderHints() & QPainter::Antialiasing));
+ if (ops & CGStroke) {
+ if (needContextSave)
+ saveGraphicsState();
+ CGContextBeginPath(hd);
+
+ // Translate a fraction of a pixel size in the y direction
+ // to make sure that primitives painted at pixel borders
+ // fills the right pixel. This is needed since the y xais
+ // in the Quartz coordinate system is inverted compared to Qt.
+ if (!(q->state->renderHints() & QPainter::Antialiasing)) {
+ if (current.pen.style() == Qt::SolidLine || current.pen.width() >= 3)
+ CGContextTranslateCTM(hd, double(pixelSize.x()) * 0.25, double(pixelSize.y()) * 0.25);
+ else if (current.pen.style() == Qt::DotLine && QSysInfo::MacintoshVersion == QSysInfo::MV_10_3)
+ ; // Do nothing.
+ else
+ CGContextTranslateCTM(hd, 0, double(pixelSize.y()) * 0.1);
+ }
+
+ if (cosmeticPen != QCoreGraphicsPaintEnginePrivate::CosmeticNone) {
+ // If antialiazing is enabled, use the cosmetic pen size directly.
+ if (q->state->renderHints() & QPainter::Antialiasing)
+ CGContextSetLineWidth(hd, cosmeticPenSize);
+ else if (current.pen.widthF() <= 1)
+ CGContextSetLineWidth(hd, cosmeticPenSize * 0.9f);
+ else
+ CGContextSetLineWidth(hd, cosmeticPenSize);
+ }
+ if (cosmeticPen == QCoreGraphicsPaintEnginePrivate::CosmeticTransformPath) {
+ qt_mac_cg_transform_path t;
+ t.transform = qt_mac_convert_transform_to_cg(current.transform);
+ t.path = CGPathCreateMutable();
+ CGPathApply(path, &t, qt_mac_cg_transform_path_apply); //transform the path
+ setTransform(0); //unset the context transform
+ CGContextSetLineWidth(hd, cosmeticPenSize);
+ CGContextAddPath(hd, t.path);
+ CGPathRelease(t.path);
+ } else {
+ CGContextAddPath(hd, path);
+ }
+
+ CGContextStrokePath(hd);
+ if (needContextSave)
+ restoreGraphicsState();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/cocoa/qpaintengine_mac_p.h b/src/plugins/platforms/cocoa/qpaintengine_mac_p.h
new file mode 100644
index 0000000000..0987d921fc
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qpaintengine_mac_p.h
@@ -0,0 +1,254 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPAINTENGINE_MAC_P_H
+#define QPAINTENGINE_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtGui/qpaintengine.h"
+#include "private/qpaintengine_p.h"
+#include "private/qpolygonclipper_p.h"
+#include "private/qfont_p.h"
+#include "QtCore/qhash.h"
+
+#include "qt_mac_p.h"
+
+typedef struct CGColorSpace *CGColorSpaceRef;
+QT_BEGIN_NAMESPACE
+
+class QCoreGraphicsPaintEnginePrivate;
+class QCoreGraphicsPaintEngine : public QPaintEngine
+{
+ Q_DECLARE_PRIVATE(QCoreGraphicsPaintEngine)
+
+public:
+ QCoreGraphicsPaintEngine();
+ ~QCoreGraphicsPaintEngine();
+
+ bool begin(QPaintDevice *pdev);
+ bool end();
+ static CGColorSpaceRef macGenericColorSpace();
+ static CGColorSpaceRef macDisplayColorSpace(const QWidget *widget = 0);
+
+ void updateState(const QPaintEngineState &state);
+
+ void updatePen(const QPen &pen);
+ void updateBrush(const QBrush &brush, const QPointF &pt);
+ void updateFont(const QFont &font);
+ void updateOpacity(qreal opacity);
+ void updateMatrix(const QTransform &matrix);
+ void updateTransform(const QTransform &matrix);
+ void updateClipRegion(const QRegion &region, Qt::ClipOperation op);
+ void updateClipPath(const QPainterPath &path, Qt::ClipOperation op);
+ void updateCompositionMode(QPainter::CompositionMode mode);
+ void updateRenderHints(QPainter::RenderHints hints);
+
+ void drawLines(const QLineF *lines, int lineCount);
+ void drawRects(const QRectF *rects, int rectCount);
+ void drawPoints(const QPointF *p, int pointCount);
+ void drawEllipse(const QRectF &r);
+ void drawPath(const QPainterPath &path);
+
+ void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+ void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+
+ void drawTextItem(const QPointF &pos, const QTextItem &item);
+ void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr,
+ Qt::ImageConversionFlags flags = Qt::AutoColor);
+
+ Type type() const { return QPaintEngine::CoreGraphics; }
+
+ CGContextRef handle() const;
+
+ static void initialize();
+ static void cleanup();
+
+ QPainter::RenderHints supportedRenderHints() const;
+
+ //avoid partial shadowed overload warnings...
+ void drawLines(const QLine *lines, int lineCount) { QPaintEngine::drawLines(lines, lineCount); }
+ void drawRects(const QRect *rects, int rectCount) { QPaintEngine::drawRects(rects, rectCount); }
+ void drawPoints(const QPoint *p, int pointCount) { QPaintEngine::drawPoints(p, pointCount); }
+ void drawEllipse(const QRect &r) { QPaintEngine::drawEllipse(r); }
+ void drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
+ { QPaintEngine::drawPolygon(points, pointCount, mode); }
+
+ bool supportsTransformations(qreal, const QTransform &) const { return true; };
+
+protected:
+ friend class QMacPrintEngine;
+ friend class QMacPrintEnginePrivate;
+ QCoreGraphicsPaintEngine(QPaintEnginePrivate &dptr);
+
+private:
+ static bool m_postRoutineRegistered;
+ static CGColorSpaceRef m_genericColorSpace;
+ static QHash<CGDirectDisplayID, CGColorSpaceRef> m_displayColorSpaceHash;
+ static void cleanUpMacColorSpaces();
+ Q_DISABLE_COPY(QCoreGraphicsPaintEngine)
+};
+
+/*****************************************************************************
+ Private data
+ *****************************************************************************/
+class QCoreGraphicsPaintEnginePrivate : public QPaintEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QCoreGraphicsPaintEngine)
+public:
+ QCoreGraphicsPaintEnginePrivate()
+ : hd(0), shading(0), stackCount(0), complexXForm(false), disabledSmoothFonts(false)
+ {
+ }
+
+ struct {
+ QPen pen;
+ QBrush brush;
+ uint clipEnabled : 1;
+ QRegion clip;
+ QTransform transform;
+ } current;
+
+ //state info (shared with QD)
+ CGAffineTransform orig_xform;
+
+ //cg structures
+ CGContextRef hd;
+ CGShadingRef shading;
+ int stackCount;
+ bool complexXForm;
+ bool disabledSmoothFonts;
+ enum { CosmeticNone, CosmeticTransformPath, CosmeticSetPenWidth } cosmeticPen;
+
+ // pixel and cosmetic pen size in user coordinates.
+ QPointF pixelSize;
+ float cosmeticPenSize;
+
+ //internal functions
+ enum { CGStroke=0x01, CGEOFill=0x02, CGFill=0x04 };
+ void drawPath(uchar ops, CGMutablePathRef path = 0);
+ void setClip(const QRegion *rgn=0);
+ void resetClip();
+ void setFillBrush(const QPointF &origin=QPoint());
+ void setStrokePen(const QPen &pen);
+ inline void saveGraphicsState();
+ inline void restoreGraphicsState();
+ float penOffset();
+ QPointF devicePixelSize(CGContextRef context);
+ float adjustPenWidth(float penWidth);
+ inline void setTransform(const QTransform *matrix=0)
+ {
+ CGContextConcatCTM(hd, CGAffineTransformInvert(CGContextGetCTM(hd)));
+ CGAffineTransform xform = orig_xform;
+ if (matrix) {
+ extern CGAffineTransform qt_mac_convert_transform_to_cg(const QTransform &);
+ xform = CGAffineTransformConcat(qt_mac_convert_transform_to_cg(*matrix), xform);
+ }
+ CGContextConcatCTM(hd, xform);
+ CGContextSetTextMatrix(hd, xform);
+ }
+};
+
+inline void QCoreGraphicsPaintEnginePrivate::saveGraphicsState()
+{
+ ++stackCount;
+ CGContextSaveGState(hd);
+}
+
+inline void QCoreGraphicsPaintEnginePrivate::restoreGraphicsState()
+{
+ --stackCount;
+ Q_ASSERT(stackCount >= 0);
+ CGContextRestoreGState(hd);
+}
+
+class QMacQuartzPaintDevice : public QPaintDevice
+{
+public:
+ QMacQuartzPaintDevice(CGContextRef cg, int width, int height, int bytesPerLine)
+ : mCG(cg), mWidth(width), mHeight(height), mBytesPerLine(bytesPerLine)
+ { }
+ int devType() const { return QInternal::MacQuartz; }
+ CGContextRef cgContext() const { return mCG; }
+ int metric(PaintDeviceMetric metric) const {
+ switch (metric) {
+ case PdmWidth:
+ return mWidth;
+ case PdmHeight:
+ return mHeight;
+ case PdmWidthMM:
+ return (qt_defaultDpiX() * mWidth) / 2.54;
+ case PdmHeightMM:
+ return (qt_defaultDpiY() * mHeight) / 2.54;
+ case PdmNumColors:
+ return 0;
+ case PdmDepth:
+ return 32;
+ case PdmDpiX:
+ case PdmPhysicalDpiX:
+ return qt_defaultDpiX();
+ case PdmDpiY:
+ case PdmPhysicalDpiY:
+ return qt_defaultDpiY();
+ }
+ return 0;
+ }
+ QPaintEngine *paintEngine() const { qWarning("This function should never be called."); return 0; }
+private:
+ CGContextRef mCG;
+ int mWidth;
+ int mHeight;
+ int mBytesPerLine;
+};
+
+QT_END_NAMESPACE
+
+#endif // QPAINTENGINE_MAC_P_H
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac.mm b/src/plugins/platforms/cocoa/qprintengine_mac.mm
new file mode 100644
index 0000000000..e432b12e67
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qprintengine_mac.mm
@@ -0,0 +1,817 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qprintengine_mac_p.h"
+#include <qdebug.h>
+#include <qthread.h>
+#include <QtCore/qcoreapplication.h>
+#include <QtPrintSupport/QPlatformPrinterSupport>
+
+#include "qcocoaautoreleasepool.h"
+
+#ifndef QT_NO_PRINTER
+
+QT_BEGIN_NAMESPACE
+
+QMacPrintEngine::QMacPrintEngine(QPrinter::PrinterMode mode) : QPaintEngine(*(new QMacPrintEnginePrivate))
+{
+ Q_D(QMacPrintEngine);
+ d->mode = mode;
+ d->initialize();
+}
+
+bool QMacPrintEngine::begin(QPaintDevice *dev)
+{
+ Q_D(QMacPrintEngine);
+
+ Q_ASSERT(dev && dev->devType() == QInternal::Printer);
+ if (!static_cast<QPrinter *>(dev)->isValid())
+ return false;
+
+ if (d->state == QPrinter::Idle && !d->isPrintSessionInitialized()) // Need to reinitialize
+ d->initialize();
+
+ d->paintEngine->state = state;
+ d->paintEngine->begin(dev);
+ Q_ASSERT_X(d->state == QPrinter::Idle, "QMacPrintEngine", "printer already active");
+
+ if (PMSessionValidatePrintSettings(d->session(), d->settings(), kPMDontWantBoolean) != noErr
+ || PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean) != noErr) {
+ d->state = QPrinter::Error;
+ return false;
+ }
+
+ if (!d->outputFilename.isEmpty()) {
+ QCFType<CFURLRef> outFile = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault,
+ QCFString(d->outputFilename),
+ kCFURLPOSIXPathStyle,
+ false);
+ if (PMSessionSetDestination(d->session(), d->settings(), kPMDestinationFile,
+ kPMDocumentFormatPDF, outFile) != noErr) {
+ qWarning("QMacPrintEngine::begin: Problem setting file [%s]", d->outputFilename.toUtf8().constData());
+ return false;
+ }
+ }
+
+ OSStatus status = PMSessionBeginCGDocumentNoDialog(d->session(), d->settings(), d->format());
+ if (status != noErr) {
+ d->state = QPrinter::Error;
+ return false;
+ }
+
+ d->state = QPrinter::Active;
+ setActive(true);
+ d->newPage_helper();
+ return true;
+}
+
+bool QMacPrintEngine::end()
+{
+ Q_D(QMacPrintEngine);
+ if (d->state == QPrinter::Aborted)
+ return true; // I was just here a function call ago :)
+ if (d->paintEngine->type() == QPaintEngine::CoreGraphics) {
+ // We dont need the paint engine to call restoreGraphicsState()
+ static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->stackCount = 0;
+ static_cast<QCoreGraphicsPaintEngine*>(d->paintEngine)->d_func()->hd = 0;
+ }
+ d->paintEngine->end();
+ if (d->state != QPrinter::Idle)
+ d->releaseSession();
+ d->state = QPrinter::Idle;
+ return true;
+}
+
+QPaintEngine *
+QMacPrintEngine::paintEngine() const
+{
+ return d_func()->paintEngine;
+}
+
+Qt::HANDLE QMacPrintEngine::handle() const
+{
+ QCoreGraphicsPaintEngine *cgEngine = static_cast<QCoreGraphicsPaintEngine*>(paintEngine());
+ return cgEngine->d_func()->hd;
+}
+
+QMacPrintEnginePrivate::~QMacPrintEnginePrivate()
+{
+ [printInfo release];
+ delete paintEngine;
+}
+
+void QMacPrintEnginePrivate::setPaperSize(QPrinter::PaperSize ps)
+{
+ Q_Q(QMacPrintEngine);
+ QSizeF newSize = QPlatformPrinterSupport::convertPaperSizeToQSizeF(ps);
+ QCFType<CFArrayRef> formats;
+ PMPrinter printer;
+
+ if (PMSessionGetCurrentPrinter(session(), &printer) == noErr
+ && PMSessionCreatePageFormatList(session(), printer, &formats) == noErr) {
+ CFIndex total = CFArrayGetCount(formats);
+ PMPageFormat tmp;
+ PMRect paper;
+ for (CFIndex idx = 0; idx < total; ++idx) {
+ tmp = static_cast<PMPageFormat>(
+ const_cast<void *>(CFArrayGetValueAtIndex(formats, idx)));
+ PMGetUnadjustedPaperRect(tmp, &paper);
+ int wMM = int((paper.right - paper.left) / 72 * 25.4 + 0.5);
+ int hMM = int((paper.bottom - paper.top) / 72 * 25.4 + 0.5);
+ if (newSize.width() == wMM && newSize.height() == hMM) {
+ PMCopyPageFormat(tmp, format());
+ // reset the orientation and resolution as they are lost in the copy.
+ q->setProperty(QPrintEngine::PPK_Orientation, orient);
+ if (PMSessionValidatePageFormat(session(), format(), kPMDontWantBoolean) != noErr) {
+ // Don't know, warn for the moment.
+ qWarning("QMacPrintEngine, problem setting format and resolution for this page size");
+ }
+ break;
+ }
+ }
+ }
+}
+
+QPrinter::PaperSize QMacPrintEnginePrivate::paperSize() const
+{
+ if (hasCustomPaperSize)
+ return QPrinter::Custom;
+ PMRect paper;
+ PMGetUnadjustedPaperRect(format(), &paper);
+ QSizeF sizef((paper.right - paper.left) / 72.0 * 25.4, (paper.bottom - paper.top) / 72.0 * 25.4);
+ return QPlatformPrinterSupport::convertQSizeFToPaperSize(sizef);
+}
+
+QList<QVariant> QMacPrintEnginePrivate::supportedResolutions() const
+{
+ Q_ASSERT_X(printInfo, "QMacPrinterEngine::supportedResolutions",
+ "must have a valid printer session");
+ UInt32 resCount;
+ QList<QVariant> resolutions;
+ PMPrinter printer;
+ if (PMSessionGetCurrentPrinter(session(), &printer) == noErr) {
+ PMResolution res;
+ OSStatus status = PMPrinterGetPrinterResolutionCount(printer, &resCount);
+ if (status == kPMNotImplemented) {
+#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
+ // *Sigh* we have to use the non-indexed version.
+ if (PMPrinterGetPrinterResolution(printer, kPMMinSquareResolution, &res) == noErr)
+ resolutions.append(int(res.hRes));
+ if (PMPrinterGetPrinterResolution(printer, kPMMaxSquareResolution, &res) == noErr) {
+ QVariant var(int(res.hRes));
+ if (!resolutions.contains(var))
+ resolutions.append(var);
+ }
+ if (PMPrinterGetPrinterResolution(printer, kPMDefaultResolution, &res) == noErr) {
+ QVariant var(int(res.hRes));
+ if (!resolutions.contains(var))
+ resolutions.append(var);
+ }
+#endif
+ } else if (status == noErr) {
+ // According to the docs, index start at 1.
+ for (UInt32 i = 1; i <= resCount; ++i) {
+ if (PMPrinterGetIndexedPrinterResolution(printer, i, &res) == noErr)
+ resolutions.append(QVariant(int(res.hRes)));
+ }
+ } else {
+ qWarning("QMacPrintEngine::supportedResolutions: Unexpected error: %ld", long(status));
+ }
+ }
+ return resolutions;
+}
+
+QPrinter::PrinterState QMacPrintEngine::printerState() const
+{
+ return d_func()->state;
+}
+
+bool QMacPrintEngine::newPage()
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ OSStatus err = PMSessionEndPageNoDialog(d->session());
+ if (err != noErr) {
+ if (err == kPMCancel) {
+ // User canceled, we need to abort!
+ abort();
+ } else {
+ // Not sure what the problem is...
+ qWarning("QMacPrintEngine::newPage: Cannot end current page. %ld", long(err));
+ d->state = QPrinter::Error;
+ }
+ return false;
+ }
+ return d->newPage_helper();
+}
+
+bool QMacPrintEngine::abort()
+{
+ Q_D(QMacPrintEngine);
+ if (d->state != QPrinter::Active)
+ return false;
+ bool ret = end();
+ d->state = QPrinter::Aborted;
+ return ret;
+}
+
+static inline int qt_get_PDMWidth(PMPageFormat pformat, bool fullPage,
+ const PMResolution &resolution)
+{
+ int val = 0;
+ PMRect r;
+ qreal hRatio = resolution.hRes / 72;
+ if (fullPage) {
+ if (PMGetAdjustedPaperRect(pformat, &r) == noErr)
+ val = qRound((r.right - r.left) * hRatio);
+ } else {
+ if (PMGetAdjustedPageRect(pformat, &r) == noErr)
+ val = qRound((r.right - r.left) * hRatio);
+ }
+ return val;
+}
+
+static inline int qt_get_PDMHeight(PMPageFormat pformat, bool fullPage,
+ const PMResolution &resolution)
+{
+ int val = 0;
+ PMRect r;
+ qreal vRatio = resolution.vRes / 72;
+ if (fullPage) {
+ if (PMGetAdjustedPaperRect(pformat, &r) == noErr)
+ val = qRound((r.bottom - r.top) * vRatio);
+ } else {
+ if (PMGetAdjustedPageRect(pformat, &r) == noErr)
+ val = qRound((r.bottom - r.top) * vRatio);
+ }
+ return val;
+}
+
+
+int QMacPrintEngine::metric(QPaintDevice::PaintDeviceMetric m) const
+{
+ Q_D(const QMacPrintEngine);
+ int val = 1;
+ switch (m) {
+ case QPaintDevice::PdmWidth:
+ if (d->hasCustomPaperSize) {
+ val = qRound(d->customSize.width());
+ if (d->hasCustomPageMargins) {
+ val -= qRound(d->leftMargin + d->rightMargin);
+ } else {
+ QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList();
+ val -= qRound(margins.at(0).toDouble() + margins.at(2).toDouble());
+ }
+ } else {
+ val = qt_get_PDMWidth(d->format(), property(PPK_FullPage).toBool(), d->resolution);
+ }
+ break;
+ case QPaintDevice::PdmHeight:
+ if (d->hasCustomPaperSize) {
+ val = qRound(d->customSize.height());
+ if (d->hasCustomPageMargins) {
+ val -= qRound(d->topMargin + d->bottomMargin);
+ } else {
+ QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList();
+ val -= qRound(margins.at(1).toDouble() + margins.at(3).toDouble());
+ }
+ } else {
+ val = qt_get_PDMHeight(d->format(), property(PPK_FullPage).toBool(), d->resolution);
+ }
+ break;
+ case QPaintDevice::PdmWidthMM:
+ val = metric(QPaintDevice::PdmWidth);
+ val = int((val * 254 + 5 * d->resolution.hRes) / (10 * d->resolution.hRes));
+ break;
+ case QPaintDevice::PdmHeightMM:
+ val = metric(QPaintDevice::PdmHeight);
+ val = int((val * 254 + 5 * d->resolution.vRes) / (10 * d->resolution.vRes));
+ break;
+ case QPaintDevice::PdmPhysicalDpiX:
+ case QPaintDevice::PdmPhysicalDpiY: {
+ PMPrinter printer;
+ if (PMSessionGetCurrentPrinter(d->session(), &printer) == noErr) {
+ PMResolution resolution;
+ PMPrinterGetOutputResolution(printer, d->settings(), &resolution);
+ val = (int)resolution.vRes;
+ break;
+ }
+ //otherwise fall through
+ }
+ case QPaintDevice::PdmDpiY:
+ val = (int)d->resolution.vRes;
+ break;
+ case QPaintDevice::PdmDpiX:
+ val = (int)d->resolution.hRes;
+ break;
+ case QPaintDevice::PdmNumColors:
+ val = (1 << metric(QPaintDevice::PdmDepth));
+ break;
+ case QPaintDevice::PdmDepth:
+ val = 24;
+ break;
+ default:
+ val = 0;
+ qWarning("QPrinter::metric: Invalid metric command");
+ }
+ return val;
+}
+
+void QMacPrintEnginePrivate::initialize()
+{
+ Q_Q(QMacPrintEngine);
+
+ Q_ASSERT(!printInfo);
+
+ if (!paintEngine)
+ paintEngine = new QCoreGraphicsPaintEngine();
+
+ q->gccaps = paintEngine->gccaps;
+
+ fullPage = false;
+
+ QCocoaAutoReleasePool pool;
+ printInfo = [[NSPrintInfo alloc] initWithDictionary:[NSDictionary dictionary]];
+
+ PMPrinter printer;
+ if (printInfo && PMSessionGetCurrentPrinter(session(), &printer) == noErr) {
+ QList<QVariant> resolutions = supportedResolutions();
+ if (!resolutions.isEmpty() && mode != QPrinter::ScreenResolution) {
+ if (resolutions.count() > 1 && mode == QPrinter::HighResolution) {
+ int max = 0;
+ for (int i = 0; i < resolutions.count(); ++i) {
+ int value = resolutions.at(i).toInt();
+ if (value > max)
+ max = value;
+ }
+ resolution.hRes = resolution.vRes = max;
+ } else {
+ resolution.hRes = resolution.vRes = resolutions.at(0).toInt();
+ }
+ if (resolution.hRes == 0)
+ resolution.hRes = resolution.vRes = 600;
+ } else {
+ resolution.hRes = resolution.vRes = qt_defaultDpi();
+ }
+ }
+
+ QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant>::const_iterator propC;
+ for (propC = valueCache.constBegin(); propC != valueCache.constEnd(); propC++) {
+ q->setProperty(propC.key(), propC.value());
+ }
+}
+
+void QMacPrintEnginePrivate::releaseSession()
+{
+ PMSessionEndPageNoDialog(session());
+ PMSessionEndDocumentNoDialog(session());
+ [printInfo release];
+ printInfo = 0;
+}
+
+bool QMacPrintEnginePrivate::newPage_helper()
+{
+ Q_Q(QMacPrintEngine);
+ Q_ASSERT(state == QPrinter::Active);
+
+ if (PMSessionError(session()) != noErr) {
+ q->abort();
+ return false;
+ }
+
+ // pop the stack of saved graphic states, in case we get the same
+ // context back - either way, the stack count should be 0 when we
+ // get the new one
+ QCoreGraphicsPaintEngine *cgEngine = static_cast<QCoreGraphicsPaintEngine*>(paintEngine);
+ while (cgEngine->d_func()->stackCount > 0)
+ cgEngine->d_func()->restoreGraphicsState();
+
+ OSStatus status = PMSessionBeginPageNoDialog(session(), format(), 0);
+ if (status != noErr) {
+ state = QPrinter::Error;
+ return false;
+ }
+
+ QRect page = q->property(QPrintEngine::PPK_PageRect).toRect();
+ QRect paper = q->property(QPrintEngine::PPK_PaperRect).toRect();
+
+ CGContextRef cgContext;
+ OSStatus err = noErr;
+ err = PMSessionGetCGGraphicsContext(session(), &cgContext);
+ if (err != noErr) {
+ qWarning("QMacPrintEngine::newPage: Cannot retrieve CoreGraphics context: %ld", long(err));
+ state = QPrinter::Error;
+ return false;
+ }
+ cgEngine->d_func()->hd = cgContext;
+
+ // Set the resolution as a scaling ration of 72 (the default).
+ CGContextScaleCTM(cgContext, 72 / resolution.hRes, 72 / resolution.vRes);
+
+ CGContextScaleCTM(cgContext, 1, -1);
+ CGContextTranslateCTM(cgContext, 0, -paper.height());
+ if (!fullPage)
+ CGContextTranslateCTM(cgContext, page.x() - paper.x(), page.y() - paper.y());
+ cgEngine->d_func()->orig_xform = CGContextGetCTM(cgContext);
+ cgEngine->d_func()->setClip(0);
+ cgEngine->state->dirtyFlags = QPaintEngine::DirtyFlag(QPaintEngine::AllDirty
+ & ~(QPaintEngine::DirtyClipEnabled
+ | QPaintEngine::DirtyClipRegion
+ | QPaintEngine::DirtyClipPath));
+ if (cgEngine->painter()->hasClipping())
+ cgEngine->state->dirtyFlags |= QPaintEngine::DirtyClipEnabled;
+ cgEngine->syncState();
+ return true;
+}
+
+
+void QMacPrintEngine::updateState(const QPaintEngineState &state)
+{
+ d_func()->paintEngine->updateState(state);
+}
+
+void QMacPrintEngine::drawRects(const QRectF *r, int num)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawRects(r, num);
+}
+
+void QMacPrintEngine::drawPoints(const QPointF *points, int pointCount)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawPoints(points, pointCount);
+}
+
+void QMacPrintEngine::drawEllipse(const QRectF &r)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawEllipse(r);
+}
+
+void QMacPrintEngine::drawLines(const QLineF *lines, int lineCount)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawLines(lines, lineCount);
+}
+
+void QMacPrintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawPolygon(points, pointCount, mode);
+}
+
+void QMacPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawPixmap(r, pm, sr);
+}
+
+void QMacPrintEngine::drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawImage(r, pm, sr, flags);
+}
+
+void QMacPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawTextItem(p, ti);
+}
+
+void QMacPrintEngine::drawTiledPixmap(const QRectF &dr, const QPixmap &pixmap, const QPointF &sr)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawTiledPixmap(dr, pixmap, sr);
+}
+
+void QMacPrintEngine::drawPath(const QPainterPath &path)
+{
+ Q_D(QMacPrintEngine);
+ Q_ASSERT(d->state == QPrinter::Active);
+ d->paintEngine->drawPath(path);
+}
+
+
+void QMacPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value)
+{
+ Q_D(QMacPrintEngine);
+
+ d->valueCache.insert(key, value);
+ if (!d->printInfo)
+ return;
+
+ switch (key) {
+ case PPK_CollateCopies:
+ break;
+ case PPK_ColorMode:
+ break;
+ case PPK_Creator:
+ break;
+ case PPK_DocumentName:
+ break;
+ case PPK_PageOrder:
+ break;
+ case PPK_PaperSource:
+ break;
+ case PPK_SelectionOption:
+ break;
+ case PPK_Resolution: {
+ PMPrinter printer;
+ UInt32 count;
+ if (PMSessionGetCurrentPrinter(d->session(), &printer) != noErr)
+ break;
+ if (PMPrinterGetPrinterResolutionCount(printer, &count) != noErr)
+ break;
+ PMResolution resolution = { 0.0, 0.0 };
+ PMResolution bestResolution = { 0.0, 0.0 };
+ int dpi = value.toInt();
+ int bestDistance = INT_MAX;
+ for (UInt32 i = 1; i <= count; ++i) { // Yes, it starts at 1
+ if (PMPrinterGetIndexedPrinterResolution(printer, i, &resolution) == noErr) {
+ if (dpi == int(resolution.hRes)) {
+ bestResolution = resolution;
+ break;
+ } else {
+ int distance = qAbs(dpi - int(resolution.hRes));
+ if (distance < bestDistance) {
+ bestDistance = distance;
+ bestResolution = resolution;
+ }
+ }
+ }
+ }
+ PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
+ break;
+ }
+
+ case PPK_FullPage:
+ d->fullPage = value.toBool();
+ break;
+ case PPK_CopyCount: // fallthrough
+ case PPK_NumberOfCopies:
+ PMSetCopies(d->settings(), value.toInt(), false);
+ break;
+ case PPK_Orientation: {
+ if (d->state == QPrinter::Active) {
+ qWarning("QMacPrintEngine::setOrientation: Orientation cannot be changed during a print job, ignoring change");
+ } else {
+ QPrinter::Orientation newOrientation = QPrinter::Orientation(value.toInt());
+ if (d->hasCustomPaperSize && (d->orient != newOrientation))
+ d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
+ d->orient = newOrientation;
+ PMOrientation o = d->orient == QPrinter::Portrait ? kPMPortrait : kPMLandscape;
+ PMSetOrientation(d->format(), o, false);
+ PMSessionValidatePageFormat(d->session(), d->format(), kPMDontWantBoolean);
+ }
+ break; }
+ case PPK_OutputFileName:
+ d->outputFilename = value.toString();
+ break;
+ case PPK_PaperSize:
+ d->setPaperSize(QPrinter::PaperSize(value.toInt()));
+ break;
+ case PPK_PrinterName: {
+ bool printerNameSet = false;
+ OSStatus status = noErr;
+ QCFType<CFArrayRef> printerList;
+ status = PMServerCreatePrinterList(kPMServerLocal, &printerList);
+ if (status == noErr) {
+ CFIndex count = CFArrayGetCount(printerList);
+ for (CFIndex i=0; i<count; ++i) {
+ PMPrinter printer = static_cast<PMPrinter>(const_cast<void *>(CFArrayGetValueAtIndex(printerList, i)));
+ QString name = QCFString::toQString(PMPrinterGetName(printer));
+ if (name == value.toString()) {
+ status = PMSessionSetCurrentPMPrinter(d->session(), printer);
+ printerNameSet = true;
+ break;
+ }
+ }
+ }
+ if (status != noErr)
+ qWarning("QMacPrintEngine::setPrinterName: Error setting printer: %ld", long(status));
+ if (!printerNameSet) {
+ qWarning("QMacPrintEngine::setPrinterName: Failed to set printer named '%s'.", qPrintable(value.toString()));
+ d->releaseSession();
+ d->state = QPrinter::Idle;
+ }
+ break; }
+ case PPK_SuppressSystemPrintStatus:
+ break;
+ case PPK_CustomPaperSize:
+ {
+ PMOrientation orientation;
+ PMGetOrientation(d->format(), &orientation);
+ d->hasCustomPaperSize = true;
+ d->customSize = value.toSizeF();
+ if (orientation != kPMPortrait)
+ d->customSize = QSizeF(d->customSize.height(), d->customSize.width());
+ break;
+ }
+ case PPK_PageMargins:
+ {
+ QList<QVariant> margins(value.toList());
+ Q_ASSERT(margins.size() == 4);
+ d->leftMargin = margins.at(0).toDouble();
+ d->topMargin = margins.at(1).toDouble();
+ d->rightMargin = margins.at(2).toDouble();
+ d->bottomMargin = margins.at(3).toDouble();
+ d->hasCustomPageMargins = true;
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+QVariant QMacPrintEngine::property(PrintEnginePropertyKey key) const
+{
+ Q_D(const QMacPrintEngine);
+ QVariant ret;
+
+ if (!d->printInfo && d->valueCache.contains(key))
+ return *d->valueCache.find(key);
+
+ switch (key) {
+ case PPK_CollateCopies:
+ ret = false;
+ break;
+ case PPK_ColorMode:
+ ret = QPrinter::Color;
+ break;
+ case PPK_Creator:
+ break;
+ case PPK_DocumentName:
+ break;
+ case PPK_FullPage:
+ ret = d->fullPage;
+ break;
+ case PPK_NumberOfCopies:
+ ret = 1;
+ break;
+ case PPK_CopyCount: {
+ UInt32 copies = 1;
+ PMGetCopies(d->settings(), &copies);
+ ret = (uint) copies;
+ break;
+ }
+ case PPK_SupportsMultipleCopies:
+ ret = true;
+ break;
+ case PPK_Orientation:
+ PMOrientation orientation;
+ PMGetOrientation(d->format(), &orientation);
+ ret = orientation == kPMPortrait ? QPrinter::Portrait : QPrinter::Landscape;
+ break;
+ case PPK_OutputFileName:
+ ret = d->outputFilename;
+ break;
+ case PPK_PageOrder:
+ break;
+ case PPK_PaperSource:
+ break;
+ case PPK_PageRect: {
+ // PageRect is returned in device pixels
+ QRect r;
+ PMRect macrect, macpaper;
+ qreal hRatio = d->resolution.hRes / 72;
+ qreal vRatio = d->resolution.vRes / 72;
+ if (d->hasCustomPaperSize) {
+ r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio));
+ if (d->hasCustomPageMargins) {
+ r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio),
+ -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
+ } else {
+ QList<QVariant> margins = property(QPrintEngine::PPK_PageMargins).toList();
+ r.adjust(qRound(margins.at(0).toDouble() * hRatio),
+ qRound(margins.at(1).toDouble() * vRatio),
+ -qRound(margins.at(2).toDouble() * hRatio),
+ -qRound(margins.at(3).toDouble()) * vRatio);
+ }
+ } else if (PMGetAdjustedPageRect(d->format(), &macrect) == noErr
+ && PMGetAdjustedPaperRect(d->format(), &macpaper) == noErr)
+ {
+ if (d->fullPage || d->hasCustomPageMargins) {
+ r.setCoords(int(macpaper.left * hRatio), int(macpaper.top * vRatio),
+ int(macpaper.right * hRatio), int(macpaper.bottom * vRatio));
+ r.translate(-r.x(), -r.y());
+ if (d->hasCustomPageMargins) {
+ r.adjust(qRound(d->leftMargin * hRatio), qRound(d->topMargin * vRatio),
+ -qRound(d->rightMargin * hRatio), -qRound(d->bottomMargin * vRatio));
+ }
+ } else {
+ r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
+ int(macrect.right * hRatio), int(macrect.bottom * vRatio));
+ r.translate(int(-macpaper.left * hRatio), int(-macpaper.top * vRatio));
+ }
+ }
+ ret = r;
+ break; }
+ case PPK_PaperSize:
+ ret = d->paperSize();
+ break;
+ case PPK_PaperRect: {
+ QRect r;
+ PMRect macrect;
+ qreal hRatio = d->resolution.hRes / 72;
+ qreal vRatio = d->resolution.vRes / 72;
+ if (d->hasCustomPaperSize) {
+ r = QRect(0, 0, qRound(d->customSize.width() * hRatio), qRound(d->customSize.height() * vRatio));
+ } else if (PMGetAdjustedPaperRect(d->format(), &macrect) == noErr) {
+ r.setCoords(int(macrect.left * hRatio), int(macrect.top * vRatio),
+ int(macrect.right * hRatio), int(macrect.bottom * vRatio));
+ r.translate(-r.x(), -r.y());
+ }
+ ret = r;
+ break; }
+ case PPK_PrinterName: {
+ PMPrinter printer;
+ OSStatus status = PMSessionGetCurrentPrinter(d->session(), &printer);
+ if (status != noErr)
+ qWarning("QMacPrintEngine::printerName: Failed getting current PMPrinter: %ld", long(status));
+ if (printer)
+ ret = QCFString::toQString(PMPrinterGetName(printer));
+ break; }
+ case PPK_Resolution: {
+ ret = d->resolution.hRes;
+ break;
+ }
+ case PPK_SupportedResolutions:
+ ret = d->supportedResolutions();
+ break;
+ case PPK_CustomPaperSize:
+ ret = d->customSize;
+ break;
+ case PPK_PageMargins:
+ {
+ QList<QVariant> margins;
+ if (d->hasCustomPageMargins) {
+ margins << d->leftMargin << d->topMargin
+ << d->rightMargin << d->bottomMargin;
+ } else {
+ PMPaperMargins paperMargins;
+ PMPaper paper;
+ PMGetPageFormatPaper(d->format(), &paper);
+ PMPaperGetMargins(paper, &paperMargins);
+ margins << paperMargins.left << paperMargins.top
+ << paperMargins.right << paperMargins.bottom;
+ }
+ ret = margins;
+ break;
+ }
+ default:
+ break;
+ }
+ return ret;
+}
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
diff --git a/src/plugins/platforms/cocoa/qprintengine_mac_p.h b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
new file mode 100644
index 0000000000..2d37b43dfa
--- /dev/null
+++ b/src/plugins/platforms/cocoa/qprintengine_mac_p.h
@@ -0,0 +1,160 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPRINTENGINE_MAC_P_H
+#define QPRINTENGINE_MAC_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#ifndef QT_NO_PRINTER
+
+#include <QtPrintSupport/qprinter.h>
+#include <QtPrintSupport/qprintengine.h>
+#include <QtGui/private/qpainter_p.h>
+
+#include "qpaintengine_mac_p.h"
+
+#ifdef __OBJC__
+@class NSPrintInfo;
+#else
+typedef void NSPrintInfo;
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QPrinterPrivate;
+class QMacPrintEnginePrivate;
+class QMacPrintEngine : public QPaintEngine, public QPrintEngine
+{
+ Q_DECLARE_PRIVATE(QMacPrintEngine)
+public:
+ QMacPrintEngine(QPrinter::PrinterMode mode);
+
+ Qt::HANDLE handle() const;
+
+ bool begin(QPaintDevice *dev);
+ bool end();
+ virtual QPaintEngine::Type type() const { return QPaintEngine::MacPrinter; }
+
+ QPaintEngine *paintEngine() const;
+
+ void setProperty(PrintEnginePropertyKey key, const QVariant &value);
+ QVariant property(PrintEnginePropertyKey key) const;
+
+ QPrinter::PrinterState printerState() const;
+
+ bool newPage();
+ bool abort();
+ int metric(QPaintDevice::PaintDeviceMetric) const;
+
+ //forwarded functions
+
+ void updateState(const QPaintEngineState &state);
+
+ virtual void drawLines(const QLineF *lines, int lineCount);
+ virtual void drawRects(const QRectF *r, int num);
+ virtual void drawPoints(const QPointF *p, int pointCount);
+ virtual void drawEllipse(const QRectF &r);
+ virtual void drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode);
+ virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
+ virtual void drawImage(const QRectF &r, const QImage &pm, const QRectF &sr, Qt::ImageConversionFlags flags);
+ virtual void drawTextItem(const QPointF &p, const QTextItem &ti);
+ virtual void drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s);
+ virtual void drawPath(const QPainterPath &);
+
+private:
+ friend class QCocoaNativeInterface;
+};
+
+class QMacPrintEnginePrivate : public QPaintEnginePrivate
+{
+ Q_DECLARE_PUBLIC(QMacPrintEngine)
+public:
+ QPrinter::PrinterMode mode;
+ QPrinter::PrinterState state;
+ QPrinter::Orientation orient;
+ NSPrintInfo *printInfo;
+ PMResolution resolution;
+ QString outputFilename;
+ bool fullPage;
+ QPaintEngine *paintEngine;
+ bool hasCustomPaperSize;
+ QSizeF customSize;
+ bool hasCustomPageMargins;
+ qreal leftMargin;
+ qreal topMargin;
+ qreal rightMargin;
+ qreal bottomMargin;
+ QHash<QMacPrintEngine::PrintEnginePropertyKey, QVariant> valueCache;
+ QMacPrintEnginePrivate() : mode(QPrinter::ScreenResolution), state(QPrinter::Idle),
+ orient(QPrinter::Portrait), printInfo(0), paintEngine(0),
+ hasCustomPaperSize(false), hasCustomPageMargins(false) {}
+ ~QMacPrintEnginePrivate();
+ void initialize();
+ void releaseSession();
+ bool newPage_helper();
+ void setPaperSize(QPrinter::PaperSize ps);
+ QPrinter::PaperSize paperSize() const;
+ QList<QVariant> supportedResolutions() const;
+ inline bool isPrintSessionInitialized() const
+ {
+ return printInfo != 0;
+ }
+
+ PMPageFormat format() const { return static_cast<PMPageFormat>([printInfo PMPageFormat]); }
+ PMPrintSession session() const { return static_cast<PMPrintSession>([printInfo PMPrintSession]); }
+ PMPrintSettings settings() const { return static_cast<PMPrintSettings>([printInfo PMPrintSettings]); }
+};
+
+QT_END_NAMESPACE
+
+#endif // QT_NO_PRINTER
+
+#endif // QPRINTENGINE_WIN_P_H
diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h
index b75e6e2bcb..f881965b32 100644
--- a/src/plugins/platforms/cocoa/qt_mac_p.h
+++ b/src/plugins/platforms/cocoa/qt_mac_p.h
@@ -159,7 +159,7 @@ class QMacCGContext
{
CGContextRef context;
public:
- QMacCGContext(QPainter *p); //qpaintengine_mac.cpp
+ QMacCGContext(QPainter *p); //qpaintengine_mac.mm
inline QMacCGContext() { context = 0; }
inline QMacCGContext(const QPaintDevice *pdev) {
extern CGContextRef qt_mac_cg_context(const QPaintDevice *);
diff --git a/src/plugins/platforms/eglfs/eglfs.json b/src/plugins/platforms/eglfs/eglfs.json
new file mode 100644
index 0000000000..c1ad6ca028
--- /dev/null
+++ b/src/plugins/platforms/eglfs/eglfs.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "eglfs" ]
+}
diff --git a/src/plugins/platforms/eglfs/eglfs.pro b/src/plugins/platforms/eglfs/eglfs.pro
index 291e09d6ed..ed8503b53c 100644
--- a/src/plugins/platforms/eglfs/eglfs.pro
+++ b/src/plugins/platforms/eglfs/eglfs.pro
@@ -1,6 +1,5 @@
TARGET = qeglfs
-TEMPLATE = lib
-CONFIG += plugin
+load(qt_plugin)
QT += core-private gui-private platformsupport-private
@@ -29,3 +28,6 @@ CONFIG += qpa/genericunixfontdatabase
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
+
+OTHER_FILES += \
+ eglfs.json
diff --git a/src/plugins/platforms/eglfs/main.cpp b/src/plugins/platforms/eglfs/main.cpp
index e4167bf173..2ca2199619 100644
--- a/src/plugins/platforms/eglfs/main.cpp
+++ b/src/plugins/platforms/eglfs/main.cpp
@@ -46,6 +46,8 @@ QT_BEGIN_NAMESPACE
class QEglIntegrationPlugin : public QPlatformIntegrationPlugin
{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformIntegrationFactoryInterface" FILE "eglfs.json")
public:
QStringList keys() const;
QPlatformIntegration *create(const QString&, const QStringList&);
@@ -67,6 +69,6 @@ QPlatformIntegration* QEglIntegrationPlugin::create(const QString& system, const
return 0;
}
-Q_EXPORT_PLUGIN2(eglintegration, QEglIntegrationPlugin)
-
QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/platforms/qnx/qqnxwindow.h b/src/plugins/platforms/qnx/qqnxwindow.h
index 9507b08ade..9c03af7594 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.h
+++ b/src/plugins/platforms/qnx/qqnxwindow.h
@@ -60,7 +60,6 @@ QT_BEGIN_NAMESPACE
class QQnxGLContext;
class QQnxScreen;
-class QPlatformGLContext;
class QSurfaceFormat;
class QQnxWindow : public QPlatformWindow
diff --git a/src/plugins/platforms/uikit/README b/src/plugins/platforms/uikit/README
deleted file mode 100644
index f878cce50e..0000000000
--- a/src/plugins/platforms/uikit/README
+++ /dev/null
@@ -1,45 +0,0 @@
-This is a proof-of-concept implemenation of a UIKit based
-QPA plugin. Note that this is completely unsupported, and it is probable
-that many parts of QtCore and other Qt Modules don't work properly.
-
-1) Build Qt
-
-The example Xcode project in the examples subdirectory requires that you do shadow
-builds of Qt in qt-lighthouse-ios-simulator and qt-lighthouse-ios-device directories
-parallel to the sources. To build for simulator make sure that both the Simulator
-configuration *and* the simulator specific target are active. To build for device
-make sure that both the Device configuration *and* the device specific target are
-active.
-
-The setup is configured to use the iOS 4.2 SDKs, you might want to edit the mkspecs
-to fit your need.
-
-After configuring and building Qt you need to also build src/plugins/platforms/uikit.
-
-Simulator:
-----------
-configure -qpa -xplatform qws/macx-iphonesimulator-g++ -arch i386 -developer-build -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake docs -nomake examples -nomake translations
-
-Device:
--------
-configure -qpa -xplatform qws/macx-iphonedevice-g++ -arch armv7 -developer-build -release -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake docs -nomake examples -nomake translations
-
-2) XCode setup:
-- there are examples in the examples subdirectory of the platform plugin
-- to create something fresh do something like:
- - Xcode: Create a "View-based Appplication"
- - remove the nibs and view controller and app controller files
- - remove the reference to "Main nib file" from plist file
- - create a main.mm like in the examples
- - add the qmlapplicationviewer sources to your project (including the moc_*.h)
- (best to link, not copy), the code for this is from the Qt Creator
- mobile Qt Quick application template
- - Add the Qt .a libraries, uikit platform plugin and libz (v1.2.3) to Frameworks
- - add "$(SRCROOT)/../../../../qt-lighthouse-ios-device/include" (or -simulator)
- to the include search paths.
- - add "$(SRCROOT)/../qmltest" to the include search path if you didn't copy but
- linked to the qmlapplicationviewer
- - for device set the architecture to armv7 only
-
-3) Done: Build and Run.
-
diff --git a/src/plugins/platforms/uikit/examples/qmltest/main.mm b/src/plugins/platforms/uikit/examples/qmltest/main.mm
deleted file mode 100644
index 68eef2a353..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/main.mm
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <UIKit/UIKit.h>
-
-#include "qmlapplicationviewer/qmlapplicationviewer.h"
-
-#include <QtGui/QApplication>
-#include <QtCore/QtPlugin>
-#include <QtDeclarative/QDeclarativeEngine>
-
-Q_IMPORT_PLUGIN(UIKit)
-
-static QString qStringFromNSString(NSString *nsstring)
-{
- return QString::fromUtf8([nsstring UTF8String]);
-}
-
-static QString documentsDirectory()
-{
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- return qStringFromNSString(documentsDirectory);
-}
-
-int main(int argc, char *argv[]) {
-
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
-
- QApplication app(argc, argv);
- QmlApplicationViewer viewer;
- viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
- viewer.engine()->setOfflineStoragePath(documentsDirectory());
- NSString *resourcePath = [[NSBundle mainBundle] resourcePath];
- viewer.setMainQmlFile(qStringFromNSString([resourcePath stringByAppendingPathComponent:@"qml/main.qml"]));
- viewer.showMaximized();
- int retVal = app.exec();
- [pool release];
- return retVal;
-}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qml/main.qml b/src/plugins/platforms/uikit/examples/qmltest/qml/main.qml
deleted file mode 100644
index 07e8eb08a6..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/qml/main.qml
+++ /dev/null
@@ -1,112 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the examples of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
-**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * 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.
-** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
-** the names of its contributors may be used to endorse or promote
-** products derived from this software without specific prior written
-** permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
-** OWNER OR 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."
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-import QtQuick 1.0
-
-Rectangle {
- id: box
- width: 350; height: 250
-
- Rectangle {
- id: redSquare
- width: 80; height: 80
- anchors.top: parent.top; anchors.left: parent.left; anchors.margins: 10
- color: "red"
-
- Text { text: "Click"; font.pixelSize: 16; anchors.centerIn: parent }
-
- MouseArea {
- anchors.fill: parent
- hoverEnabled: true
- acceptedButtons: Qt.LeftButton | Qt.RightButton
-
- onEntered: info.text = 'Entered'
- onExited: info.text = 'Exited (pressed=' + pressed + ')'
-
- onPressed: {
- info.text = 'Pressed (button=' + (mouse.button == Qt.RightButton ? 'right' : 'left')
- + ' shift=' + (mouse.modifiers & Qt.ShiftModifier ? 'true' : 'false') + ')'
- var posInBox = redSquare.mapToItem(box, mouse.x, mouse.y)
- posInfo.text = + mouse.x + ',' + mouse.y + ' in square'
- + ' (' + posInBox.x + ',' + posInBox.y + ' in window)'
- }
-
- onReleased: {
- info.text = 'Released (isClick=' + mouse.isClick + ' wasHeld=' + mouse.wasHeld + ')'
- posInfo.text = ''
- }
-
- onPressAndHold: info.text = 'Press and hold'
- onClicked: info.text = 'Clicked (wasHeld=' + mouse.wasHeld + ')'
- onDoubleClicked: info.text = 'Double clicked'
- }
- }
-
- Rectangle {
- id: blueSquare
- width: 80; height: 80
- x: box.width - width - 10; y: 10 // making this item draggable, so don't use anchors
- color: "blue"
-
- Text { text: "Drag"; font.pixelSize: 16; color: "white"; anchors.centerIn: parent }
-
- MouseArea {
- anchors.fill: parent
- drag.target: blueSquare
- drag.axis: Drag.XandYAxis
- drag.minimumX: 0
- drag.maximumX: box.width - parent.width
- drag.minimumY: 0
- drag.maximumY: box.height - parent.width
- }
- }
-
- Text {
- id: info
- anchors.bottom: posInfo.top; anchors.horizontalCenter: parent.horizontalCenter; anchors.margins: 30
-
- onTextChanged: console.log(text)
- }
-
- Text {
- id: posInfo
- anchors.bottom: parent.bottom; anchors.horizontalCenter: parent.horizontalCenter; anchors.margins: 30
- }
-}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp
deleted file mode 100644
index 2b36a87272..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/moc_qmlapplicationviewer.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-/****************************************************************************
-** Meta object code from reading C++ file 'qmlapplicationviewer.h'
-**
-** Created: Fri Feb 18 17:53:42 2011
-** by: The Qt Meta Object Compiler version 62 (Qt 4.7.2)
-**
-** WARNING! All changes made in this file will be lost!
-*****************************************************************************/
-
-#include "qmlapplicationviewer.h"
-#if !defined(Q_MOC_OUTPUT_REVISION)
-#error "The header file 'qmlapplicationviewer.h' doesn't include <QObject>."
-#elif Q_MOC_OUTPUT_REVISION != 62
-#error "This file was generated using the moc from 4.7.2. It"
-#error "cannot be used with the include files from this version of Qt."
-#error "(The moc has changed too much.)"
-#endif
-
-QT_BEGIN_MOC_NAMESPACE
-static const uint qt_meta_data_QmlApplicationViewer[] = {
-
- // content:
- 5, // revision
- 0, // classname
- 0, 0, // classinfo
- 0, 0, // methods
- 0, 0, // properties
- 0, 0, // enums/sets
- 0, 0, // constructors
- 0, // flags
- 0, // signalCount
-
- 0 // eod
-};
-
-static const char qt_meta_stringdata_QmlApplicationViewer[] = {
- "QmlApplicationViewer\0"
-};
-
-const QMetaObject QmlApplicationViewer::staticMetaObject = {
- { &QDeclarativeView::staticMetaObject, qt_meta_stringdata_QmlApplicationViewer,
- qt_meta_data_QmlApplicationViewer, 0 }
-};
-
-#ifdef Q_NO_DATA_RELOCATION
-const QMetaObject &QmlApplicationViewer::getStaticMetaObject() { return staticMetaObject; }
-#endif //Q_NO_DATA_RELOCATION
-
-const QMetaObject *QmlApplicationViewer::metaObject() const
-{
- return QObject::d_ptr->metaObject ? QObject::d_ptr->metaObject : &staticMetaObject;
-}
-
-void *QmlApplicationViewer::qt_metacast(const char *_clname)
-{
- if (!_clname) return 0;
- if (!strcmp(_clname, qt_meta_stringdata_QmlApplicationViewer))
- return static_cast<void*>(const_cast< QmlApplicationViewer*>(this));
- return QDeclarativeView::qt_metacast(_clname);
-}
-
-int QmlApplicationViewer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
-{
- _id = QDeclarativeView::qt_metacall(_c, _id, _a);
- if (_id < 0)
- return _id;
- return _id;
-}
-QT_END_MOC_NAMESPACE
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp
deleted file mode 100644
index aba9366d47..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.cpp
+++ /dev/null
@@ -1,179 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// checksum 0x17fa version 0x3000a
-/*
- This file was generated by the Qt Quick Application wizard of Qt Creator.
- QmlApplicationViewer is a convenience class containing mobile device specific
- code such as screen orientation handling. Also QML paths and debugging are
- handled here.
- It is recommended not to modify this file, since newer versions of Qt Creator
- may offer an updated version of it.
-*/
-
-#include "qmlapplicationviewer.h"
-
-#include <QtCore/QCoreApplication>
-#include <QtCore/QDir>
-#include <QtCore/QFileInfo>
-#include <QtDeclarative/QDeclarativeComponent>
-#include <QtDeclarative/QDeclarativeEngine>
-#include <QtDeclarative/QDeclarativeContext>
-
-#if defined(QMLJSDEBUGGER)
-#include <qt_private/qdeclarativedebughelper_p.h>
-#endif
-
-#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
-#include <jsdebuggeragent.h>
-#endif
-#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
-#include <qdeclarativeviewobserver.h>
-#endif
-
-#if defined(QMLJSDEBUGGER)
-
-// Enable debugging before any QDeclarativeEngine is created
-struct QmlJsDebuggingEnabler
-{
- QmlJsDebuggingEnabler()
- {
- QDeclarativeDebugHelper::enableDebugging();
- }
-};
-
-// Execute code in constructor before first QDeclarativeEngine is instantiated
-static QmlJsDebuggingEnabler enableDebuggingHelper;
-
-#endif // QMLJSDEBUGGER
-
-class QmlApplicationViewerPrivate
-{
- QString mainQmlFile;
- friend class QmlApplicationViewer;
- static QString adjustPath(const QString &path);
-};
-
-QString QmlApplicationViewerPrivate::adjustPath(const QString &path)
-{
-#ifdef Q_OS_UNIX
-#ifdef Q_OS_MAC
- if (!QDir::isAbsolutePath(path))
- return QCoreApplication::applicationDirPath()
- + QLatin1String("/../Resources/") + path;
-#else
- const QString pathInShareDir = QCoreApplication::applicationDirPath()
- + QLatin1String("/../share/")
- + QFileInfo(QCoreApplication::applicationFilePath()).fileName()
- + QLatin1Char('/') + path;
- if (QFileInfo(pathInShareDir).exists())
- return pathInShareDir;
-#endif
-#endif
- return path;
-}
-
-QmlApplicationViewer::QmlApplicationViewer(QWidget *parent) :
- QDeclarativeView(parent),
- m_d(new QmlApplicationViewerPrivate)
-{
- connect(engine(), SIGNAL(quit()), SLOT(close()));
- setResizeMode(QDeclarativeView::SizeRootObjectToView);
-#if defined(QMLJSDEBUGGER) && !defined(NO_JSDEBUGGER)
- new QmlJSDebugger::JSDebuggerAgent(engine());
-#endif
-#if defined(QMLJSDEBUGGER) && !defined(NO_QMLOBSERVER)
- new QmlJSDebugger::QDeclarativeViewObserver(this, parent);
-#endif
-}
-
-QmlApplicationViewer::~QmlApplicationViewer()
-{
- delete m_d;
-}
-
-void QmlApplicationViewer::setMainQmlFile(const QString &file)
-{
- m_d->mainQmlFile = QmlApplicationViewerPrivate::adjustPath(file);
- setSource(QUrl::fromLocalFile(m_d->mainQmlFile));
-}
-
-void QmlApplicationViewer::addImportPath(const QString &path)
-{
- engine()->addImportPath(QmlApplicationViewerPrivate::adjustPath(path));
-}
-
-void QmlApplicationViewer::setOrientation(ScreenOrientation orientation)
-{
-// Qt::WidgetAttribute attribute;
-// switch (orientation) {
-//#if QT_VERSION < 0x040702
-// // Qt < 4.7.2 does not yet have the Qt::WA_*Orientation attributes
-// case ScreenOrientationLockPortrait:
-// attribute = static_cast<Qt::WidgetAttribute>(128);
-// break;
-// case ScreenOrientationLockLandscape:
-// attribute = static_cast<Qt::WidgetAttribute>(129);
-// break;
-// default:
-// case ScreenOrientationAuto:
-// attribute = static_cast<Qt::WidgetAttribute>(130);
-// break;
-//#else // QT_VERSION < 0x040702
-// case ScreenOrientationLockPortrait:
-// attribute = Qt::WA_LockPortraitOrientation;
-// break;
-// case ScreenOrientationLockLandscape:
-// attribute = Qt::WA_LockLandscapeOrientation;
-// break;
-// default:
-// case ScreenOrientationAuto:
-// attribute = Qt::WA_AutoOrientation;
-// break;
-//#endif // QT_VERSION < 0x040702
-// };
-// setAttribute(attribute, true);
-}
-
-void QmlApplicationViewer::showExpanded()
-{
- show();
-}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h b/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h
deleted file mode 100644
index e2ee5b5069..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/qmlapplicationviewer/qmlapplicationviewer.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-// checksum 0x5a59 version 0x3000a
-/*
- This file was generated by the Qt Quick Application wizard of Qt Creator.
- QmlApplicationViewer is a convenience class containing mobile device specific
- code such as screen orientation handling. Also QML paths and debugging are
- handled here.
- It is recommended not to modify this file, since newer versions of Qt Creator
- may offer an updated version of it.
-*/
-
-#ifndef QMLAPPLICATIONVIEWER_H
-#define QMLAPPLICATIONVIEWER_H
-
-#include <QtDeclarative/QDeclarativeView>
-
-class QmlApplicationViewer : public QDeclarativeView
-{
- Q_OBJECT
-
-public:
- enum ScreenOrientation {
- ScreenOrientationLockPortrait,
- ScreenOrientationLockLandscape,
- ScreenOrientationAuto
- };
-
- explicit QmlApplicationViewer(QWidget *parent = 0);
- virtual ~QmlApplicationViewer();
-
- void setMainQmlFile(const QString &file);
- void addImportPath(const QString &path);
- void setOrientation(ScreenOrientation orientation);
- void showExpanded();
-
-private:
- class QmlApplicationViewerPrivate *m_d;
-};
-
-#endif // QMLAPPLICATIONVIEWER_H
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist b/src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist
deleted file mode 100644
index 15665856b0..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/qmltest-Info.plist
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
- <key>CFBundleDevelopmentRegion</key>
- <string>English</string>
- <key>CFBundleDisplayName</key>
- <string>${PRODUCT_NAME}</string>
- <key>CFBundleExecutable</key>
- <string>${EXECUTABLE_NAME}</string>
- <key>CFBundleIconFile</key>
- <string></string>
- <key>CFBundleIdentifier</key>
- <string>com.yourcompany.${PRODUCT_NAME:rfc1034identifier}</string>
- <key>CFBundleInfoDictionaryVersion</key>
- <string>6.0</string>
- <key>CFBundleName</key>
- <string>${PRODUCT_NAME}</string>
- <key>CFBundlePackageType</key>
- <string>APPL</string>
- <key>CFBundleSignature</key>
- <string>????</string>
- <key>CFBundleVersion</key>
- <string>1.0</string>
- <key>LSRequiresIPhoneOS</key>
- <true/>
-</dict>
-</plist>
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj b/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj
deleted file mode 100755
index 10bb20fcb9..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/qmltest.xcodeproj/project.pbxproj
+++ /dev/null
@@ -1,491 +0,0 @@
-// !$*UTF8*$!
-{
- archiveVersion = 1;
- classes = {
- };
- objectVersion = 45;
- objects = {
-
-/* Begin PBXBuildFile section */
- 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
- 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
- 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
- D316594E1338B29E00760B02 /* libQtXml_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D31659431338B21000760B02 /* libQtXml_debug.a */; };
- D316594F1338B29E00760B02 /* libQtXmlPatterns_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */; };
- D35784241345D8C90046D202 /* libQtOpenGL_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784231345D8C90046D202 /* libQtOpenGL_debug.a */; };
- D35784261345D9940046D202 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784251345D9940046D202 /* OpenGLES.framework */; };
- D35784281345D9E00046D202 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784271345D9E00046D202 /* QuartzCore.framework */; };
- D3578436134A09990046D202 /* libQtOpenGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3578435134A09990046D202 /* libQtOpenGL.a */; };
- D3578439134A0AAE0046D202 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784251345D9940046D202 /* OpenGLES.framework */; };
- D357843A134A0AB10046D202 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D35784271345D9E00046D202 /* QuartzCore.framework */; };
- D3CAA7C813264AAD008BB877 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7C713264AAD008BB877 /* main.mm */; };
- D3CAA7E613264EA6008BB877 /* moc_qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */; };
- D3CAA7E713264EA6008BB877 /* qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */; };
- D3CAA7EC13264F52008BB877 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7C713264AAD008BB877 /* main.mm */; };
- D3CAA7ED13264F52008BB877 /* moc_qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */; };
- D3CAA7EE13264F52008BB877 /* qmlapplicationviewer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */; };
- D3CAA7F013264F52008BB877 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
- D3CAA7F113264F52008BB877 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
- D3CAA7F213264F52008BB877 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
- D3CAA7FA13264F8A008BB877 /* libz.1.2.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */; };
- D3CAA81113264FF0008BB877 /* libz.1.2.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */; };
- D3CAA81B13265056008BB877 /* libQtCore_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81613265056008BB877 /* libQtCore_debug.a */; };
- D3CAA81C13265056008BB877 /* libQtDeclarative_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81713265056008BB877 /* libQtDeclarative_debug.a */; };
- D3CAA81D13265056008BB877 /* libQtGui_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81813265056008BB877 /* libQtGui_debug.a */; };
- D3CAA81E13265056008BB877 /* libQtScript_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81913265056008BB877 /* libQtScript_debug.a */; };
- D3CAA81F13265056008BB877 /* libQtSql_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA81A13265056008BB877 /* libQtSql_debug.a */; };
- D3CAA8211326507D008BB877 /* libquikit_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA8201326507D008BB877 /* libquikit_debug.a */; };
- D3CAA82813265220008BB877 /* libQtNetwork_debug.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3CAA82713265220008BB877 /* libQtNetwork_debug.a */; };
- D3CAA88A132652E5008BB877 /* fonts in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA836132652E5008BB877 /* fonts */; };
- D3CAA88B132652E5008BB877 /* fonts in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA836132652E5008BB877 /* fonts */; };
- D3CAA89113265310008BB877 /* qml in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA88E13265310008BB877 /* qml */; };
- D3CAA89213265310008BB877 /* qml in Resources */ = {isa = PBXBuildFile; fileRef = D3CAA88E13265310008BB877 /* qml */; };
- D3D817B2132A2CFD00CDE422 /* libQtCore.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AA132A2CFD00CDE422 /* libQtCore.a */; };
- D3D817B3132A2CFD00CDE422 /* libQtDeclarative.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AB132A2CFD00CDE422 /* libQtDeclarative.a */; };
- D3D817B4132A2CFD00CDE422 /* libQtGui.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AC132A2CFD00CDE422 /* libQtGui.a */; };
- D3D817B5132A2CFD00CDE422 /* libQtNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AD132A2CFD00CDE422 /* libQtNetwork.a */; };
- D3D817B6132A2CFD00CDE422 /* libQtScript.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AE132A2CFD00CDE422 /* libQtScript.a */; };
- D3D817B7132A2CFD00CDE422 /* libQtSql.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817AF132A2CFD00CDE422 /* libQtSql.a */; };
- D3D817B8132A2CFD00CDE422 /* libQtXml.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817B0132A2CFD00CDE422 /* libQtXml.a */; };
- D3D817B9132A2CFD00CDE422 /* libQtXmlPatterns.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817B1132A2CFD00CDE422 /* libQtXmlPatterns.a */; };
- D3D817BB132A2D0E00CDE422 /* libquikit.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D3D817BA132A2D0E00CDE422 /* libquikit.a */; };
-/* End PBXBuildFile section */
-
-/* Begin PBXFileReference section */
- 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
- 1D6058910D05DD3D006BFB54 /* qmltest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = qmltest.app; sourceTree = BUILT_PRODUCTS_DIR; };
- 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
- 288765A40DF7441C002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
- 32CA4F630368D1EE00C91783 /* qmltest_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = qmltest_Prefix.pch; sourceTree = "<group>"; };
- 8D1107310486CEB800E47090 /* qmltest-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "qmltest-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = "<group>"; };
- D31659431338B21000760B02 /* libQtXml_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXml_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtXml_debug.a"; sourceTree = SOURCE_ROOT; };
- D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXmlPatterns_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtXmlPatterns_debug.a"; sourceTree = SOURCE_ROOT; };
- D35784231345D8C90046D202 /* libQtOpenGL_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtOpenGL_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtOpenGL_debug.a"; sourceTree = "<group>"; };
- D35784251345D9940046D202 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; };
- D35784271345D9E00046D202 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
- D3578435134A09990046D202 /* libQtOpenGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtOpenGL.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtOpenGL.a"; sourceTree = "<group>"; };
- D3CAA7C713264AAD008BB877 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = "<group>"; };
- D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = moc_qmlapplicationviewer.cpp; path = qmlapplicationviewer/moc_qmlapplicationviewer.cpp; sourceTree = "<group>"; };
- D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = qmlapplicationviewer.cpp; path = qmlapplicationviewer/qmlapplicationviewer.cpp; sourceTree = "<group>"; };
- D3CAA7E513264EA6008BB877 /* qmlapplicationviewer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = qmlapplicationviewer.h; path = qmlapplicationviewer/qmlapplicationviewer.h; sourceTree = "<group>"; };
- D3CAA7F613264F52008BB877 /* qmltest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = qmltest.app; sourceTree = BUILT_PRODUCTS_DIR; };
- D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.2.3.dylib; path = usr/lib/libz.1.2.3.dylib; sourceTree = SDKROOT; };
- D3CAA81613265056008BB877 /* libQtCore_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtCore_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtCore_debug.a"; sourceTree = SOURCE_ROOT; };
- D3CAA81713265056008BB877 /* libQtDeclarative_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtDeclarative_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtDeclarative_debug.a"; sourceTree = SOURCE_ROOT; };
- D3CAA81813265056008BB877 /* libQtGui_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtGui_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtGui_debug.a"; sourceTree = SOURCE_ROOT; };
- D3CAA81913265056008BB877 /* libQtScript_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtScript_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtScript_debug.a"; sourceTree = SOURCE_ROOT; };
- D3CAA81A13265056008BB877 /* libQtSql_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtSql_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtSql_debug.a"; sourceTree = SOURCE_ROOT; };
- D3CAA8201326507D008BB877 /* libquikit_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libquikit_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/plugins/platforms/libquikit_debug.a"; sourceTree = SOURCE_ROOT; };
- D3CAA82713265220008BB877 /* libQtNetwork_debug.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtNetwork_debug.a; path = "../../../../../../../qt-lighthouse-ios-simulator/lib/libQtNetwork_debug.a"; sourceTree = SOURCE_ROOT; };
- D3CAA836132652E5008BB877 /* fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; name = fonts; path = ../../../../../../lib/fonts; sourceTree = SOURCE_ROOT; };
- D3CAA88E13265310008BB877 /* qml */ = {isa = PBXFileReference; lastKnownFileType = folder; path = qml; sourceTree = SOURCE_ROOT; };
- D3D817AA132A2CFD00CDE422 /* libQtCore.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtCore.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtCore.a"; sourceTree = SOURCE_ROOT; };
- D3D817AB132A2CFD00CDE422 /* libQtDeclarative.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtDeclarative.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtDeclarative.a"; sourceTree = SOURCE_ROOT; };
- D3D817AC132A2CFD00CDE422 /* libQtGui.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtGui.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtGui.a"; sourceTree = SOURCE_ROOT; };
- D3D817AD132A2CFD00CDE422 /* libQtNetwork.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtNetwork.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtNetwork.a"; sourceTree = SOURCE_ROOT; };
- D3D817AE132A2CFD00CDE422 /* libQtScript.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtScript.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtScript.a"; sourceTree = SOURCE_ROOT; };
- D3D817AF132A2CFD00CDE422 /* libQtSql.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtSql.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtSql.a"; sourceTree = SOURCE_ROOT; };
- D3D817B0132A2CFD00CDE422 /* libQtXml.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXml.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtXml.a"; sourceTree = SOURCE_ROOT; };
- D3D817B1132A2CFD00CDE422 /* libQtXmlPatterns.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libQtXmlPatterns.a; path = "../../../../../../../qt-lighthouse-ios-device/lib/libQtXmlPatterns.a"; sourceTree = SOURCE_ROOT; };
- D3D817BA132A2D0E00CDE422 /* libquikit.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libquikit.a; path = "../../../../../../../qt-lighthouse-ios-device/plugins/platforms/libquikit.a"; sourceTree = SOURCE_ROOT; };
-/* End PBXFileReference section */
-
-/* Begin PBXFrameworksBuildPhase section */
- 1D60588F0D05DD3D006BFB54 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D35784281345D9E00046D202 /* QuartzCore.framework in Frameworks */,
- 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */,
- 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */,
- 288765A50DF7441C002DB57D /* CoreGraphics.framework in Frameworks */,
- D35784261345D9940046D202 /* OpenGLES.framework in Frameworks */,
- D3CAA7FA13264F8A008BB877 /* libz.1.2.3.dylib in Frameworks */,
- D3CAA81B13265056008BB877 /* libQtCore_debug.a in Frameworks */,
- D3CAA81C13265056008BB877 /* libQtDeclarative_debug.a in Frameworks */,
- D3CAA81D13265056008BB877 /* libQtGui_debug.a in Frameworks */,
- D3CAA81E13265056008BB877 /* libQtScript_debug.a in Frameworks */,
- D3CAA81F13265056008BB877 /* libQtSql_debug.a in Frameworks */,
- D3CAA8211326507D008BB877 /* libquikit_debug.a in Frameworks */,
- D3CAA82813265220008BB877 /* libQtNetwork_debug.a in Frameworks */,
- D316594E1338B29E00760B02 /* libQtXml_debug.a in Frameworks */,
- D316594F1338B29E00760B02 /* libQtXmlPatterns_debug.a in Frameworks */,
- D35784241345D8C90046D202 /* libQtOpenGL_debug.a in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- D3CAA7EF13264F52008BB877 /* Frameworks */ = {
- isa = PBXFrameworksBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D357843A134A0AB10046D202 /* QuartzCore.framework in Frameworks */,
- D3578439134A0AAE0046D202 /* OpenGLES.framework in Frameworks */,
- D3CAA7F013264F52008BB877 /* Foundation.framework in Frameworks */,
- D3CAA7F113264F52008BB877 /* UIKit.framework in Frameworks */,
- D3CAA7F213264F52008BB877 /* CoreGraphics.framework in Frameworks */,
- D3CAA81113264FF0008BB877 /* libz.1.2.3.dylib in Frameworks */,
- D3D817B2132A2CFD00CDE422 /* libQtCore.a in Frameworks */,
- D3D817B3132A2CFD00CDE422 /* libQtDeclarative.a in Frameworks */,
- D3D817B4132A2CFD00CDE422 /* libQtGui.a in Frameworks */,
- D3D817B5132A2CFD00CDE422 /* libQtNetwork.a in Frameworks */,
- D3D817B6132A2CFD00CDE422 /* libQtScript.a in Frameworks */,
- D3D817B7132A2CFD00CDE422 /* libQtSql.a in Frameworks */,
- D3D817B8132A2CFD00CDE422 /* libQtXml.a in Frameworks */,
- D3D817B9132A2CFD00CDE422 /* libQtXmlPatterns.a in Frameworks */,
- D3D817BB132A2D0E00CDE422 /* libquikit.a in Frameworks */,
- D3578436134A09990046D202 /* libQtOpenGL.a in Frameworks */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXFrameworksBuildPhase section */
-
-/* Begin PBXGroup section */
- 19C28FACFE9D520D11CA2CBB /* Products */ = {
- isa = PBXGroup;
- children = (
- 1D6058910D05DD3D006BFB54 /* qmltest.app */,
- D3CAA7F613264F52008BB877 /* qmltest.app */,
- );
- name = Products;
- sourceTree = "<group>";
- };
- 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
- isa = PBXGroup;
- children = (
- 29B97315FDCFA39411CA2CEA /* Other Sources */,
- 29B97317FDCFA39411CA2CEA /* Resources */,
- D3CAA7E213264E8C008BB877 /* QMLApplicationViewer */,
- 29B97323FDCFA39411CA2CEA /* Frameworks */,
- 19C28FACFE9D520D11CA2CBB /* Products */,
- );
- name = CustomTemplate;
- sourceTree = "<group>";
- };
- 29B97315FDCFA39411CA2CEA /* Other Sources */ = {
- isa = PBXGroup;
- children = (
- 32CA4F630368D1EE00C91783 /* qmltest_Prefix.pch */,
- D3CAA7C713264AAD008BB877 /* main.mm */,
- );
- name = "Other Sources";
- sourceTree = "<group>";
- };
- 29B97317FDCFA39411CA2CEA /* Resources */ = {
- isa = PBXGroup;
- children = (
- D3CAA88E13265310008BB877 /* qml */,
- D3CAA836132652E5008BB877 /* fonts */,
- 8D1107310486CEB800E47090 /* qmltest-Info.plist */,
- );
- name = Resources;
- sourceTree = "<group>";
- };
- 29B97323FDCFA39411CA2CEA /* Frameworks */ = {
- isa = PBXGroup;
- children = (
- D3CAA81513265035008BB877 /* Simulator */,
- D3CAA8141326500A008BB877 /* Device */,
- 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */,
- 1D30AB110D05D00D00671497 /* Foundation.framework */,
- 288765A40DF7441C002DB57D /* CoreGraphics.framework */,
- D35784251345D9940046D202 /* OpenGLES.framework */,
- D35784271345D9E00046D202 /* QuartzCore.framework */,
- D3CAA7F913264F8A008BB877 /* libz.1.2.3.dylib */,
- );
- name = Frameworks;
- sourceTree = "<group>";
- };
- D3CAA7E213264E8C008BB877 /* QMLApplicationViewer */ = {
- isa = PBXGroup;
- children = (
- D3CAA7E313264EA6008BB877 /* moc_qmlapplicationviewer.cpp */,
- D3CAA7E413264EA6008BB877 /* qmlapplicationviewer.cpp */,
- D3CAA7E513264EA6008BB877 /* qmlapplicationviewer.h */,
- );
- name = QMLApplicationViewer;
- sourceTree = "<group>";
- };
- D3CAA8141326500A008BB877 /* Device */ = {
- isa = PBXGroup;
- children = (
- D3D817BA132A2D0E00CDE422 /* libquikit.a */,
- D3D817AA132A2CFD00CDE422 /* libQtCore.a */,
- D3D817AB132A2CFD00CDE422 /* libQtDeclarative.a */,
- D3D817AC132A2CFD00CDE422 /* libQtGui.a */,
- D3D817AD132A2CFD00CDE422 /* libQtNetwork.a */,
- D3578435134A09990046D202 /* libQtOpenGL.a */,
- D3D817AE132A2CFD00CDE422 /* libQtScript.a */,
- D3D817AF132A2CFD00CDE422 /* libQtSql.a */,
- D3D817B0132A2CFD00CDE422 /* libQtXml.a */,
- D3D817B1132A2CFD00CDE422 /* libQtXmlPatterns.a */,
- );
- name = Device;
- sourceTree = "<group>";
- };
- D3CAA81513265035008BB877 /* Simulator */ = {
- isa = PBXGroup;
- children = (
- D3CAA8201326507D008BB877 /* libquikit_debug.a */,
- D3CAA81613265056008BB877 /* libQtCore_debug.a */,
- D3CAA81713265056008BB877 /* libQtDeclarative_debug.a */,
- D3CAA81813265056008BB877 /* libQtGui_debug.a */,
- D3CAA82713265220008BB877 /* libQtNetwork_debug.a */,
- D35784231345D8C90046D202 /* libQtOpenGL_debug.a */,
- D3CAA81913265056008BB877 /* libQtScript_debug.a */,
- D3CAA81A13265056008BB877 /* libQtSql_debug.a */,
- D31659431338B21000760B02 /* libQtXml_debug.a */,
- D31659441338B21000760B02 /* libQtXmlPatterns_debug.a */,
- );
- name = Simulator;
- sourceTree = "<group>";
- };
-/* End PBXGroup section */
-
-/* Begin PBXNativeTarget section */
- 1D6058900D05DD3D006BFB54 /* qmltest simulator */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "qmltest simulator" */;
- buildPhases = (
- 1D60588D0D05DD3D006BFB54 /* Resources */,
- 1D60588E0D05DD3D006BFB54 /* Sources */,
- 1D60588F0D05DD3D006BFB54 /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "qmltest simulator";
- productName = qmltest;
- productReference = 1D6058910D05DD3D006BFB54 /* qmltest.app */;
- productType = "com.apple.product-type.application";
- };
- D3CAA7E813264F52008BB877 /* qmltest device */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = D3CAA7F313264F52008BB877 /* Build configuration list for PBXNativeTarget "qmltest device" */;
- buildPhases = (
- D3CAA7E913264F52008BB877 /* Resources */,
- D3CAA7EB13264F52008BB877 /* Sources */,
- D3CAA7EF13264F52008BB877 /* Frameworks */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "qmltest device";
- productName = qmltest;
- productReference = D3CAA7F613264F52008BB877 /* qmltest.app */;
- productType = "com.apple.product-type.application";
- };
-/* End PBXNativeTarget section */
-
-/* Begin PBXProject section */
- 29B97313FDCFA39411CA2CEA /* Project object */ = {
- isa = PBXProject;
- buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "qmltest" */;
- compatibilityVersion = "Xcode 3.1";
- developmentRegion = English;
- hasScannedForEncodings = 1;
- knownRegions = (
- English,
- Japanese,
- French,
- German,
- );
- mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */;
- projectDirPath = "";
- projectRoot = "";
- targets = (
- 1D6058900D05DD3D006BFB54 /* qmltest simulator */,
- D3CAA7E813264F52008BB877 /* qmltest device */,
- );
- };
-/* End PBXProject section */
-
-/* Begin PBXResourcesBuildPhase section */
- 1D60588D0D05DD3D006BFB54 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D3CAA88A132652E5008BB877 /* fonts in Resources */,
- D3CAA89113265310008BB877 /* qml in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- D3CAA7E913264F52008BB877 /* Resources */ = {
- isa = PBXResourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D3CAA88B132652E5008BB877 /* fonts in Resources */,
- D3CAA89213265310008BB877 /* qml in Resources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXResourcesBuildPhase section */
-
-/* Begin PBXSourcesBuildPhase section */
- 1D60588E0D05DD3D006BFB54 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D3CAA7C813264AAD008BB877 /* main.mm in Sources */,
- D3CAA7E613264EA6008BB877 /* moc_qmlapplicationviewer.cpp in Sources */,
- D3CAA7E713264EA6008BB877 /* qmlapplicationviewer.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
- D3CAA7EB13264F52008BB877 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- D3CAA7EC13264F52008BB877 /* main.mm in Sources */,
- D3CAA7ED13264F52008BB877 /* moc_qmlapplicationviewer.cpp in Sources */,
- D3CAA7EE13264F52008BB877 /* qmlapplicationviewer.cpp in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXSourcesBuildPhase section */
-
-/* Begin XCBuildConfiguration section */
- 1D6058940D05DD3E006BFB54 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- COPY_PHASE_STRIP = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = qmltest_Prefix.pch;
- HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/include\"/**";
- INFOPLIST_FILE = "qmltest-Info.plist";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/lib\"",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/plugins/platforms\"",
- );
- PRODUCT_NAME = qmltest;
- };
- name = Debug;
- };
- 1D6058950D05DD3E006BFB54 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- COPY_PHASE_STRIP = YES;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = qmltest_Prefix.pch;
- HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/include\"/**";
- INFOPLIST_FILE = "qmltest-Info.plist";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/lib\"",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-simulator/plugins/platforms\"",
- );
- PRODUCT_NAME = qmltest;
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
- C01FCF4F08A954540054247B /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- PREBINDING = NO;
- SDKROOT = iphoneos;
- };
- name = Debug;
- };
- C01FCF5008A954540054247B /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
- "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- GCC_C_LANGUAGE_STANDARD = c99;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
- PREBINDING = NO;
- SDKROOT = iphoneos;
- };
- name = Release;
- };
- D3CAA7F413264F52008BB877 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- COPY_PHASE_STRIP = NO;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = qmltest_Prefix.pch;
- HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/include\"/**";
- INFOPLIST_FILE = "qmltest-Info.plist";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/lib\"",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/plugins/platforms\"",
- );
- PRODUCT_NAME = qmltest;
- };
- name = Debug;
- };
- D3CAA7F513264F52008BB877 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)";
- COPY_PHASE_STRIP = YES;
- GCC_PRECOMPILE_PREFIX_HEADER = YES;
- GCC_PREFIX_HEADER = qmltest_Prefix.pch;
- HEADER_SEARCH_PATHS = "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/include\"/**";
- INFOPLIST_FILE = "qmltest-Info.plist";
- LIBRARY_SEARCH_PATHS = (
- "$(inherited)",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/lib\"",
- "\"$(SRCROOT)/../../../../../../../qt-lighthouse-ios-device/plugins/platforms\"",
- );
- PRODUCT_NAME = qmltest;
- VALIDATE_PRODUCT = YES;
- };
- name = Release;
- };
-/* End XCBuildConfiguration section */
-
-/* Begin XCConfigurationList section */
- 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "qmltest simulator" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- 1D6058940D05DD3E006BFB54 /* Debug */,
- 1D6058950D05DD3E006BFB54 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- C01FCF4E08A954540054247B /* Build configuration list for PBXProject "qmltest" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- C01FCF4F08A954540054247B /* Debug */,
- C01FCF5008A954540054247B /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
- D3CAA7F313264F52008BB877 /* Build configuration list for PBXNativeTarget "qmltest device" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- D3CAA7F413264F52008BB877 /* Debug */,
- D3CAA7F513264F52008BB877 /* Release */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
-/* End XCConfigurationList section */
- };
- rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
-}
diff --git a/src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch b/src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch
deleted file mode 100644
index c06715c661..0000000000
--- a/src/plugins/platforms/uikit/examples/qmltest/qmltest_Prefix.pch
+++ /dev/null
@@ -1,8 +0,0 @@
-//
-// Prefix header for all source files of the 'qmltest' target in the 'qmltest' project
-//
-
-#ifdef __OBJC__
- #import <Foundation/Foundation.h>
- #import <UIKit/UIKit.h>
-#endif
diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm
deleted file mode 100644
index 43df46705d..0000000000
--- a/src/plugins/platforms/uikit/quikiteventloop.mm
+++ /dev/null
@@ -1,174 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "quikiteventloop.h"
-#include "quikitwindow.h"
-#include "quikitwindowsurface.h"
-
-#include <UIKit/UIKit.h>
-
-#include <QtGui/QApplication>
-#include <QtGui/QWidget>
-#include <QtDebug>
-
-@interface QUIKitAppDelegate : NSObject <UIApplicationDelegate> {
-}
-@end
-
-@interface EventLoopHelper : NSObject {
- QUIKitEventLoop *mIntegration;
-}
-
-- (id)initWithEventLoopIntegration:(QUIKitEventLoop *)integration;
-
-- (void)processEvents;
-- (void)processEventsAndSchedule;
-
-@end
-
-@implementation QUIKitAppDelegate
-
-- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
-{
- Q_UNUSED(launchOptions)
- Q_UNUSED(application)
- foreach (QWidget *widget, qApp->topLevelWidgets()) {
- QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
- platformWindow->ensureNativeWindow();
- }
- return YES;
-}
-
-- (void)applicationWillTerminate:(UIApplication *)application
-{
- Q_UNUSED(application)
- // TODO this isn't called for some reason
- qDebug() << "quit";
- qApp->quit();
-}
-
-@end
-
-@implementation EventLoopHelper
-
-- (id)initWithEventLoopIntegration:(QUIKitEventLoop *)integration
-{
- if ((self = [self init])) {
- mIntegration = integration;
- }
- return self;
-}
-
-- (void)processEvents
-{
- QPlatformEventLoopIntegration::processEvents();
-}
-
-- (void)processEventsAndSchedule
-{
- QPlatformEventLoopIntegration::processEvents();
- qint64 nextTime = mIntegration->nextTimerEvent();
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- NSDate *nextDate = [[NSDate date] dateByAddingTimeInterval:((double)nextTime/1000)];
- [mIntegration->mTimer setFireDate:nextDate];
- [pool release];
-}
-
-@end
-
-QT_BEGIN_NAMESPACE
-
-QUIKitEventLoop::QUIKitEventLoop()
-{
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- mInputHandler = new QUIKitSoftwareInputHandler;
- mHelper = [[EventLoopHelper alloc] initWithEventLoopIntegration:this];
- mTimer = [[NSTimer timerWithTimeInterval:0.030 target:mHelper selector:@selector(processEventsAndSchedule) userInfo:nil repeats:YES] retain];
- [pool release];
-}
-
-QUIKitEventLoop::~QUIKitEventLoop()
-{
- [mTimer release];
- [mHelper release];
- delete mInputHandler;
-}
-
-void QUIKitEventLoop::startEventLoop()
-{
- qApp->installEventFilter(mInputHandler);
- NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
- [[NSRunLoop currentRunLoop] addTimer:[mTimer autorelease] forMode:NSDefaultRunLoopMode];
- UIApplicationMain(qApp->argc(), qApp->argv(), nil, @"QUIKitAppDelegate");
- [pool release];
-}
-
-void QUIKitEventLoop::quitEventLoop()
-{
-
-}
-
-void QUIKitEventLoop::qtNeedsToProcessEvents()
-{
- [mHelper performSelectorOnMainThread:@selector(processEvents) withObject:nil waitUntilDone:NO];
-}
-
-bool QUIKitSoftwareInputHandler::eventFilter(QObject *obj, QEvent *event)
-{
- if (event->type() == QEvent::RequestSoftwareInputPanel) {
- QWidget *widget = qobject_cast<QWidget *>(obj);
- if (widget) {
- QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
- [platformWindow->nativeView() becomeFirstResponder];
- return true;
- }
- } else if (event->type() == QEvent::CloseSoftwareInputPanel) {
- QWidget *widget = qobject_cast<QWidget *>(obj);
- if (widget) {
- QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow());
- [platformWindow->nativeView() resignFirstResponder];
- return true;
- }
- }
- return false;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm
deleted file mode 100644
index 0c8579fc0f..0000000000
--- a/src/plugins/platforms/uikit/quikitintegration.mm
+++ /dev/null
@@ -1,104 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "quikitintegration.h"
-#include "quikitwindow.h"
-#include "quikitwindowsurface.h"
-#include "quikitscreen.h"
-#include "quikiteventloop.h"
-
-#include <QtGui/QApplication>
-
-#include <private/qpixmap_raster_p.h>
-
-#include <UIKit/UIKit.h>
-
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-QUIKitIntegration::QUIKitIntegration()
-{
- mScreens << new QUIKitScreen(0);
-}
-
-QUIKitIntegration::~QUIKitIntegration()
-{
-}
-
-QPlatformPixmap *QUIKitIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
-{
- return new QRasterPlatformPixmap(type);
-}
-
-QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const
-{
- Q_UNUSED(winId);
- return new QUIKitWindow(widget);
-}
-
-QList<QPlatformScreen *> QUIKitIntegration::screens() const
-{
- return mScreens;
-}
-
-QWindowSurface *QUIKitIntegration::createWindowSurface(QWidget *widget, WId winId) const
-{
- Q_UNUSED(winId);
- return new QUIKitWindowSurface(widget);
-}
-
-QPlatformEventLoopIntegration *QUIKitIntegration::createEventLoopIntegration() const
-{
- return new QUIKitEventLoop();
-}
-
-QPlatformFontDatabase * QUIKitIntegration::fontDatabase() const
-{
- static bool initialized = false;
- if (!initialized) {
- initialized = true;
- setenv("QT_QPA_FONTDIR",[[[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"fonts"] UTF8String],1);
- }
- return QPlatformIntegration::fontDatabase();
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm
deleted file mode 100644
index 9569f95052..0000000000
--- a/src/plugins/platforms/uikit/quikitscreen.mm
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "quikitscreen.h"
-
-#include <QtGui/QApplication>
-
-#include <QtDebug>
-
-QT_BEGIN_NAMESPACE
-
-QUIKitScreen::QUIKitScreen(int screenIndex)
- : QPlatformScreen(),
- m_index(screenIndex)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex];
- CGRect bounds = [screen bounds];
- m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height);
-
- m_format = QImage::Format_ARGB32;
-
- m_depth = 24;
-
- const qreal inch = 25.4;
- qreal dpi = 160.;
- int dragDistance = 12;
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
- dpi = 132.;
- dragDistance = 10;
- }
- m_physicalSize = QSizeF(bounds.size.width, bounds.size.height) * inch / dpi;
- qApp->setStartDragDistance(dragDistance);
- [pool release];
-}
-
-QUIKitScreen::~QUIKitScreen()
-{
-}
-
-UIScreen *QUIKitScreen::uiScreen() const
-{
- return [[UIScreen screens] objectAtIndex:m_index];
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h
deleted file mode 100644
index 7fe599f0cd..0000000000
--- a/src/plugins/platforms/uikit/quikitwindow.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QUIKITWINDOW_H
-#define QUIKITWINDOW_H
-
-#include <QPlatformWindow>
-
-#import <UIKit/UIKit.h>
-#import <OpenGLES/ES1/gl.h>
-#import <OpenGLES/ES1/glext.h>
-#import <OpenGLES/ES2/gl.h>
-#import <OpenGLES/ES2/glext.h>
-#import <OpenGLES/EAGL.h>
-
-@interface EAGLView : UIView <UIKeyInput>
-{
- QPlatformWindow *mWindow;
- EAGLContext *mContext;
-
- GLint mFramebufferWidth;
- GLint mFramebufferHeight;
-
- GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer;
-
- id delegate;
- // ------- Text Input ----------
- UITextAutocapitalizationType autocapitalizationType;
- UITextAutocorrectionType autocorrectionType;
- BOOL enablesReturnKeyAutomatically;
- UIKeyboardAppearance keyboardAppearance;
- UIKeyboardType keyboardType;
- UIReturnKeyType returnKeyType;
- BOOL secureTextEntry;
-}
-
-- (void)setContext:(EAGLContext *)newContext;
-- (void)presentFramebuffer;
-- (void)deleteFramebuffer;
-- (void)createFramebuffer;
-- (void)makeCurrent;
-- (void)setWindow:(QPlatformWindow *)window;
-- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons;
-
-@property (readonly,getter=fbo) GLint fbo;
-@property (nonatomic, assign) id delegate;
-
-// ------- Text Input ----------
-
-@property(nonatomic) UITextAutocapitalizationType autocapitalizationType;
-@property(nonatomic) UITextAutocorrectionType autocorrectionType;
-@property(nonatomic) BOOL enablesReturnKeyAutomatically;
-@property(nonatomic) UIKeyboardAppearance keyboardAppearance;
-@property(nonatomic) UIKeyboardType keyboardType;
-@property(nonatomic) UIReturnKeyType returnKeyType;
-@property(nonatomic, getter=isSecureTextEntry) BOOL secureTextEntry;
-
-@end
-
-@protocol EAGLViewDelegate
-- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer;
-@end
-
-class EAGLPlatformContext;
-
-QT_BEGIN_NAMESPACE
-
-class QUIKitScreen;
-
-class QUIKitWindow : public QPlatformWindow
-{
-public:
- explicit QUIKitWindow(QWidget *tlw);
- ~QUIKitWindow();
-
- UIWindow *nativeWindow() const { return mWindow; }
- EAGLView *nativeView() const { return mView; }
- void setGeometry(const QRect &rect);
-
- UIWindow *ensureNativeWindow();
-
- QPlatformOpenGLContext *glContext() const;
-
-private:
- QUIKitScreen *mScreen;
- UIWindow *mWindow;
- EAGLView *mView;
- mutable EAGLPlatformContext *mContext;
-};
-
-QT_END_NAMESPACE
-
-#endif // QUIKITWINDOW_H
diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm
deleted file mode 100644
index fb6711009a..0000000000
--- a/src/plugins/platforms/uikit/quikitwindow.mm
+++ /dev/null
@@ -1,392 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#import <QuartzCore/CAEAGLLayer.h>
-
-#include "quikitwindow.h"
-
-#include "quikitscreen.h"
-
-#include <QtDebug>
-#include <QtGui/QApplication>
-#include <QtGui/QKeyEvent>
-#include <QtGui/QPlatformOpenGLContext>
-#include <QtGui/QWindowSystemInterface>
-
-#include <QtDebug>
-
-class EAGLPlatformContext : public QPlatformOpenGLContext
-{
-public:
- EAGLPlatformContext(EAGLView *view)
- : mView(view)
- {
- mFormat.setWindowApi(QPlatformWindowFormat::OpenGL);
- mFormat.setDepthBufferSize(24);
- mFormat.setAccumBufferSize(0);
- mFormat.setRedBufferSize(8);
- mFormat.setGreenBufferSize(8);
- mFormat.setBlueBufferSize(8);
- mFormat.setAlphaBufferSize(8);
- mFormat.setStencilBufferSize(8);
- mFormat.setSampleBuffers(false);
- mFormat.setSamples(1);
-// mFormat.setSwapInterval(?)
- mFormat.setDoubleBuffer(true);
- mFormat.setDepth(true);
- mFormat.setRgba(true);
- mFormat.setAlpha(true);
- mFormat.setAccum(false);
- mFormat.setStencil(true);
- mFormat.setStereo(false);
- mFormat.setDirectRendering(false);
-
-#if defined(QT_OPENGL_ES_2)
- EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
-#else
- EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
-#endif
- [mView setContext:aContext];
- }
-
- ~EAGLPlatformContext() { }
-
- void makeCurrent()
- {
- QPlatformOpenGLContext::makeCurrent();
- [mView makeCurrent];
- }
-
- void doneCurrent()
- {
- QPlatformOpenGLContext::doneCurrent();
- }
-
- void swapBuffers()
- {
- [mView presentFramebuffer];
- }
-
- void* getProcAddress(const QString& ) { return 0; }
-
- QPlatformWindowFormat platformWindowFormat() const
- {
- return mFormat;
- }
-
-private:
- EAGLView *mView;
-
- QPlatformWindowFormat mFormat;
-};
-
-@implementation EAGLView
-
-@synthesize delegate;
-
-+ (Class)layerClass
-{
- return [CAEAGLLayer class];
-}
-
-- (id)initWithFrame:(CGRect)frame
-{
- if ((self = [super initWithFrame:frame])) {
- CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
- eaglLayer.opaque = TRUE;
- eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
- kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
- nil];
- autocapitalizationType = UITextAutocapitalizationTypeNone;
- autocorrectionType = UITextAutocorrectionTypeNo;
- enablesReturnKeyAutomatically = NO;
- keyboardAppearance = UIKeyboardAppearanceDefault;
- keyboardType = UIKeyboardTypeDefault;
- returnKeyType = UIReturnKeyDone;
- secureTextEntry = NO;
- }
- return self;
-}
-
-- (void)setContext:(EAGLContext *)newContext
-{
- if (mContext != newContext)
- {
- [self deleteFramebuffer];
- [mContext release];
- mContext = [newContext retain];
- [EAGLContext setCurrentContext:nil];
- }
-}
-
-- (void)presentFramebuffer
-{
- if (mContext) {
- [EAGLContext setCurrentContext:mContext];
- glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
- [mContext presentRenderbuffer:GL_RENDERBUFFER];
- }
-}
-
-- (void)deleteFramebuffer
-{
- if (mContext)
- {
- [EAGLContext setCurrentContext:mContext];
- if (mFramebuffer) {
- glDeleteFramebuffers(1, &mFramebuffer);
- mFramebuffer = 0;
- }
- if (mColorRenderbuffer) {
- glDeleteRenderbuffers(1, &mColorRenderbuffer);
- mColorRenderbuffer = 0;
- }
- if (mDepthRenderbuffer) {
- glDeleteRenderbuffers(1, &mDepthRenderbuffer);
- mDepthRenderbuffer = 0;
- }
- }
-}
-
-- (void)createFramebuffer
-{
- if (mContext && !mFramebuffer)
- {
- [EAGLContext setCurrentContext:mContext];
- glGenFramebuffers(1, &mFramebuffer);
- glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
-
- glGenRenderbuffers(1, &mColorRenderbuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer);
- [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer];
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth);
- glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer);
-
- glGenRenderbuffers(1, &mDepthRenderbuffer);
- glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer);
-
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
- if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) {
- [delegate eaglView:self usesFramebuffer:mFramebuffer];
- }
- }
-}
-
-- (void)makeCurrent
-{
- if (mContext)
- {
- [EAGLContext setCurrentContext:mContext];
- if (!mFramebuffer)
- [self createFramebuffer];
- glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
- glViewport(0, 0, mFramebufferWidth, mFramebufferHeight);
- }
-}
-
-- (GLint)fbo
-{
- return mFramebuffer;
-}
-
-- (void)setWindow:(QPlatformWindow *)window
-{
- mWindow = window;
-}
-
-- (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons
-{
- UITouch *touch = [touches anyObject];
- CGPoint locationInView = [touch locationInView:self];
- QPoint p(locationInView.x, locationInView.y);
- // TODO handle global touch point? for status bar?
- QWindowSystemInterface::handleMouseEvent(mWindow->widget(), (ulong)(event.timestamp*1000),
- p, p, buttons);
-}
-
-- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
-{
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
-}
-
-- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
-{
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::LeftButton];
-}
-
-- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
-{
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
-}
-
-- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
-{
- [self sendMouseEventForTouches:touches withEvent:event fakeButtons:Qt::NoButton];
-}
-
-// ------- Text Input ----------
-
-@synthesize autocapitalizationType;
-@synthesize autocorrectionType;
-@synthesize enablesReturnKeyAutomatically;
-@synthesize keyboardAppearance;
-@synthesize keyboardType;
-@synthesize returnKeyType;
-@synthesize secureTextEntry;
-
-- (BOOL)canBecomeFirstResponder
-{
- return YES;
-}
-
-- (BOOL)hasText
-{
- return YES;
-}
-
-- (void)insertText:(NSString *)text
-{
- QKeyEvent *ev;
- int key = 0;
- if ([text isEqualToString:@"\n"])
- key = (int)Qt::Key_Return;
- ev = new QKeyEvent(QEvent::KeyPress,
- key,
- Qt::NoModifier,
- QString::fromUtf8([text UTF8String])
- );
- qApp->postEvent(qApp->focusWidget(), ev);
- ev = new QKeyEvent(QEvent::KeyRelease,
- key,
- Qt::NoModifier,
- QString::fromUtf8([text UTF8String])
- );
- qApp->postEvent(qApp->focusWidget(), ev);
-}
-
-- (void)deleteBackward
-{
- QKeyEvent *ev;
- ev = new QKeyEvent(QEvent::KeyPress,
- (int)Qt::Key_Backspace,
- Qt::NoModifier
- );
- qApp->postEvent(qApp->focusWidget(), ev);
- ev = new QKeyEvent(QEvent::KeyRelease,
- (int)Qt::Key_Backspace,
- Qt::NoModifier
- );
- qApp->postEvent(qApp->focusWidget(), ev);
-}
-
-@end
-
-QT_BEGIN_NAMESPACE
-
-QUIKitWindow::QUIKitWindow(QWidget *tlw) :
- QPlatformWindow(tlw),
- mWindow(nil),
- mContext(0)
-{
- mScreen = static_cast<QUIKitScreen *>(QPlatformScreen::platformScreenForWidget(tlw));
- CGRect screenBounds = [mScreen->uiScreen() bounds];
- QRect geom(screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height);
- setGeometry(geom);
- mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
- // TODO ensure the native window if the application is already running
-}
-
-QUIKitWindow::~QUIKitWindow()
-{
- delete mContext; mContext = 0;
- [mView release];
- [mWindow release];
-}
-
-void QUIKitWindow::setGeometry(const QRect &rect)
-{
- if (mWindow && rect != geometry()) {
- mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
- mView.frame = CGRectMake(0, 0, rect.width(), rect.height());
- [mView deleteFramebuffer];
- [mWindow setNeedsDisplay];
- }
- QPlatformWindow::setGeometry(rect);
-}
-
-UIWindow *QUIKitWindow::ensureNativeWindow()
-{
- if (!mWindow) {
- // window
- CGRect frame = [mScreen->uiScreen() applicationFrame];
- QRect geom = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
- widget()->setGeometry(geom);
- mWindow = [[UIWindow alloc] init];
- mWindow.screen = mScreen->uiScreen();
- mWindow.frame = frame; // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards
-
- // view
- [mView deleteFramebuffer];
- mView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); // fill
- [mView setMultipleTouchEnabled:YES];
- [mView setWindow:this];
- [mWindow addSubview:mView];
- [mWindow setNeedsDisplay];
- [mWindow makeKeyAndVisible];
- }
- return mWindow;
-}
-
-QPlatformOpenGLContext *QUIKitWindow::glContext() const
-{
- if (!mContext) {
- mContext = new EAGLPlatformContext(mView);
- }
- return mContext;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.mm b/src/plugins/platforms/uikit/quikitwindowsurface.mm
deleted file mode 100644
index b7455b3bbe..0000000000
--- a/src/plugins/platforms/uikit/quikitwindowsurface.mm
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "quikitwindowsurface.h"
-#include "quikitwindow.h"
-
-#include <QtOpenGL/private/qgl_p.h>
-#include <QtOpenGL/private/qglpaintdevice_p.h>
-
-#include <QtDebug>
-
-class EAGLPaintDevice;
-
-@interface PaintDeviceHelper : NSObject {
- EAGLPaintDevice *device;
-}
-
-@property (nonatomic, assign) EAGLPaintDevice *device;
-
-- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer;
-
-@end
-
-class EAGLPaintDevice : public QGLPaintDevice
-{
-public:
- EAGLPaintDevice(QPlatformWindow *window)
- :QGLPaintDevice(), mWindow(window)
- {
-#if defined(QT_OPENGL_ES_2)
- helper = [[PaintDeviceHelper alloc] init];
- helper.device = this;
- EAGLView *view = static_cast<QUIKitWindow *>(window)->nativeView();
- view.delegate = helper;
- m_thisFBO = view.fbo;
-#endif
- }
-
- ~EAGLPaintDevice()
- {
-#if defined(QT_OPENGL_ES_2)
- [helper release];
-#endif
- }
-
- void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; }
- int devType() const { return QInternal::OpenGL; }
- QSize size() const { return mWindow->geometry().size(); }
- QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); }
-
- QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); }
-
-private:
- QPlatformWindow *mWindow;
- PaintDeviceHelper *helper;
-};
-
-@implementation PaintDeviceHelper
-@synthesize device;
-
-- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer
-{
- Q_UNUSED(view)
- if (device)
- device->setFramebuffer(buffer);
-}
-
-@end
-
-QT_BEGIN_NAMESPACE
-
-QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window)
- : QWindowSurface(window), mPaintDevice(new EAGLPaintDevice(window->platformWindow()))
-{
-}
-
-QPaintDevice *QUIKitWindowSurface::paintDevice()
-{
- return mPaintDevice;
-}
-
-void QUIKitWindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
-{
- Q_UNUSED(widget);
- Q_UNUSED(region);
- Q_UNUSED(offset);
- widget->platformWindow()->glContext()->swapBuffers();
-}
-
-QWindowSurface::WindowSurfaceFeatures QUIKitWindowSurface::features() const
-{
- return PartialUpdates;
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/uikit/uikit.pro b/src/plugins/platforms/uikit/uikit.pro
deleted file mode 100644
index 5e3a0e6b7c..0000000000
--- a/src/plugins/platforms/uikit/uikit.pro
+++ /dev/null
@@ -1,27 +0,0 @@
-TARGET = quikit
-load(qpa/plugin)
-QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/platforms
-
-QT += opengl
-
-OBJECTIVE_SOURCES = main.mm \
- quikitintegration.mm \
- quikitwindow.mm \
- quikitscreen.mm \
- quikiteventloop.mm \
- quikitwindowsurface.mm
-
-OBJECTIVE_HEADERS = quikitintegration.h \
- quikitwindow.h \
- quikitscreen.h \
- quikiteventloop.h \
- quikitwindowsurface.h
-
-HEADERS = quikitsoftwareinputhandler.h
-
-#add libz for freetype.
-LIBS += -lz
-
-#load(qpa/fontdatabases/basicunix)
-target.path += $$[QT_INSTALL_PLUGINS]/platforms
-INSTALLS += target
diff --git a/src/plugins/platforms/vnc/qvnccursor.cpp b/src/plugins/platforms/vnc/qvnccursor.cpp
deleted file mode 100644
index 52591bdc05..0000000000
--- a/src/plugins/platforms/vnc/qvnccursor.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include <QPainter>
-#include <QTcpSocket>
-#include <arpa/inet.h>
-#include <QBitmap>
-#include <QApplication>
-
-#include <QDebug>
-
-#include "qvnccursor.h"
-#include "qvncserver.h"
-#include "qvncintegration.h"
-
-QT_BEGIN_NAMESPACE
-
-QVNCCursor::QVNCCursor(QVNCServer * srvr, QVNCScreen *scr )
- :QPlatformSoftwareCursor(scr), useVncCursor(false), server(srvr)
-{
-}
-
-void QVNCCursor::changeCursor(QCursor * widgetCursor, QWidget * widget)
-{
- QPlatformSoftwareCursor::changeCursor(widgetCursor, widget);
- if (useVncCursor) {
- server->setDirtyCursor();
- } else {
- setDirty();
- }
-}
-
-void QVNCCursor::setCursorMode(bool vnc)
-{
- if (vnc) {
- setDirty();
- server->setDirtyCursor();
- } else {
- server->setDirtyCursor();
- }
- useVncCursor = vnc;
-}
-
-QRect QVNCCursor::drawCursor(QPainter & painter)
-{
- if (useVncCursor)
- return QRect();
-
- return QPlatformSoftwareCursor::drawCursor(painter);
-}
-
-void QVNCCursor::clearClientCursor()
-{
- QTcpSocket *socket = server->clientSocket();
- if (!socket) {
- return;
- }
- // FramebufferUpdate header
- {
- const quint16 tmp[6] = { htons(0),
- htons(1),
- htons(0), htons(0),
- htons(0),
- htons(0) };
- socket->write((char*)tmp, sizeof(tmp));
-
- const quint32 encoding = htonl(-239);
- socket->write((char*)(&encoding), sizeof(encoding));
- }
-}
-
-void QVNCCursor::sendClientCursor()
-{
- if (useVncCursor == false) {
- clearClientCursor();
- return;
- }
- QImage *image = graphic->image();
- if (image->isNull())
- return;
- QTcpSocket *socket = server->clientSocket();
- if (!socket) {
- return;
- }
- // FramebufferUpdate header
- {
- const quint16 tmp[6] = { htons(0),
- htons(1),
- htons(graphic->hotspot().x()), htons(graphic->hotspot().y()),
- htons(image->width()),
- htons(image->height()) };
- socket->write((char*)tmp, sizeof(tmp));
-
- const quint32 encoding = htonl(-239);
- socket->write((char*)(&encoding), sizeof(encoding));
- }
-
- // write pixels
- //Q_ASSERT(cursor->hasAlphaChannel());
- const QImage img = image->convertToFormat(QImage::Format_RGB32);
- const int n = server->clientBytesPerPixel() * img.width();
- char *buffer = new char[n];
- for (int i = 0; i < img.height(); ++i) {
- server->convertPixels(buffer, (const char*)img.scanLine(i), img.width());
- socket->write(buffer, n);
- }
- delete[] buffer;
-
- // write mask
- const QImage bitmap = image->createAlphaMask().convertToFormat(QImage::Format_Mono);
- Q_ASSERT(bitmap.depth() == 1);
- Q_ASSERT(bitmap.size() == img.size());
- const int width = (bitmap.width() + 7) / 8;
- for (int i = 0; i < bitmap.height(); ++i)
- socket->write((const char*)bitmap.scanLine(i), width);
-}
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvnccursor.h b/src/plugins/platforms/vnc/qvnccursor.h
deleted file mode 100644
index 3428d71ac7..0000000000
--- a/src/plugins/platforms/vnc/qvnccursor.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-#ifndef QVNCCURSOR_H
-#define QVNCCURSOR_H
-
-#include "../fb_base/fb_base.h"
-#include <QList>
-#include <QImage>
-#include <QMouseEvent>
-
-QT_BEGIN_NAMESPACE
-
-class QVNCScreen;
-class QVNCServer;
-
-class QVNCCursor : public QPlatformSoftwareCursor {
-public:
- QVNCCursor(QVNCServer *, QVNCScreen *);
-
- // input methods
- void setCursorMode(bool vnc);
- void changeCursor(QCursor * widgetCursor, QWidget * widget);
-
- // output methods
- QRect drawCursor(QPainter &);
-
- // VNC client communication
- void sendClientCursor();
- void clearClientCursor();
-private:
- bool useVncCursor; // VNC or local
-
- QVNCServer * server; // VNC server to get events from
-};
-
-QT_END_NAMESPACE
-
-#endif // QVNCCURSOR_H
diff --git a/src/plugins/platforms/vnc/qvncintegration.cpp b/src/plugins/platforms/vnc/qvncintegration.cpp
deleted file mode 100644
index 8b653f7208..0000000000
--- a/src/plugins/platforms/vnc/qvncintegration.cpp
+++ /dev/null
@@ -1,255 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qvncintegration.h"
-#include "../fb_base/fb_base.h"
-#include <private/qapplication_p.h>
-#include <QtGui/private/qpixmap_raster_p.h>
-#include <QtCore/qdebug.h>
-
-#include <qvncserver.h>
-#include <QtGui/QPainter>
-
-#include <QtCore/QTimer>
-#include "qgenericunixfontdatabase.h"
-
-QVNCScreen::QVNCScreen(QRect screenSize, int screenId)
- : QFbScreen::QFbScreen()
-{
- setGeometry(screenSize);
- setDepth(32);
- setFormat(QImage::Format_RGB32);
- setPhysicalSize((geometry().size()*254)/720);
-
-
- d_ptr = new QVNCScreenPrivate(this, screenId);
-
- cursor = new QVNCCursor(d_ptr->vncServer, this);
- d_ptr->vncServer->setCursor(static_cast<QVNCCursor *>(cursor));
-}
-
-QVNCDirtyMap *QVNCScreen::dirtyMap()
-{
- return d_ptr->dirty;
-}
-
-QRegion QVNCScreen::doRedraw()
-{
- QRegion touched;
- touched = QFbScreen::doRedraw();
-
- QVector<QRect> rects = touched.rects();
- for (int i = 0; i < rects.size(); i++)
- d_ptr->setDirty(rects[i]);
- return touched;
-}
-
-static inline int defaultWidth() { return 800; }
-static inline int defaultHeight() { return 600; }
-static inline int defaultDisplay() { return 0; }
-
-static void usage()
-{
- qWarning() << "VNC Platform Integration options:";
- qWarning() << " size=<Width>x<Height> - set the display width and height";
- qWarning() << " defaults to" << defaultWidth() << "x" << defaultHeight();
- qWarning() << " display=<ID> - set the VNC display port to ID + 5900";
- qWarning() << " defaults to" << defaultDisplay();
- qWarning() << " offset=<X>x<Y> - set the current screens offset";
- qWarning() << " vnc - start configuration of a new screen";
- qWarning() << " size and offset are inherited from the previous screen if not set";
- qWarning() << " display id is incremented from the previous screen if not set";
- qWarning() << " virtual - manage the set of screens as a virtual desktop";
-}
-
-QVNCIntegration::QVNCIntegration(const QStringList& paramList)
- : virtualDesktop(false), fontDb(new QGenericUnixFontDatabase())
-{
- int sizeX = defaultWidth();
- int sizeY = defaultHeight();
- int offsetX = 0;
- int offsetY = 0;
- int display = defaultDisplay();
- bool showUsage = false;
-
- foreach(QString confString, paramList) {
- if (confString.startsWith(QLatin1String("size="))) {
- QString val = confString.section(QLatin1Char('='), 1, 1);
- sizeX = val.section(QLatin1Char('x'), 0, 0).toInt();
- sizeY = val.section(QLatin1Char('x'), 1, 1).toInt();
- }
- else if (confString.startsWith(QLatin1String("display="))) {
- display = confString.section(QLatin1Char('='), 1, 1).toInt();
- }
- else if (confString.startsWith(QLatin1String("offset="))) {
- QString val = confString.section(QLatin1Char('='), 1, 1);
- offsetX = val.section(QLatin1Char('x'), 0, 0).toInt();
- offsetY = val.section(QLatin1Char('x'), 1, 1).toInt();
- }
- else if (confString == QLatin1String("vnc")) {
- QRect screenRect(offsetX, offsetY, sizeX, sizeY);
- QVNCScreen *screen = new QVNCScreen(screenRect, display);
- mScreens.append(screen);
- screen->setObjectName(QString("screen %1").arg(display));
- screen->setDirty(screenRect);
- ++display;
- }
- else if (confString == QLatin1String("virtual")) {
- virtualDesktop = true;
- }
- else {
- qWarning() << "Unknown VNC option:" << confString;
- showUsage = true;
- }
- }
-
- if (showUsage)
- usage();
-
- QRect screenRect(offsetX, offsetY, sizeX, sizeY);
- QVNCScreen *screen = new QVNCScreen(screenRect, display);
- mScreens.append(screen);
- mPrimaryScreen = qobject_cast<QVNCScreen *>(mScreens.first());
- screen->setObjectName(QString("screen %1").arg(display));
- screen->setDirty(screenRect);
-}
-
-bool QVNCIntegration::hasCapability(QPlatformIntegration::Capability cap) const
-{
- switch (cap) {
- case ThreadedPixmaps: return true;
- default: return QPlatformIntegration::hasCapability(cap);
- }
-}
-
-
-QPlatformPixmap *QVNCIntegration::createPlatformPixmap(QPlatformPixmap::PixelType type) const
-{
- return new QRasterPlatformPixmap(type);
-}
-
-QWindowSurface *QVNCIntegration::createWindowSurface(QWidget *widget, WId) const
-{
- QFbWindowSurface * surface;
- surface = new QFbWindowSurface(mPrimaryScreen, widget);
- return surface;
-}
-
-QAbstractEventDispatcher *QVFbIntegration::createEventDispatcher() const
-{
- return createUnixEventDispatcher();
-}
-
-QPlatformWindow *QVNCIntegration::createPlatformWindow(QWidget *widget, WId /*winId*/) const
-{
- QFbWindow *w = new QFbWindow(widget);
- if (virtualDesktop) {
- QList<QPlatformScreen *>::const_iterator i = mScreens.constBegin();
- QList<QPlatformScreen *>::const_iterator end = mScreens.constEnd();
- QFbScreen *screen;
- while (i != end) {
- screen = static_cast<QFbScreen *>(*i);
- screen->addWindow(w);
- ++i;
- }
- }
- else
- mPrimaryScreen->addWindow(w);
- return w;
-}
-
-QPixmap QVNCIntegration::grabWindow(WId window, int x, int y, int width, int height) const
-{
-// qDebug() << "QVNCIntegration::grabWindow" << window << x << y << width << height;
-
- if (window == 0) { //desktop
- QImage *desktopImage = mPrimaryScreen->image();
- if (x==0 && y == 0 && width < 0 && height < 0) {
- return QPixmap::fromImage(*desktopImage);
- }
- if (width < 0)
- width = desktopImage->width() - x;
- if (height < 0)
- height = desktopImage->height() - y;
- int bytesPerPixel = desktopImage->depth()/8; //We don't support 1, 2, or 4 bpp
- QImage img(desktopImage->scanLine(y) + bytesPerPixel*x, width, height, desktopImage->bytesPerLine(), desktopImage->format());
- return QPixmap::fromImage(img);
- }
- QWidget *win = QWidget::find(window);
- if (win) {
- QRect r = win->geometry();
- if (width < 0)
- width = r.width() - x;
- if (height < 0)
- height = r.height() - y;
- QImage *desktopImage = mPrimaryScreen->image();
- int bytesPerPixel = desktopImage->depth()/8; //We don't support 1, 2, or 4 bpp
-
- QImage img(desktopImage->scanLine(r.top() + y) + bytesPerPixel*(r.left()+x), width, height, desktopImage->bytesPerLine(), desktopImage->format());
- return QPixmap::fromImage(img);
- }
- return QPixmap();
-}
-
-
-void QVNCIntegration::moveToScreen(QWidget *window, int screen)
-{
- if (virtualDesktop) { // all windows exist on all screens in virtual desktop mode
- return;
- }
- if (screen < 0 || screen > mScreens.size())
- return;
- QVNCScreen * newScreen = qobject_cast<QVNCScreen *>(mScreens.at(screen));
- for(int i = 0; i < mScreens.size(); i++) {
- QVNCScreen *oldScreen = qobject_cast<QVNCScreen *>(mScreens.at(i));
- if (oldScreen->windowStack.contains(static_cast<QFbWindow *>(window->platformWindow()))) {
- oldScreen->removeWindow(static_cast<QFbWindow *>(window->platformWindow()));
- break;
- }
- }
- window->platformWindow()->setGeometry(window->geometry()); // this should be unified elsewhere
- newScreen->addWindow(static_cast<QFbWindow *>(window->platformWindow()));
-}
-
-QPlatformFontDatabase *QVNCIntegration::fontDatabase() const
-{
- return fontDb;
-}
diff --git a/src/plugins/platforms/vnc/qvncintegration.h b/src/plugins/platforms/vnc/qvncintegration.h
deleted file mode 100644
index a6baf0340e..0000000000
--- a/src/plugins/platforms/vnc/qvncintegration.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QGRAPHICSSYSTEM_VNC_H
-#define QGRAPHICSSYSTEM_VNC_H
-
-#include "qvnccursor.h"
-#include "../fb_base/fb_base.h"
-#include <QPlatformIntegration>
-#include "qgenericunixfontdatabase.h"
-
-QT_BEGIN_NAMESPACE
-
-class QVNCServer;
-class QVNCDirtyMap;
-
-class QVNCScreenPrivate;
-
-class QVNCScreen : public QFbScreen
-{
- Q_OBJECT
-public:
- QVNCScreen(QRect screenSize, int screenId);
-
- int linestep() const { return image() ? image()->bytesPerLine() : 0; }
- uchar *base() const { return image() ? image()->bits() : 0; }
- QVNCDirtyMap *dirtyMap();
-
-public:
- QVNCScreenPrivate *d_ptr;
-
-private:
- QVNCServer *server;
- QRegion doRedraw();
- friend class QVNCIntegration;
-};
-
-class QVNCIntegrationPrivate;
-class QAbstractEventDispatcher;
-
-class QVNCIntegration : public QPlatformIntegration
-{
-public:
- QVNCIntegration(const QStringList& paramList);
-
- bool hasCapability(QPlatformIntegration::Capability cap) const;
- QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
- QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId) const;
- QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const;
- QAbstractEventDispatcher createEventDispatcher() const;
-
- QPixmap grabWindow(WId window, int x, int y, int width, int height) const;
-
- QList<QPlatformScreen *> screens() const { return mScreens; }
-
- bool isVirtualDesktop() { return virtualDesktop; }
- void moveToScreen(QWidget *window, int screen);
-
- QPlatformFontDatabase *fontDatabase() const;
-
-private:
- QVNCScreen *mPrimaryScreen;
- QList<QPlatformScreen *> mScreens;
- bool virtualDesktop;
- QPlatformFontDatabase *fontDb;
-};
-
-
-
-QT_END_NAMESPACE
-
-#endif //QGRAPHICSSYSTEM_VNC_H
-
diff --git a/src/plugins/platforms/vnc/qvncserver.cpp b/src/plugins/platforms/vnc/qvncserver.cpp
deleted file mode 100644
index db49025c41..0000000000
--- a/src/plugins/platforms/vnc/qvncserver.cpp
+++ /dev/null
@@ -1,1935 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qvncserver.h"
-
-#include <QtCore/qtimer.h>
-#include <QtCore/qregexp.h>
-#include <QtWidgets/qwidget.h>
-#include <QtGui/qpolygon.h>
-#include <QtGui/qpainter.h>
-
-#include <QtGui/qevent.h>
-#include <QWindowSystemInterface>
-
-#include <qplatformdefs.h>
-
-#include <qdebug.h>
-
-#include <stdlib.h>
-
-
-#define QT_QWS_VNC_DEBUG
-#define QT_NO_QWS_CURSOR //###
-
-
-QT_BEGIN_NAMESPACE
-
-
-
-//copied from qscreen_qws.h
-#ifndef QT_QWS_DEPTH16_RGB
-#define QT_QWS_DEPTH16_RGB 565
-#endif
-static const int qt_rbits = (QT_QWS_DEPTH16_RGB/100);
-static const int qt_gbits = (QT_QWS_DEPTH16_RGB/10%10);
-static const int qt_bbits = (QT_QWS_DEPTH16_RGB%10);
-static const int qt_red_shift = qt_bbits+qt_gbits-(8-qt_rbits);
-static const int qt_green_shift = qt_bbits-(8-qt_gbits);
-static const int qt_neg_blue_shift = 8-qt_bbits;
-static const int qt_blue_mask = (1<<qt_bbits)-1;
-static const int qt_green_mask = (1<<(qt_gbits+qt_bbits))-(1<<qt_bbits);
-static const int qt_red_mask = (1<<(qt_rbits+qt_gbits+qt_bbits))-(1<<(qt_gbits+qt_bbits));
-
-static const int qt_red_rounding_shift = qt_red_shift + qt_rbits;
-static const int qt_green_rounding_shift = qt_green_shift + qt_gbits;
-static const int qt_blue_rounding_shift = qt_bbits - qt_neg_blue_shift;
-
-
-inline QRgb qt_conv16ToRgb(ushort c)
-{
- const int r=(c & qt_red_mask);
- const int g=(c & qt_green_mask);
- const int b=(c & qt_blue_mask);
- const int tr = r >> qt_red_shift | r >> qt_red_rounding_shift;
- const int tg = g >> qt_green_shift | g >> qt_green_rounding_shift;
- const int tb = b << qt_neg_blue_shift | b >> qt_blue_rounding_shift;
-
- return qRgb(tr,tg,tb);
-}
-
-
-
-//===========================================================================
-
-static const struct {
- int keysym;
- int keycode;
-} keyMap[] = {
- { 0xff08, Qt::Key_Backspace },
- { 0xff09, Qt::Key_Tab },
- { 0xff0d, Qt::Key_Return },
- { 0xff1b, Qt::Key_Escape },
- { 0xff63, Qt::Key_Insert },
- { 0xffff, Qt::Key_Delete },
- { 0xff50, Qt::Key_Home },
- { 0xff57, Qt::Key_End },
- { 0xff55, Qt::Key_PageUp },
- { 0xff56, Qt::Key_PageDown },
- { 0xff51, Qt::Key_Left },
- { 0xff52, Qt::Key_Up },
- { 0xff53, Qt::Key_Right },
- { 0xff54, Qt::Key_Down },
- { 0xffbe, Qt::Key_F1 },
- { 0xffbf, Qt::Key_F2 },
- { 0xffc0, Qt::Key_F3 },
- { 0xffc1, Qt::Key_F4 },
- { 0xffc2, Qt::Key_F5 },
- { 0xffc3, Qt::Key_F6 },
- { 0xffc4, Qt::Key_F7 },
- { 0xffc5, Qt::Key_F8 },
- { 0xffc6, Qt::Key_F9 },
- { 0xffc7, Qt::Key_F10 },
- { 0xffc8, Qt::Key_F11 },
- { 0xffc9, Qt::Key_F12 },
- { 0xffe1, Qt::Key_Shift },
- { 0xffe2, Qt::Key_Shift },
- { 0xffe3, Qt::Key_Control },
- { 0xffe4, Qt::Key_Control },
- { 0xffe7, Qt::Key_Meta },
- { 0xffe8, Qt::Key_Meta },
- { 0xffe9, Qt::Key_Alt },
- { 0xffea, Qt::Key_Alt },
- { 0, 0 }
-};
-
-void QRfbRect::read(QTcpSocket *s)
-{
- quint16 buf[4];
- s->read((char*)buf, 8);
- x = ntohs(buf[0]);
- y = ntohs(buf[1]);
- w = ntohs(buf[2]);
- h = ntohs(buf[3]);
-}
-
-void QRfbRect::write(QTcpSocket *s) const
-{
- quint16 buf[4];
- buf[0] = htons(x);
- buf[1] = htons(y);
- buf[2] = htons(w);
- buf[3] = htons(h);
- s->write((char*)buf, 8);
-}
-
-void QRfbPixelFormat::read(QTcpSocket *s)
-{
- char buf[16];
- s->read(buf, 16);
- bitsPerPixel = buf[0];
- depth = buf[1];
- bigEndian = buf[2];
- trueColor = buf[3];
-
- quint16 a = ntohs(*(quint16 *)(buf + 4));
- redBits = 0;
- while (a) { a >>= 1; redBits++; }
-
- a = ntohs(*(quint16 *)(buf + 6));
- greenBits = 0;
- while (a) { a >>= 1; greenBits++; }
-
- a = ntohs(*(quint16 *)(buf + 8));
- blueBits = 0;
- while (a) { a >>= 1; blueBits++; }
-
- redShift = buf[10];
- greenShift = buf[11];
- blueShift = buf[12];
-}
-
-void QRfbPixelFormat::write(QTcpSocket *s)
-{
- char buf[16];
- buf[0] = bitsPerPixel;
- buf[1] = depth;
- buf[2] = bigEndian;
- buf[3] = trueColor;
-
- quint16 a = 0;
- for (int i = 0; i < redBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 4) = htons(a);
-
- a = 0;
- for (int i = 0; i < greenBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 6) = htons(a);
-
- a = 0;
- for (int i = 0; i < blueBits; i++) a = (a << 1) | 1;
- *(quint16 *)(buf + 8) = htons(a);
-
- buf[10] = redShift;
- buf[11] = greenShift;
- buf[12] = blueShift;
- s->write(buf, 16);
-}
-
-
-void QRfbServerInit::setName(const char *n)
-{
- delete[] name;
- name = new char [strlen(n) + 1];
- strcpy(name, n);
-}
-
-void QRfbServerInit::read(QTcpSocket *s)
-{
- s->read((char *)&width, 2);
- width = ntohs(width);
- s->read((char *)&height, 2);
- height = ntohs(height);
- format.read(s);
-
- quint32 len;
- s->read((char *)&len, 4);
- len = ntohl(len);
-
- name = new char [len + 1];
- s->read(name, len);
- name[len] = '\0';
-}
-
-void QRfbServerInit::write(QTcpSocket *s)
-{
- quint16 t = htons(width);
- s->write((char *)&t, 2);
- t = htons(height);
- s->write((char *)&t, 2);
- format.write(s);
- quint32 len = strlen(name);
- len = htonl(len);
- s->write((char *)&len, 4);
- s->write(name, strlen(name));
-}
-
-bool QRfbSetEncodings::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 3)
- return false;
-
- char tmp;
- s->read(&tmp, 1); // padding
- s->read((char *)&count, 2);
- count = ntohs(count);
-
- return true;
-}
-
-bool QRfbFrameBufferUpdateRequest::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 9)
- return false;
-
- s->read(&incremental, 1);
- rect.read(s);
-
- return true;
-}
-
-bool QRfbKeyEvent::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 7)
- return false;
-
- s->read(&down, 1);
- quint16 tmp;
- s->read((char *)&tmp, 2); // padding
-
- quint32 key;
- s->read((char *)&key, 4);
- key = ntohl(key);
-
- unicode = 0;
- keycode = 0;
- int i = 0;
- while (keyMap[i].keysym && !keycode) {
- if (keyMap[i].keysym == (int)key)
- keycode = keyMap[i].keycode;
- i++;
- }
- if (!keycode) {
- if (key <= 0xff) {
- unicode = key;
- if (key >= 'a' && key <= 'z')
- keycode = Qt::Key_A + key - 'a';
- else if (key >= ' ' && key <= '~')
- keycode = Qt::Key_Space + key - ' ';
- }
- }
-
- return true;
-}
-
-bool QRfbPointerEvent::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 5)
- return false;
-
- char buttonMask;
- s->read(&buttonMask, 1);
-
- buttons = Qt::NoButton;
- wheelDirection = WheelNone;
- if (buttonMask & 1)
- buttons |= Qt::LeftButton;
- if (buttonMask & 2)
- buttons |= Qt::MidButton;
- if (buttonMask & 4)
- buttons |= Qt::RightButton;
- if (buttonMask & 8)
- wheelDirection = WheelUp;
- if (buttonMask & 16)
- wheelDirection = WheelDown;
- if (buttonMask & 32)
- wheelDirection = WheelLeft;
- if (buttonMask & 64)
- wheelDirection = WheelRight;
-
- quint16 tmp;
- s->read((char *)&tmp, 2);
- x = ntohs(tmp);
- s->read((char *)&tmp, 2);
- y = ntohs(tmp);
-
- return true;
-}
-
-bool QRfbClientCutText::read(QTcpSocket *s)
-{
- if (s->bytesAvailable() < 7)
- return false;
-
- char tmp[3];
- s->read(tmp, 3); // padding
- s->read((char *)&length, 4);
- length = ntohl(length);
-
- return true;
-}
-
-//===========================================================================
-
-QVNCServer::QVNCServer(QVNCScreen *screen)
- : qvnc_screen(screen), cursor(0)
-{
- init(5900);
-}
-
-QVNCServer::QVNCServer(QVNCScreen *screen, int id)
- : qvnc_screen(screen), cursor(0)
-{
- init(5900 + id);
-}
-
-void QVNCServer::init(uint port)
-{
- qDebug() << "QVNCServer::init" << port;
-
- handleMsg = false;
- client = 0;
- encodingsPending = 0;
- cutTextPending = 0;
- keymod = 0;
- state = Unconnected;
- dirtyCursor = false;
-
- refreshRate = 25;
- timer = new QTimer(this);
- timer->setSingleShot(true);
- connect(timer, SIGNAL(timeout()), this, SLOT(checkUpdate()));
-
- serverSocket = new QTcpServer(this);
- if (!serverSocket->listen(QHostAddress::Any, port))
- qDebug() << "QVNCServer could not connect:" << serverSocket->errorString();
- else
- qDebug("QVNCServer created on port %d", port);
-
- connect(serverSocket, SIGNAL(newConnection()), this, SLOT(newConnection()));
-
-#ifndef QT_NO_QWS_CURSOR
- qvnc_cursor = 0;
-#endif
- encoder = 0;
-}
-
-QVNCServer::~QVNCServer()
-{
- delete encoder;
- encoder = 0;
- delete client;
- client = 0;
-#ifndef QT_NO_QWS_CURSOR
- delete qvnc_cursor;
- qvnc_cursor = 0;
-#endif
-}
-
-void QVNCServer::setDirty()
-{
- if (state == Connected && !timer->isActive() &&
- ((dirtyMap()->numDirty > 0) || dirtyCursor)) {
- timer->start();
- }
-}
-
-void QVNCServer::newConnection()
-{
- if (client)
- delete client;
-
- client = serverSocket->nextPendingConnection();
- connect(client,SIGNAL(readyRead()),this,SLOT(readClient()));
- connect(client,SIGNAL(disconnected()),this,SLOT(discardClient()));
- handleMsg = false;
- encodingsPending = 0;
- cutTextPending = 0;
- supportHextile = false;
- wantUpdate = false;
-
- timer->start(1000 / refreshRate);
- dirtyMap()->reset();
-
- // send protocol version
- const char *proto = "RFB 003.003\n";
- client->write(proto, 12);
- state = Protocol;
-
-// if (!qvnc_screen->screen())
-// QWSServer::instance()->enablePainting(true);
-}
-
-void QVNCServer::readClient()
-{
- switch (state) {
- case Protocol:
- if (client->bytesAvailable() >= 12) {
- char proto[13];
- client->read(proto, 12);
- proto[12] = '\0';
- qDebug("Client protocol version %s", proto);
- // No authentication
- quint32 auth = htonl(1);
- client->write((char *) &auth, sizeof(auth));
- state = Init;
- }
- break;
-
- case Init:
- if (client->bytesAvailable() >= 1) {
- quint8 shared;
- client->read((char *) &shared, 1);
-
- // Server Init msg
- QRfbServerInit sim;
- QRfbPixelFormat &format = sim.format;
- switch (qvnc_screen->depth()) {
- case 32:
- format.bitsPerPixel = 32;
- format.depth = 32;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 8;
- format.greenBits = 8;
- format.blueBits = 8;
- format.redShift = 16;
- format.greenShift = 8;
- format.blueShift = 0;
- break;
-
- case 24:
- format.bitsPerPixel = 24;
- format.depth = 24;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 8;
- format.greenBits = 8;
- format.blueBits = 8;
- format.redShift = 16;
- format.greenShift = 8;
- format.blueShift = 0;
- break;
-
- case 18:
- format.bitsPerPixel = 24;
- format.depth = 18;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 6;
- format.greenBits = 6;
- format.blueBits = 6;
- format.redShift = 12;
- format.greenShift = 6;
- format.blueShift = 0;
- break;
-
- case 16:
- format.bitsPerPixel = 16;
- format.depth = 16;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 5;
- format.greenBits = 6;
- format.blueBits = 5;
- format.redShift = 11;
- format.greenShift = 5;
- format.blueShift = 0;
- break;
-
- case 15:
- format.bitsPerPixel = 16;
- format.depth = 15;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 5;
- format.greenBits = 5;
- format.blueBits = 5;
- format.redShift = 10;
- format.greenShift = 5;
- format.blueShift = 0;
- break;
-
- case 12:
- format.bitsPerPixel = 16;
- format.depth = 12;
- format.bigEndian = 0;
- format.trueColor = true;
- format.redBits = 4;
- format.greenBits = 4;
- format.blueBits = 4;
- format.redShift = 8;
- format.greenShift = 4;
- format.blueShift = 0;
- break;
-
- case 8:
- case 4:
- format.bitsPerPixel = 8;
- format.depth = 8;
- format.bigEndian = 0;
- format.trueColor = false;
- format.redBits = 0;
- format.greenBits = 0;
- format.blueBits = 0;
- format.redShift = 0;
- format.greenShift = 0;
- format.blueShift = 0;
- break;
-
- default:
- qDebug("QVNC cannot drive depth %d", qvnc_screen->depth());
- discardClient();
- return;
- }
- sim.width = qvnc_screen->geometry().width();
- sim.height = qvnc_screen->geometry().height();
- sim.setName("Qt for Embedded Linux VNC Server");
- sim.write(client);
- state = Connected;
- }
- break;
-
- case Connected:
- do {
- if (!handleMsg) {
- client->read((char *)&msgType, 1);
- handleMsg = true;
- }
- if (handleMsg) {
- switch (msgType ) {
- case SetPixelFormat:
- setPixelFormat();
- break;
- case FixColourMapEntries:
- qDebug("Not supported: FixColourMapEntries");
- handleMsg = false;
- break;
- case SetEncodings:
- setEncodings();
- break;
- case FramebufferUpdateRequest:
- frameBufferUpdateRequest();
- break;
- case KeyEvent:
- keyEvent();
- break;
- case PointerEvent:
- pointerEvent();
- break;
- case ClientCutText:
- clientCutText();
- break;
- default:
- qDebug("Unknown message type: %d", (int)msgType);
- handleMsg = false;
- }
- }
- } while (!handleMsg && client->bytesAvailable());
- break;
- default:
- break;
- }
-}
-
-#if 0//Q_BYTE_ORDER == Q_BIG_ENDIAN
-bool QVNCScreen::swapBytes() const
-{
- if (depth() != 16)
- return false;
-
- if (screen())
- return screen()->frameBufferLittleEndian();
- return frameBufferLittleEndian();
-}
-#endif
-
-void QVNCServer::setPixelFormat()
-{
- if (client->bytesAvailable() >= 19) {
- char buf[3];
- client->read(buf, 3); // just padding
- pixelFormat.read(client);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("Want format: %d %d %d %d %d %d %d %d %d %d",
- int(pixelFormat.bitsPerPixel),
- int(pixelFormat.depth),
- int(pixelFormat.bigEndian),
- int(pixelFormat.trueColor),
- int(pixelFormat.redBits),
- int(pixelFormat.greenBits),
- int(pixelFormat.blueBits),
- int(pixelFormat.redShift),
- int(pixelFormat.greenShift),
- int(pixelFormat.blueShift));
-#endif
- if (!pixelFormat.trueColor) {
- qDebug("Can only handle true color clients");
- discardClient();
- }
- handleMsg = false;
- sameEndian = (QSysInfo::ByteOrder == QSysInfo::BigEndian) == !!pixelFormat.bigEndian;
- needConversion = pixelConversionNeeded();
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- swapBytes = qvnc_screen->swapBytes();
-#endif
- }
-}
-
-void QVNCServer::setEncodings()
-{
- QRfbSetEncodings enc;
-
- if (!encodingsPending && enc.read(client)) {
- encodingsPending = enc.count;
- if (!encodingsPending)
- handleMsg = false;
- }
-
- if (encoder) {
- delete encoder;
- encoder = 0;
- }
-
- enum Encodings {
- Raw = 0,
- CopyRect = 1,
- RRE = 2,
- CoRRE = 4,
- Hextile = 5,
- ZRLE = 16,
- Cursor = -239,
- DesktopSize = -223
- };
-
- supportCursor = false;
-
- if (encodingsPending && (unsigned)client->bytesAvailable() >=
- encodingsPending * sizeof(quint32)) {
- for (int i = 0; i < encodingsPending; ++i) {
- qint32 enc;
- client->read((char *)&enc, sizeof(qint32));
- enc = ntohl(enc);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: %d", enc);
-#endif
- switch (enc) {
- case Raw:
- if (!encoder) {
- encoder = new QRfbRawEncoder(this);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: using raw");
-#endif
- }
- break;
- case CopyRect:
- supportCopyRect = true;
- break;
- case RRE:
- supportRRE = true;
- break;
- case CoRRE:
- supportCoRRE = true;
- break;
- case Hextile:
- supportHextile = true;
- if (encoder)
- break;
- switch (qvnc_screen->depth()) {
-#ifdef QT_QWS_DEPTH_8
- case 8:
- encoder = new QRfbHextileEncoder<quint8>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12:
- encoder = new QRfbHextileEncoder<qrgb444>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15:
- encoder = new QRfbHextileEncoder<qrgb555>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_16
- case 16:
- encoder = new QRfbHextileEncoder<quint16>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_18
- case 18:
- encoder = new QRfbHextileEncoder<qrgb666>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24:
- encoder = new QRfbHextileEncoder<qrgb888>(this);
- break;
-#endif
-#ifdef QT_QWS_DEPTH_32
- case 32:
- encoder = new QRfbHextileEncoder<quint32>(this);
- break;
-#endif
- default:
- break;
- }
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: using hextile");
-#endif
- break;
- case ZRLE:
- supportZRLE = true;
- break;
- case Cursor:
- supportCursor = true;
-#ifndef QT_NO_QWS_CURSOR
- if (!qvnc_screen->screen() || qt_screencursor->isAccelerated()) {
- delete qvnc_cursor;
- qvnc_cursor = new QVNCClientCursor(this);
- }
-#endif
- break;
- case DesktopSize:
- supportDesktopSize = true;
- break;
- default:
- break;
- }
- }
- handleMsg = false;
- encodingsPending = 0;
- }
-
- if (!encoder) {
- encoder = new QRfbRawEncoder(this);
-#ifdef QT_QWS_VNC_DEBUG
- qDebug("QVNCServer::setEncodings: fallback using raw");
-#endif
- }
-
- if (cursor)
- cursor->setCursorMode(supportCursor);
-}
-
-void QVNCServer::frameBufferUpdateRequest()
-{
- QRfbFrameBufferUpdateRequest ev;
-
- if (ev.read(client)) {
- if (!ev.incremental) {
- QRect r(ev.rect.x, ev.rect.y, ev.rect.w, ev.rect.h);
-////### r.translate(qvnc_screen->offset());
- qvnc_screen->d_ptr->setDirty(r, true);
- }
- wantUpdate = true;
- checkUpdate();
- handleMsg = false;
- }
-}
-
-static bool buttonChange(Qt::MouseButtons before, Qt::MouseButtons after, Qt::MouseButton *button, bool *isPress)
-{
- if (before == after)
- return false;
- for (int b = Qt::LeftButton; b <= Qt::MidButton; b<<=1) {
- if ((before & b) != (after & b)) {
- *button = static_cast<Qt::MouseButton>(b);
- *isPress = (after & b);
- return true;
- }
- }
- return false;
-}
-
-void QVNCServer::pointerEvent()
-{
- QPoint screenOffset = this->screen()->geometry().topLeft();
-
- QRfbPointerEvent ev;
- if (ev.read(client)) {
- QPoint eventPoint(ev.x, ev.y);
- eventPoint += screenOffset; // local to global translation
-
- if (ev.wheelDirection == ev.WheelNone) {
- QEvent::Type type = QEvent::MouseMove;
- Qt::MouseButton button = Qt::NoButton;
- bool isPress;
- if (buttonChange(buttons, ev.buttons, &button, &isPress))
- type = isPress ? QEvent::MouseButtonPress : QEvent::MouseButtonRelease;
- QWindowSystemInterface::handleMouseEvent(0, eventPoint, eventPoint, ev.buttons);
- } else {
- // No buttons or motion reported at the same time as wheel events
- Qt::Orientation orientation;
- if (ev.wheelDirection == ev.WheelLeft || ev.wheelDirection == ev.WheelRight)
- orientation = Qt::Horizontal;
- else
- orientation = Qt::Vertical;
- int delta = 120 * ((ev.wheelDirection == ev.WheelLeft || ev.wheelDirection == ev.WheelUp) ? 1 : -1);
- QWindowSystemInterface::handleWheelEvent(0, eventPoint, eventPoint, delta, orientation);
- }
- handleMsg = false;
- }
-}
-
-void QVNCServer::keyEvent()
-{
- QRfbKeyEvent ev;
-
- if (ev.read(client)) {
- if (ev.keycode == Qt::Key_Shift)
- keymod = ev.down ? keymod | Qt::ShiftModifier :
- keymod & ~Qt::ShiftModifier;
- else if (ev.keycode == Qt::Key_Control)
- keymod = ev.down ? keymod | Qt::ControlModifier :
- keymod & ~Qt::ControlModifier;
- else if (ev.keycode == Qt::Key_Alt)
- keymod = ev.down ? keymod | Qt::AltModifier :
- keymod & ~Qt::AltModifier;
- if (ev.unicode || ev.keycode) {
-// qDebug() << "keyEvent" << hex << ev.unicode << ev.keycode << keymod << ev.down;
- QEvent::Type type = ev.down ? QEvent::KeyPress : QEvent::KeyRelease;
- QString str;
- if (ev.unicode && ev.unicode != 0xffff)
- str = QString(ev.unicode);
- QWindowSystemInterface::handleKeyEvent(0, type, ev.keycode, keymod, str);
- }
- handleMsg = false;
- }
-}
-
-void QVNCServer::clientCutText()
-{
- QRfbClientCutText ev;
-
- if (cutTextPending == 0 && ev.read(client)) {
- cutTextPending = ev.length;
- if (!cutTextPending)
- handleMsg = false;
- }
-
- if (cutTextPending && client->bytesAvailable() >= cutTextPending) {
- char *text = new char [cutTextPending+1];
- client->read(text, cutTextPending);
- delete [] text;
- cutTextPending = 0;
- handleMsg = false;
- }
-}
-
-// stride in bytes
-template <class SRC>
-bool QRfbSingleColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const int depth = encoder->server->screen()->depth();
- if (width % (depth / 8)) // hw: should rather fallback to simple loop
- return false;
-
- static int alwaysFalse = qgetenv("QT_VNC_NOCHECKFILL").toInt();
- if (alwaysFalse)
- return false;
-
- switch (depth) {
- case 4: {
- const quint8 *data8 = reinterpret_cast<const quint8*>(data);
- if ((data8[0] & 0xf) != (data8[0] >> 4))
- return false;
- width /= 2;
- } // fallthrough
- case 8: {
- const quint8 *data8 = reinterpret_cast<const quint8*>(data);
- if (data8[0] != data8[1])
- return false;
- width /= 2;
- } // fallthrough
- case 12:
- case 15:
- case 16: {
- const quint16 *data16 = reinterpret_cast<const quint16*>(data);
- if (data16[0] != data16[1])
- return false;
- width /= 2;
- } // fallthrough
- case 18:
- case 24:
- case 32: {
- const quint32 *data32 = reinterpret_cast<const quint32*>(data);
- const quint32 first = data32[0];
- const int linestep = (stride / sizeof(quint32)) - width;
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- if (*(data32++) != first)
- return false;
- }
- data32 += linestep;
- }
- break;
- }
- default:
- return false;
- }
-
- SRC color = reinterpret_cast<const SRC*>(data)[0];
- encoder->newBg |= (color != encoder->bg);
- encoder->bg = color;
- return true;
-}
-
-template <class SRC>
-void QRfbSingleColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- if (true || encoder->newBg) {
- const int bpp = encoder->server->clientBytesPerPixel();
- const int padding = 3;
- QVarLengthArray<char> buffer(padding + 1 + bpp);
- buffer[padding] = 2; // BackgroundSpecified
- encoder->server->convertPixels(buffer.data() + padding + 1,
- reinterpret_cast<char*>(&encoder->bg),
- 1);
- socket->write(buffer.data() + padding, bpp + 1);
-// encoder->newBg = false;
- } else {
- char subenc = 0;
- socket->write(&subenc, 1);
- }
-}
-
-template <class SRC>
-bool QRfbDualColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const SRC *ptr = reinterpret_cast<const SRC*>(data);
- const int linestep = (stride / sizeof(SRC)) - width;
-
- SRC c1;
- SRC c2 = 0;
- int n1 = 0;
- int n2 = 0;
- int x = 0;
- int y = 0;
-
- c1 = *ptr;
-
- // find second color
- while (y < height) {
- while (x < width) {
- if (*ptr == c1) {
- ++n1;
- } else {
- c2 = *ptr;
- goto found_second_color;
- }
- ++ptr;
- ++x;
- }
- x = 0;
- ptr += linestep;
- ++y;
- }
-
-found_second_color:
- // finish counting
- while (y < height) {
- while (x < width) {
- if (*ptr == c1) {
- ++n1;
- } else if (*ptr == c2) {
- ++n2;
- } else {
- return false;
- }
- ++ptr;
- ++x;
- }
- x = 0;
- ptr += linestep;
- ++y;
- }
-
- if (n2 > n1) {
- const quint32 tmpC = c1;
- c1 = c2;
- c2 = tmpC;
- }
-
- encoder->newBg |= (c1 != encoder->bg);
- encoder->newFg |= (c2 != encoder->fg);
-
- encoder->bg = c1;
- encoder->fg = c2;
-
- // create map
- bool inRect = false;
- numRects = 0;
- ptr = reinterpret_cast<const SRC*>(data);
- for (y = 0; y < height; ++y) {
- for (x = 0; x < width; ++x) {
- if (inRect && *ptr == encoder->bg) {
- // rect finished
- setWidth(x - lastx());
- next();
- inRect = false;
- } else if (!inRect && *ptr == encoder->fg) {
- // rect start
- setX(x);
- setY(y);
- setHeight(1);
- inRect = true;
- }
- ++ptr;
- }
- if (inRect) {
- // finish rect
- setWidth(width - lastx());
- next();
- inRect = false;
- }
- ptr += linestep;
- }
-
- return true;
-}
-
-template <class SRC>
-void QRfbDualColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- const int bpp = encoder->server->clientBytesPerPixel();
- const int padding = 3;
- QVarLengthArray<char> buffer(padding + 2 * bpp + sizeof(char) + sizeof(numRects));
- char &subenc = buffer[padding];
- int n = padding + sizeof(subenc);
-
- subenc = 0x8; // AnySubrects
-
- if (encoder->newBg) {
- subenc |= 0x2; // Background
- encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->bg, 1);
- n += bpp;
-// encoder->newBg = false;
- }
-
- if (encoder->newFg) {
- subenc |= 0x4; // Foreground
- encoder->server->convertPixels(buffer.data() + n, (char*)&encoder->fg, 1);
- n += bpp;
-// encoder->newFg = false;
- }
- buffer[n] = numRects;
- n += sizeof(numRects);
-
- socket->write(buffer.data() + padding, n - padding);
- socket->write((char*)rects, numRects * sizeof(Rect));
-}
-
-template <class SRC>
-void QRfbDualColorHextile<SRC>::next()
-{
- for (int r = numRects - 1; r >= 0; --r) {
- if (recty(r) == lasty())
- continue;
- if (recty(r) < lasty() - 1) // only search previous scanline
- break;
- if (rectx(r) == lastx() && width(r) == width(numRects)) {
- ++rects[r].wh;
- return;
- }
- }
- ++numRects;
-}
-
-template <class SRC>
-inline void QRfbMultiColorHextile<SRC>::setColor(SRC color)
-{
- encoder->server->convertPixels(reinterpret_cast<char*>(rect(numRects)),
- (const char*)&color, 1);
-}
-
-template <class SRC>
-inline bool QRfbMultiColorHextile<SRC>::beginRect()
-{
- if ((rects.size() + bpp + 2) > maxRectsSize)
- return false;
- rects.resize(rects.size() + bpp + 2);
- return true;
-}
-
-template <class SRC>
-inline void QRfbMultiColorHextile<SRC>::endRect()
-{
- setHeight(numRects, 1);
- ++numRects;
-}
-
-template <class SRC>
-bool QRfbMultiColorHextile<SRC>::read(const uchar *data,
- int width, int height, int stride)
-{
- const SRC *ptr = reinterpret_cast<const SRC*>(data);
- const int linestep = (stride / sizeof(SRC)) - width;
-
- bpp = encoder->server->clientBytesPerPixel();
-
- if (encoder->newBg)
- encoder->bg = ptr[0];
-
- const SRC bg = encoder->bg;
- SRC color = bg;
- bool inRect = false;
-
- numRects = 0;
- rects.clear();
-
- for (int y = 0; y < height; ++y) {
- for (int x = 0; x < width; ++x) {
- if (inRect && *ptr != color) { // end rect
- setWidth(numRects, x - rectx(numRects));
- endRect();
- inRect = false;
- }
-
- if (!inRect && *ptr != bg) { // begin rect
- if (!beginRect())
- return false;
- inRect = true;
- color = *ptr;
- setColor(color);
- setX(numRects, x);
- setY(numRects, y);
- }
- ++ptr;
- }
- if (inRect) { // end rect
- setWidth(numRects, width - rectx(numRects));
- endRect();
- inRect = false;
- }
- ptr += linestep;
- }
-
- return true;
-}
-
-template <class SRC>
-void QRfbMultiColorHextile<SRC>::write(QTcpSocket *socket) const
-{
- const int padding = 3;
- QVarLengthArray<quint8> buffer(bpp + padding + sizeof(quint8) + sizeof(numRects));
-
- quint8 &subenc = buffer[padding];
- int n = padding + sizeof(quint8);
-
- subenc = 8 | 16; // AnySubrects | SubrectsColoured
-
- if (encoder->newBg) {
- subenc |= 0x2; // Background
- encoder->server->convertPixels(reinterpret_cast<char*>(buffer.data() + n),
- reinterpret_cast<const char*>(&encoder->bg),
- 1);
- n += bpp;
-// encoder->newBg = false;
- }
-
- buffer[n] = numRects;
- n += sizeof(numRects);
-
- socket->write(reinterpret_cast<const char*>(buffer.data() + padding),
- n - padding);
- socket->write(reinterpret_cast<const char*>(rects.constData()),
- rects.size());
-}
-
-bool QVNCServer::pixelConversionNeeded() const
-{
- if (!sameEndian)
- return true;
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (qvnc_screen->swapBytes())
- return true;
-#endif
-
- const int screendepth = qvnc_screen->depth();
- if (screendepth != pixelFormat.bitsPerPixel)
- return true;
-
- switch (screendepth) {
- case 32:
- case 24:
- return false;
- case 18:
- return (pixelFormat.redBits == 6
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 6);
- case 16:
- return (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 5);
- case 15:
- return (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 5
- && pixelFormat.blueBits == 5);
- case 12:
- return (pixelFormat.redBits == 4
- && pixelFormat.greenBits == 4
- && pixelFormat.blueBits == 4);
- }
- return true;
-}
-
-// count: number of pixels
-void QVNCServer::convertPixels(char *dst, const char *src, int count) const
-{
- const int screendepth = qvnc_screen->depth();
- const bool isBgr = false; //### qvnc_screen->pixelType() == QScreen::BGRPixel;
-
- // cutoffs
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (!swapBytes)
-#endif
- if (sameEndian) {
- if (screendepth == pixelFormat.bitsPerPixel) { // memcpy cutoffs
-
- switch (screendepth) {
- case 32:
- memcpy(dst, src, count * sizeof(quint32));
- return;
- case 16:
- if (pixelFormat.redBits == 5
- && pixelFormat.greenBits == 6
- && pixelFormat.blueBits == 5)
- {
- memcpy(dst, src, count * sizeof(quint16));
- return;
- }
- }
- } else if (screendepth == 16 && pixelFormat.bitsPerPixel == 32) {
-#if defined(__i386__) // Currently fails on ARM if dst is not 4 byte aligned
- const quint32 *src32 = reinterpret_cast<const quint32*>(src);
- quint32 *dst32 = reinterpret_cast<quint32*>(dst);
- int count32 = count * sizeof(quint16) / sizeof(quint32);
- while (count32--) {
- const quint32 s = *src32++;
- quint32 result1;
- quint32 result2;
-
- // red
- result1 = ((s & 0xf8000000) | ((s & 0xe0000000) >> 5)) >> 8;
- result2 = ((s & 0x0000f800) | ((s & 0x0000e000) >> 5)) << 8;
-
- // green
- result1 |= ((s & 0x07e00000) | ((s & 0x06000000) >> 6)) >> 11;
- result2 |= ((s & 0x000007e0) | ((s & 0x00000600) >> 6)) << 5;
-
- // blue
- result1 |= ((s & 0x001f0000) | ((s & 0x001c0000) >> 5)) >> 13;
- result2 |= ((s & 0x0000001f) | ((s & 0x0000001c) >> 5)) << 3;
-
- *dst32++ = result2;
- *dst32++ = result1;
- }
- if (count & 0x1) {
- const quint16 *src16 = reinterpret_cast<const quint16*>(src);
- *dst32 = qt_conv16ToRgb(src16[count - 1]);
- }
- return;
-#endif
- }
- }
-
- const int bytesPerPixel = (pixelFormat.bitsPerPixel + 7) / 8;
-
-// nibble = 0;
-
- for (int i = 0; i < count; ++i) {
- int r, g, b;
-
- switch (screendepth) {
-#if 0
- case 4: {
- if (!nibble) {
- r = ((*src) & 0x0f) << 4;
- } else {
- r = (*src) & 0xf0;
- src++;
- }
- nibble = !nibble;
- g = b = r;
- break;
- }
-#endif
-#if 0
- case 8: {
- QRgb rgb = qvnc_screen->clut()[int(*src)];
- r = qRed(rgb);
- g = qGreen(rgb);
- b = qBlue(rgb);
- src++;
- break;
- }
-#endif
-#ifdef QT_QWS_DEPTH_12
- case 12: {
- quint32 p = quint32(*reinterpret_cast<const qrgb444*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb444);
- break;
- }
-#endif
-#ifdef QT_QWS_DEPTH_15
- case 15: {
- quint32 p = quint32(*reinterpret_cast<const qrgb555*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb555);
- break;
- }
-#endif
- case 16: {
- quint16 p = *reinterpret_cast<const quint16*>(src);
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (swapBytes)
- p = ((p & 0xff) << 8) | ((p & 0xff00) >> 8);
-#endif
- r = (p >> 11) & 0x1f;
- g = (p >> 5) & 0x3f;
- b = p & 0x1f;
- r <<= 3;
- g <<= 2;
- b <<= 3;
- src += sizeof(quint16);
- break;
- }
-#ifdef QT_QWS_DEPTH_18
- case 18: {
- quint32 p = quint32(*reinterpret_cast<const qrgb666*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb666);
- break;
- }
-#endif
-#ifdef QT_QWS_DEPTH_24
- case 24: {
- quint32 p = quint32(*reinterpret_cast<const qrgb888*>(src));
- r = qRed(p);
- g = qGreen(p);
- b = qBlue(p);
- src += sizeof(qrgb888);
- break;
- }
-#endif
- case 32: {
- quint32 p = *reinterpret_cast<const quint32*>(src);
- r = (p >> 16) & 0xff;
- g = (p >> 8) & 0xff;
- b = p & 0xff;
- src += sizeof(quint32);
- break;
- }
- default: {
- r = g = b = 0;
- qDebug("QVNCServer: don't support %dbpp display", screendepth);
- return;
- }
- }
-
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- if (swapBytes ^ isBgr)
-#else
- if (isBgr)
-#endif
- qSwap(r, b);
-
- r >>= (8 - pixelFormat.redBits);
- g >>= (8 - pixelFormat.greenBits);
- b >>= (8 - pixelFormat.blueBits);
-
- int pixel = (r << pixelFormat.redShift) |
- (g << pixelFormat.greenShift) |
- (b << pixelFormat.blueShift);
-
- if (sameEndian || pixelFormat.bitsPerPixel == 8) {
- memcpy(dst, &pixel, bytesPerPixel); // XXX: do a simple for-loop instead?
- dst += bytesPerPixel;
- continue;
- }
-
-
- if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
- switch (pixelFormat.bitsPerPixel) {
- case 16:
- pixel = (((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- case 32:
- pixel = (((pixel & 0xff000000) >> 24) |
- ((pixel & 0x00ff0000) >> 8) |
- ((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- default:
- qDebug("Cannot handle %d bpp client", pixelFormat.bitsPerPixel);
- }
- } else { // QSysInfo::ByteOrder == QSysInfo::LittleEndian
- switch (pixelFormat.bitsPerPixel) {
- case 16:
- pixel = (((pixel & 0xff000000) >> 8) |
- ((pixel & 0x00ff0000) << 8));
- break;
- case 32:
- pixel = (((pixel & 0xff000000) >> 24) |
- ((pixel & 0x00ff0000) >> 8) |
- ((pixel & 0x0000ff00) << 8) |
- ((pixel & 0x000000ff) << 24));
- break;
- default:
- qDebug("Cannot handle %d bpp client",
- pixelFormat.bitsPerPixel);
- break;
- }
- }
- memcpy(dst, &pixel, bytesPerPixel); // XXX: simple for-loop instead?
- dst += bytesPerPixel;
- }
-}
-
-#ifndef QT_NO_QWS_CURSOR
-static void blendCursor(QImage &image, const QRect &imageRect)
-{
- const QRect cursorRect = qt_screencursor->boundingRect();
- const QRect intersection = (cursorRect & imageRect);
- const QRect destRect = intersection.translated(-imageRect.topLeft());
- const QRect srcRect = intersection.translated(-cursorRect.topLeft());
-
- QPainter painter(&image);
- painter.drawImage(destRect, qt_screencursor->image(), srcRect);
- painter.end();
-}
-#endif // QT_NO_QWS_CURSOR
-
-QVNCDirtyMap::QVNCDirtyMap(QVNCScreen *s)
- : bytesPerPixel(0), numDirty(0), screen(s)
-{
- bytesPerPixel = (screen->depth() + 7) / 8;
- QSize screenSize = screen->geometry().size();
- bufferWidth = screenSize.width();
- bufferHeight = screenSize.height();
- bufferStride = bufferWidth * bytesPerPixel;
- buffer = new uchar[bufferHeight * bufferStride];
-
- mapWidth = (bufferWidth + MAP_TILE_SIZE - 1) / MAP_TILE_SIZE;
- mapHeight = (bufferHeight + MAP_TILE_SIZE - 1) / MAP_TILE_SIZE;
- numTiles = mapWidth * mapHeight;
- map = new uchar[numTiles];
-}
-
-QVNCDirtyMap::~QVNCDirtyMap()
-{
- delete[] map;
- delete[] buffer;
-}
-
-void QVNCDirtyMap::reset()
-{
- memset(map, 1, numTiles);
- memset(buffer, 0, bufferHeight * bufferStride);
- numDirty = numTiles;
-}
-
-inline bool QVNCDirtyMap::dirty(int x, int y) const
-{
- return map[y * mapWidth + x];
-}
-
-inline void QVNCDirtyMap::setClean(int x, int y)
-{
- map[y * mapWidth + x] = 0;
- --numDirty;
-}
-
-template <class T>
-void QVNCDirtyMapOptimized<T>::setDirty(int tileX, int tileY, bool force)
-{
- static bool alwaysForce = qgetenv("QT_VNC_NO_COMPAREBUFFER").toInt();
- if (alwaysForce)
- force = true;
-
- bool changed = false;
-
- if (!force) {
- const int lstep = screen->linestep();
- const int startX = tileX * MAP_TILE_SIZE;
- const int startY = tileY * MAP_TILE_SIZE;
- const uchar *scrn = screen->base()
- + startY * lstep + startX * bytesPerPixel;
- uchar *old = buffer + startY * bufferStride + startX * sizeof(T);
-
- const int tileHeight = (startY + MAP_TILE_SIZE > bufferHeight ?
- bufferHeight - startY : MAP_TILE_SIZE);
- const int tileWidth = (startX + MAP_TILE_SIZE > bufferWidth ?
- bufferWidth - startX : MAP_TILE_SIZE);
- const bool doInlines = (tileWidth == MAP_TILE_SIZE);
-
- int y = tileHeight;
-
- if (doInlines) { // hw: memcmp/memcpy is inlined when using constants
- while (y) {
- if (memcmp(old, scrn, sizeof(T) * MAP_TILE_SIZE)) {
- changed = true;
- break;
- }
- scrn += lstep;
- old += bufferStride;
- --y;
- }
-
- while (y) {
- memcpy(old, scrn, sizeof(T) * MAP_TILE_SIZE);
- scrn += lstep;
- old += bufferStride;
- --y;
- }
- } else {
- while (y) {
- if (memcmp(old, scrn, sizeof(T) * tileWidth)) {
- changed = true;
- break;
- }
- scrn += lstep;
- old += bufferStride;
- --y;
- }
-
- while (y) {
- memcpy(old, scrn, sizeof(T) * tileWidth);
- scrn += lstep;
- old += bufferStride;
- --y;
- }
- }
- }
-
- const int mapIndex = tileY * mapWidth + tileX;
- if ((force || changed) && !map[mapIndex]) {
- map[mapIndex] = 1;
- ++numDirty;
- }
-}
-
-template <class SRC>
-QRfbHextileEncoder<SRC>::QRfbHextileEncoder(QVNCServer *s)
- : QRfbEncoder(s),
- singleColorHextile(this), dualColorHextile(this), multiColorHextile(this)
-{
-}
-
-/*
- \internal
- Send dirty rects using hextile encoding.
-*/
-template <class SRC>
-void QRfbHextileEncoder<SRC>::write()
-{
-// QWSDisplay::grab(true);
-
- QVNCDirtyMap *map = server->dirtyMap();
- QTcpSocket *socket = server->clientSocket();
-
- const quint32 encoding = htonl(5); // hextile encoding
- const int bytesPerPixel = server->clientBytesPerPixel();
-
- {
- const char tmp[2] = { 0, 0 }; // msg type, padding
- socket->write(tmp, sizeof(tmp));
- }
- {
- const quint16 count = htons(map->numDirty);
- socket->write((char *)&count, sizeof(count));
- }
-
- if (map->numDirty <= 0) {
-// QWSDisplay::ungrab();
- return;
- }
-
- newBg = true;
- newFg = true;
-
- const QImage screenImage = server->screenImage();
- QRfbRect rect(0, 0, MAP_TILE_SIZE, MAP_TILE_SIZE);
-
- QSize screenSize = server->screen()->geometry().size();
-
- for (int y = 0; y < map->mapHeight; ++y) {
- if (rect.y + MAP_TILE_SIZE > screenSize.height())
- rect.h = screenSize.height() - rect.y;
- rect.w = MAP_TILE_SIZE;
- for (int x = 0; x < map->mapWidth; ++x) {
- if (!map->dirty(x, y))
- continue;
- map->setClean(x, y);
-
- rect.x = x * MAP_TILE_SIZE;
- if (rect.x + MAP_TILE_SIZE > screenSize.width()) //###deviceWidth ???
- rect.w = screenSize.width() - rect.x;
- rect.write(socket);
-
- socket->write((char *)&encoding, sizeof(encoding));
-
- const uchar *screendata = screenImage.scanLine(rect.y)
- + rect.x * screenImage.depth() / 8;
- int linestep = screenImage.bytesPerLine();
-
-#ifndef QT_NO_QWS_CURSOR
- // hardware cursors must be blended with the screen memory
- const bool doBlendCursor = qt_screencursor
- && !server->hasClientCursor()
- && qt_screencursor->isAccelerated();
- QImage tileImage;
- if (doBlendCursor) {
- const QRect tileRect(rect.x, rect.y, rect.w, rect.h);
- const QRect cursorRect = qt_screencursor->boundingRect()
- .translated(-server->screen()->offset());
- if (tileRect.intersects(cursorRect)) {
- tileImage = screenImage.copy(tileRect);
- blendCursor(tileImage,
- tileRect.translated(server->screen()->offset()));
- screendata = tileImage.bits();
- linestep = tileImage.bytesPerLine();
- }
- }
-#endif // QT_NO_QWS_CURSOR
-
- if (singleColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- singleColorHextile.write(socket);
- } else if (dualColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- dualColorHextile.write(socket);
- } else if (multiColorHextile.read(screendata, rect.w, rect.h, linestep)) {
- multiColorHextile.write(socket);
- } else if (server->doPixelConversion()) {
- const int bufferSize = rect.w * rect.h * bytesPerPixel + 1;
- const int padding = sizeof(quint32) - sizeof(char);
- buffer.resize(bufferSize + padding);
-
- buffer[padding] = 1; // Raw subencoding
-
- // convert pixels
- char *b = buffer.data() + padding + 1;
- const int bstep = rect.w * bytesPerPixel;
- for (int i = 0; i < rect.h; ++i) {
- server->convertPixels(b, (const char*)screendata, rect.w);
- screendata += linestep;
- b += bstep;
- }
- socket->write(buffer.constData() + padding, bufferSize);
- } else {
- quint8 subenc = 1; // Raw subencoding
- socket->write((char *)&subenc, 1);
-
- // send pixels
- for (int i = 0; i < rect.h; ++i) {
- socket->write((const char*)screendata,
- rect.w * bytesPerPixel);
- screendata += linestep;
- }
- }
- }
- if (socket->state() == QAbstractSocket::UnconnectedState)
- break;
- rect.y += MAP_TILE_SIZE;
- }
- socket->flush();
- Q_ASSERT(map->numDirty == 0);
-
-// QWSDisplay::ungrab();
-}
-
-void QRfbRawEncoder::write()
-{
-// QWSDisplay::grab(false);
-
- QVNCDirtyMap *map = server->dirtyMap();
- QTcpSocket *socket = server->clientSocket();
-
- const int bytesPerPixel = server->clientBytesPerPixel();
- QSize screenSize = server->screen()->geometry().size();
-
- // create a region from the dirty rects and send the region's merged rects.
- QRegion rgn;
- if (map) {
- for (int y = 0; y < map->mapHeight; ++y) {
- for (int x = 0; x < map->mapWidth; ++x) {
- if (!map->dirty(x, y))
- continue;
- rgn += QRect(x * MAP_TILE_SIZE, y * MAP_TILE_SIZE,
- MAP_TILE_SIZE, MAP_TILE_SIZE);
- map->setClean(x, y);
- }
- }
-
- rgn &= QRect(0, 0, screenSize.width(),
- screenSize.height());
- }
- const QVector<QRect> rects = rgn.rects();
-
- {
- const char tmp[2] = { 0, 0 }; // msg type, padding
- socket->write(tmp, sizeof(tmp));
- }
-
- {
- const quint16 count = htons(rects.size());
- socket->write((char *)&count, sizeof(count));
- }
-
- if (rects.size() <= 0) {
-// QWSDisplay::ungrab();
- return;
- }
-
- const QImage *screenImage = server->screenImage();
-
- for (int i = 0; i < rects.size(); ++i) {
- const QRect tileRect = rects.at(i);
- const QRfbRect rect(tileRect.x(), tileRect.y(),
- tileRect.width(), tileRect.height());
- rect.write(socket);
-
- const quint32 encoding = htonl(0); // raw encoding
- socket->write((char *)&encoding, sizeof(encoding));
-
- int linestep = screenImage->bytesPerLine();
- const uchar *screendata = screenImage->scanLine(rect.y)
- + rect.x * screenImage->depth() / 8;
-
-#ifndef QT_NO_QWS_CURSOR
- // hardware cursors must be blended with the screen memory
- const bool doBlendCursor = qt_screencursor
- && !server->hasClientCursor()
- && qt_screencursor->isAccelerated();
- QImage tileImage;
- if (doBlendCursor) {
- const QRect cursorRect = qt_screencursor->boundingRect()
- .translated(-server->screen()->offset());
- if (tileRect.intersects(cursorRect)) {
- tileImage = screenImage->copy(tileRect);
- blendCursor(tileImage,
- tileRect.translated(server->screen()->offset()));
- screendata = tileImage.bits();
- linestep = tileImage.bytesPerLine();
- }
- }
-#endif // QT_NO_QWS_CURSOR
-
- if (server->doPixelConversion()) {
- const int bufferSize = rect.w * rect.h * bytesPerPixel;
- if (bufferSize > buffer.size())
- buffer.resize(bufferSize);
-
- // convert pixels
- char *b = buffer.data();
- const int bstep = rect.w * bytesPerPixel;
- for (int i = 0; i < rect.h; ++i) {
- server->convertPixels(b, (const char*)screendata, rect.w);
- screendata += linestep;
- b += bstep;
- }
- socket->write(buffer.constData(), bufferSize);
- } else {
- for (int i = 0; i < rect.h; ++i) {
- socket->write((const char*)screendata, rect.w * bytesPerPixel);
- screendata += linestep;
- }
- }
- if (socket->state() == QAbstractSocket::UnconnectedState)
- break;
- }
- socket->flush();
-
-// QWSDisplay::ungrab();
-}
-
-inline QImage *QVNCServer::screenImage() const
-{
- return qvnc_screen->image();
-}
-
-void QVNCServer::checkUpdate()
-{
- if (!wantUpdate)
- return;
-
- if (dirtyCursor) {
-#ifndef QT_NO_QWS_CURSOR
- Q_ASSERT(qvnc_cursor);
- qvnc_cursor->write();
-#endif
- cursor->sendClientCursor();
- dirtyCursor = false;
- wantUpdate = false;
- return;
- }
-
- if (dirtyMap()->numDirty > 0) {
- if (encoder)
- encoder->write();
- wantUpdate = false;
- }
-}
-
-void QVNCServer::discardClient()
-{
- timer->stop();
- state = Unconnected;
- delete encoder;
- encoder = 0;
-#ifndef QT_NO_QWS_CURSOR
- delete qvnc_cursor;
- qvnc_cursor = 0;
-#endif
-// if (!qvnc_screen->screen())
-// QWSServer::instance()->enablePainting(false);
-}
-
-
-
-QVNCScreenPrivate::QVNCScreenPrivate(QVNCScreen *parent, int screenId)
- : dpiX(72), dpiY(72), doOnScreenSurface(false), refreshRate(25),
- vncServer(0), q_ptr(parent)
-{
-#if 0//ndef QT_NO_QWS_SIGNALHANDLER
- QWSSignalHandler::instance()->addObject(this);
-#endif
-
- vncServer = new QVNCServer(q_ptr, screenId);
- vncServer->setRefreshRate(refreshRate);
-
-
- Q_ASSERT(q_ptr->depth() == 32);
-
- dirty = new QVNCDirtyMapOptimized<quint32>(q_ptr);
-}
-
-QVNCScreenPrivate::~QVNCScreenPrivate()
-{
-}
-
-
-void QVNCScreenPrivate::setDirty(const QRect& rect, bool force)
-{
- if (rect.isEmpty())
- return;
-
-// if (q_ptr->screen())
-// q_ptr->screen()->setDirty(rect);
-
- if (!vncServer || !vncServer->isConnected()) {
-// qDebug() << "QVNCScreenPrivate::setDirty() - Not connected";
- return;
- }
- const QRect r = rect; // .translated(-q_ptr->offset());
- const int x1 = r.x() / MAP_TILE_SIZE;
- int y = r.y() / MAP_TILE_SIZE;
- for (; (y <= r.bottom() / MAP_TILE_SIZE) && y < dirty->mapHeight; y++)
- for (int x = x1; (x <= r.right() / MAP_TILE_SIZE) && x < dirty->mapWidth; x++)
- dirty->setDirty(x, y, force);
-
- vncServer->setDirty();
-}
-
-
-
-
-QT_END_NAMESPACE
diff --git a/src/plugins/platforms/vnc/qvncserver.h b/src/plugins/platforms/vnc/qvncserver.h
deleted file mode 100644
index e8b093764f..0000000000
--- a/src/plugins/platforms/vnc/qvncserver.h
+++ /dev/null
@@ -1,533 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/
-**
-** This file is part of the plugins of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU General
-** Public License version 3.0 as published by the Free Software Foundation
-** and appearing in the file LICENSE.GPL included in the packaging of this
-** file. Please review the following information to ensure the GNU General
-** Public License version 3.0 requirements will be met:
-** http://www.gnu.org/copyleft/gpl.html.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QSCREENVNC_P_H
-#define QSCREENVNC_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the QLibrary class. This header file may change from version to version
-// without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qvncintegration.h"
-#include "qvnccursor.h"
-#define QT_NO_QWS_CURSOR
-
-#ifndef QT_NO_QWS_VNC
-
-#include <QtCore/qvarlengtharray.h>
-#include <QtCore/qsharedmemory.h>
-#include <QtNetwork/qtcpsocket.h>
-#include <QtNetwork/qtcpserver.h>
-
-QT_BEGIN_NAMESPACE
-
-class QVNCServer;
-
-#ifndef QT_NO_QWS_CURSOR
-class QVNCCursor : public QProxyScreenCursor
-{
-public:
- QVNCCursor(QVNCScreen *s);
- ~QVNCCursor();
-
- void hide();
- void show();
- void set(const QImage &image, int hotx, int hoty);
- void move(int x, int y);
-
-private:
- void setDirty(const QRect &r) const;
- QVNCScreen *screen;
-};
-
-class QVNCClientCursor : public QProxyScreenCursor
-{
-public:
- QVNCClientCursor(QVNCServer *s);
- ~QVNCClientCursor();
-
- void set(const QImage &image, int hotx, int hoty);
- void write() const;
-
-private:
- QVNCServer *server;
-};
-#endif // QT_NO_QWS_CURSOR
-
-#define MAP_TILE_SIZE 16
-#define MAP_WIDTH 1280 / MAP_TILE_SIZE
-#define MAP_HEIGHT 1024 / MAP_TILE_SIZE
-
-class QVNCDirtyMap
-{
-public:
- QVNCDirtyMap(QVNCScreen *screen);
- virtual ~QVNCDirtyMap();
-
- void reset();
- bool dirty(int x, int y) const;
- virtual void setDirty(int x, int y, bool force = false) = 0;
- void setClean(int x, int y);
-
- int bytesPerPixel;
-
- int numDirty;
- int mapWidth;
- int mapHeight;
-
-protected:
- uchar *map;
- QVNCScreen *screen;
- uchar *buffer;
- int bufferWidth;
- int bufferHeight;
- int bufferStride;
- int numTiles;
-};
-
-template <class T>
-class QVNCDirtyMapOptimized : public QVNCDirtyMap
-{
-public:
- QVNCDirtyMapOptimized(QVNCScreen *screen) : QVNCDirtyMap(screen) {}
- ~QVNCDirtyMapOptimized() {}
-
- void setDirty(int x, int y, bool force = false);
-};
-
-class QRfbRect
-{
-public:
- QRfbRect() {}
- QRfbRect(quint16 _x, quint16 _y, quint16 _w, quint16 _h) {
- x = _x; y = _y; w = _w; h = _h;
- }
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s) const;
-
- quint16 x;
- quint16 y;
- quint16 w;
- quint16 h;
-};
-
-class QRfbPixelFormat
-{
-public:
- static int size() { return 16; }
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s);
-
- int bitsPerPixel;
- int depth;
- bool bigEndian;
- bool trueColor;
- int redBits;
- int greenBits;
- int blueBits;
- int redShift;
- int greenShift;
- int blueShift;
-};
-
-class QRfbServerInit
-{
-public:
- QRfbServerInit() { name = 0; }
- ~QRfbServerInit() { delete[] name; }
-
- int size() const { return QRfbPixelFormat::size() + 8 + strlen(name); }
- void setName(const char *n);
-
- void read(QTcpSocket *s);
- void write(QTcpSocket *s);
-
- quint16 width;
- quint16 height;
- QRfbPixelFormat format;
- char *name;
-};
-
-class QRfbSetEncodings
-{
-public:
- bool read(QTcpSocket *s);
-
- quint16 count;
-};
-
-class QRfbFrameBufferUpdateRequest
-{
-public:
- bool read(QTcpSocket *s);
-
- char incremental;
- QRfbRect rect;
-};
-
-class QRfbKeyEvent
-{
-public:
- bool read(QTcpSocket *s);
-
- char down;
- int keycode;
- int unicode;
-};
-
-class QRfbPointerEvent
-{
-public:
- bool read(QTcpSocket *s);
-
- Qt::MouseButtons buttons;
- enum { WheelNone,
- WheelUp,
- WheelDown,
- WheelLeft,
- WheelRight
- } wheelDirection;
- quint16 x;
- quint16 y;
-};
-
-class QRfbClientCutText
-{
-public:
- bool read(QTcpSocket *s);
-
- quint32 length;
-};
-
-class QVNCScreenPrivate : public QObject
-{
-public:
- QVNCScreenPrivate(QVNCScreen *parent, int screenId);
- ~QVNCScreenPrivate();
-
- void setDirty(const QRect &rect, bool force = false);
- void configure();
-
- qreal dpiX;
- qreal dpiY;
- bool doOnScreenSurface;
- QVNCDirtyMap *dirty;
- int refreshRate;
- QVNCServer *vncServer;
-
-#if !defined(QT_NO_SHAREDMEMORY)
- QSharedMemory shm;
-#endif
-
- QVNCScreen *q_ptr;
-};
-
-class QRfbEncoder
-{
-public:
- QRfbEncoder(QVNCServer *s) : server(s) {}
- virtual ~QRfbEncoder() {}
-
- virtual void write() = 0;
-
-protected:
- QVNCServer *server;
-};
-
-class QRfbRawEncoder : public QRfbEncoder
-{
-public:
- QRfbRawEncoder(QVNCServer *s) : QRfbEncoder(s) {}
-
- void write();
-
-private:
- QByteArray buffer;
-};
-
-template <class SRC> class QRfbHextileEncoder;
-
-template <class SRC>
-class QRfbSingleColorHextile
-{
-public:
- QRfbSingleColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- QRfbHextileEncoder<SRC> *encoder;
-};
-
-template <class SRC>
-class QRfbDualColorHextile
-{
-public:
- QRfbDualColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- struct Rect {
- quint8 xy;
- quint8 wh;
- } Q_PACKED rects[8 * 16];
-
- quint8 numRects;
- QRfbHextileEncoder<SRC> *encoder;
-
-private:
- inline int lastx() const { return rectx(numRects); }
- inline int lasty() const { return recty(numRects); }
- inline int rectx(int r) const { return rects[r].xy >> 4; }
- inline int recty(int r) const { return rects[r].xy & 0x0f; }
- inline int width(int r) const { return (rects[r].wh >> 4) + 1; }
- inline int height(int r) const { return (rects[r].wh & 0x0f) + 1; }
-
- inline void setX(int r, int x) {
- rects[r].xy = (x << 4) | (rects[r].xy & 0x0f);
- }
- inline void setY(int r, int y) {
- rects[r].xy = (rects[r].xy & 0xf0) | y;
- }
- inline void setWidth(int r, int width) {
- rects[r].wh = ((width - 1) << 4) | (rects[r].wh & 0x0f);
- }
- inline void setHeight(int r, int height) {
- rects[r].wh = (rects[r].wh & 0xf0) | (height - 1);
- }
-
- inline void setWidth(int width) { setWidth(numRects, width); }
- inline void setHeight(int height) { setHeight(numRects, height); }
- inline void setX(int x) { setX(numRects, x); }
- inline void setY(int y) { setY(numRects, y); }
- void next();
-};
-
-template <class SRC>
-class QRfbMultiColorHextile
-{
-public:
- QRfbMultiColorHextile(QRfbHextileEncoder<SRC> *e) : encoder(e) {}
- bool read(const uchar *data, int width, int height, int stride);
- void write(QTcpSocket *socket) const;
-
-private:
- inline quint8* rect(int r) {
- return rects.data() + r * (bpp + 2);
- }
- inline const quint8* rect(int r) const {
- return rects.constData() + r * (bpp + 2);
- }
- inline void setX(int r, int x) {
- quint8 *ptr = rect(r) + bpp;
- *ptr = (x << 4) | (*ptr & 0x0f);
- }
- inline void setY(int r, int y) {
- quint8 *ptr = rect(r) + bpp;
- *ptr = (*ptr & 0xf0) | y;
- }
- void setColor(SRC color);
- inline int rectx(int r) const {
- const quint8 *ptr = rect(r) + bpp;
- return *ptr >> 4;
- }
- inline int recty(int r) const {
- const quint8 *ptr = rect(r) + bpp;
- return *ptr & 0x0f;
- }
- inline void setWidth(int r, int width) {
- quint8 *ptr = rect(r) + bpp + 1;
- *ptr = ((width - 1) << 4) | (*ptr & 0x0f);
- }
- inline void setHeight(int r, int height) {
- quint8 *ptr = rect(r) + bpp + 1;
- *ptr = (*ptr & 0xf0) | (height - 1);
- }
-
- bool beginRect();
- void endRect();
-
- static const int maxRectsSize = 16 * 16;
- QVarLengthArray<quint8, maxRectsSize> rects;
-
- quint8 bpp;
- quint8 numRects;
- QRfbHextileEncoder<SRC> *encoder;
-};
-
-template <class SRC>
-class QRfbHextileEncoder : public QRfbEncoder
-{
-public:
- QRfbHextileEncoder(QVNCServer *s);
- void write();
-
-private:
- enum SubEncoding {
- Raw = 1,
- BackgroundSpecified = 2,
- ForegroundSpecified = 4,
- AnySubrects = 8,
- SubrectsColoured = 16
- };
-
- QByteArray buffer;
- QRfbSingleColorHextile<SRC> singleColorHextile;
- QRfbDualColorHextile<SRC> dualColorHextile;
- QRfbMultiColorHextile<SRC> multiColorHextile;
-
- SRC bg;
- SRC fg;
- bool newBg;
- bool newFg;
-
- friend class QRfbSingleColorHextile<SRC>;
- friend class QRfbDualColorHextile<SRC>;
- friend class QRfbMultiColorHextile<SRC>;
-};
-
-class QVNCServer : public QObject
-{
- Q_OBJECT
-public:
- QVNCServer(QVNCScreen *screen);
- QVNCServer(QVNCScreen *screen, int id);
- ~QVNCServer();
-
- void setDirty();
- void setDirtyCursor() { dirtyCursor = true; setDirty(); }
- inline bool isConnected() const { return state == Connected; }
- inline void setRefreshRate(int rate) { refreshRate = rate; }
-
- enum ClientMsg { SetPixelFormat = 0,
- FixColourMapEntries = 1,
- SetEncodings = 2,
- FramebufferUpdateRequest = 3,
- KeyEvent = 4,
- PointerEvent = 5,
- ClientCutText = 6 };
-
- enum ServerMsg { FramebufferUpdate = 0,
- SetColourMapEntries = 1 };
-
- void convertPixels(char *dst, const char *src, int count) const;
-
- inline int clientBytesPerPixel() const {
- return pixelFormat.bitsPerPixel / 8;
- }
-
- inline QVNCScreen* screen() const { return qvnc_screen; }
- inline QVNCDirtyMap* dirtyMap() const { return qvnc_screen->dirtyMap(); }
- inline QTcpSocket* clientSocket() const { return client; }
- QImage *screenImage() const;
- inline bool doPixelConversion() const { return needConversion; }
-#ifndef QT_NO_QWS_CURSOR
- inline bool hasClientCursor() const { return qvnc_cursor != 0; }
-#endif
-
- void setCursor(QVNCCursor * c) { cursor = c; }
-private:
- void setPixelFormat();
- void setEncodings();
- void frameBufferUpdateRequest();
- void pointerEvent();
- void keyEvent();
- void clientCutText();
- bool pixelConversionNeeded() const;
-
-private slots:
- void newConnection();
- void readClient();
- void checkUpdate();
- void discardClient();
-
-private:
- void init(uint port);
- enum ClientState { Unconnected, Protocol, Init, Connected };
- QTimer *timer;
- QTcpServer *serverSocket;
- QTcpSocket *client;
- ClientState state;
- quint8 msgType;
- bool handleMsg;
- QRfbPixelFormat pixelFormat;
- Qt::KeyboardModifiers keymod;
- Qt::MouseButtons buttons;
- int encodingsPending;
- int cutTextPending;
- uint supportCopyRect : 1;
- uint supportRRE : 1;
- uint supportCoRRE : 1;
- uint supportHextile : 1;
- uint supportZRLE : 1;
- uint supportCursor : 1;
- uint supportDesktopSize : 1;
- bool wantUpdate;
- bool sameEndian;
- bool needConversion;
-#if Q_BYTE_ORDER == Q_BIG_ENDIAN
- bool swapBytes;
-#endif
- bool dirtyCursor;
- int refreshRate;
- QVNCScreen *qvnc_screen;
-#ifndef QT_NO_QWS_CURSOR
- QVNCClientCursor *qvnc_cursor;
-#endif
-
- QRfbEncoder *encoder;
- QVNCCursor *cursor;
-};
-
-
-QT_END_NAMESPACE
-#endif // QT_NO_QWS_VNC
-#endif // QSCREENVNC_P_H
diff --git a/src/plugins/platforms/vnc/vnc.pro b/src/plugins/platforms/vnc/vnc.pro
deleted file mode 100644
index 637ed82385..0000000000
--- a/src/plugins/platforms/vnc/vnc.pro
+++ /dev/null
@@ -1,22 +0,0 @@
-TARGET = qvncgraphicssystem
-load(qt_plugin)
-
-QT += network core-private gui-private platformsupport-private
-
-DESTDIR = $$QT.gui.plugins/platforms
-
-SOURCES = main.cpp qvncintegration.cpp
-HEADERS = qvncintegration.h
-
-HEADERS += qvncserver.h
-SOURCES += qvncserver.cpp
-
-HEADERS += qvnccursor.h
-SOURCES += qvnccursor.cpp
-
-include(../fb_base/fb_base.pri)
-CONFIG += qpa/genericunixfontdatabase
-
-target.path += $$[QT_INSTALL_PLUGINS]/platforms
-
-INSTALLS += target
diff --git a/src/plugins/platforms/windows/accessible/accessible.pri b/src/plugins/platforms/windows/accessible/accessible.pri
new file mode 100644
index 0000000000..1671c67d17
--- /dev/null
+++ b/src/plugins/platforms/windows/accessible/accessible.pri
@@ -0,0 +1,19 @@
+SOURCES += \
+ $$PWD/qwindowsaccessibility.cpp
+
+HEADERS += \
+ $$PWD/qwindowsaccessibility.h
+
+!*g++* {
+ SOURCES += \
+ $$PWD/qwindowsmsaaaccessible.cpp \
+ $$PWD/iaccessible2.cpp \
+ $$PWD/comutils.cpp
+
+ HEADERS += \
+ $$PWD/qwindowsmsaaaccessible.h \
+ $$PWD/iaccessible2.h \
+ $$PWD/comutils.h
+
+ include(../../../../3rdparty/iaccessible2/iaccessible2.pri)
+} # !g++
diff --git a/src/plugins/platforms/windows/accessible/comutils.cpp b/src/plugins/platforms/windows/accessible/comutils.cpp
new file mode 100644
index 0000000000..9a0fce20b8
--- /dev/null
+++ b/src/plugins/platforms/windows/accessible/comutils.cpp
@@ -0,0 +1,641 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <ocidl.h>
+#include <olectl.h>
+
+#include "comutils.h"
+#include <QtCore/qdatetime.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qfont.h>
+
+
+#include <QtCore/qvariant.h>
+#include <QtCore/qbytearray.h>
+#include <QtGui/qcolor.h>
+
+static DATE QDateTimeToDATE(const QDateTime &dt)
+{
+ if (!dt.isValid() || dt.isNull())
+ return 949998; // Special value for no date (01/01/4501)
+
+ SYSTEMTIME stime;
+ memset(&stime, 0, sizeof(stime));
+ QDate date = dt.date();
+ QTime time = dt.time();
+ if (date.isValid() && !date.isNull()) {
+ stime.wDay = date.day();
+ stime.wMonth = date.month();
+ stime.wYear = date.year();
+ }
+ if (time.isValid() && !time.isNull()) {
+ stime.wMilliseconds = time.msec();
+ stime.wSecond = time.second();
+ stime.wMinute = time.minute();
+ stime.wHour = time.hour();
+ }
+
+ double vtime;
+ SystemTimeToVariantTime(&stime, &vtime);
+
+ return vtime;
+}
+
+inline uint QColorToOLEColor(const QColor &col)
+{
+ return qRgba(col.blue(), col.green(), col.red(), 0x00);
+}
+
+bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out)
+{
+ QVariant qvar = var;
+ // "type" is the expected type, so coerce if necessary
+ QVariant::Type proptype = typeName.isEmpty() ? QVariant::Invalid : QVariant::nameToType(typeName);
+ if (proptype == QVariant::UserType && !typeName.isEmpty()) {
+ if (typeName == "short" || typeName == "char")
+ proptype = QVariant::Int;
+ else if (typeName == "float")
+ proptype = QVariant::Double;
+ }
+ if (proptype != QVariant::Invalid && proptype != QVariant::UserType && proptype != qvar.type()) {
+ if (qvar.canConvert(proptype))
+ qvar.convert(proptype);
+ else
+ qvar = QVariant(proptype);
+ }
+
+ if (out && arg.vt == (VT_VARIANT|VT_BYREF) && arg.pvarVal) {
+ return QVariantToVARIANT(var, *arg.pvarVal, typeName, false);
+ }
+
+ if (out && proptype == QVariant::UserType && typeName == "QVariant") {
+ VARIANT *pVariant = new VARIANT;
+ QVariantToVARIANT(var, *pVariant, QByteArray(), false);
+ arg.vt = VT_VARIANT|VT_BYREF;
+ arg.pvarVal = pVariant;
+ return true;
+ }
+
+ switch ((int)qvar.type()) {
+ case QVariant::String:
+ if (out && arg.vt == (VT_BSTR|VT_BYREF)) {
+ if (*arg.pbstrVal)
+ SysFreeString(*arg.pbstrVal);
+ *arg.pbstrVal = QStringToBSTR(qvar.toString());
+ arg.vt = VT_BSTR|VT_BYREF;
+ } else {
+ arg.vt = VT_BSTR;
+ arg.bstrVal = QStringToBSTR(qvar.toString());
+ if (out) {
+ arg.pbstrVal = new BSTR(arg.bstrVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::Int:
+ if (out && arg.vt == (VT_I4|VT_BYREF)) {
+ *arg.plVal = qvar.toInt();
+ } else {
+ arg.vt = VT_I4;
+ arg.lVal = qvar.toInt();
+ if (out) {
+ if (typeName == "short") {
+ arg.vt = VT_I2;
+ arg.piVal = new short(arg.lVal);
+ } else if (typeName == "char") {
+ arg.vt = VT_I1;
+ arg.pcVal= new char(arg.lVal);
+ } else {
+ arg.plVal = new long(arg.lVal);
+ }
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::UInt:
+ if (out && (arg.vt == (VT_UINT|VT_BYREF) || arg.vt == (VT_I4|VT_BYREF))) {
+ *arg.puintVal = qvar.toUInt();
+ } else {
+ arg.vt = VT_UINT;
+ arg.uintVal = qvar.toUInt();
+ if (out) {
+ arg.puintVal = new uint(arg.uintVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::LongLong:
+ if (out && arg.vt == (VT_CY|VT_BYREF)) {
+ arg.pcyVal->int64 = qvar.toLongLong();
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ } else if (out && arg.vt == (VT_I8|VT_BYREF)) {
+ *arg.pllVal = qvar.toLongLong();
+ } else {
+ arg.vt = VT_I8;
+ arg.llVal = qvar.toLongLong();
+ if (out) {
+ arg.pllVal = new LONGLONG(arg.llVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#else
+ } else {
+ arg.vt = VT_CY;
+ arg.cyVal.int64 = qvar.toLongLong();
+ if (out) {
+ arg.pcyVal = new CY(arg.cyVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#endif
+ break;
+
+ case QVariant::ULongLong:
+ if (out && arg.vt == (VT_CY|VT_BYREF)) {
+ arg.pcyVal->int64 = qvar.toULongLong();
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ } else if (out && arg.vt == (VT_UI8|VT_BYREF)) {
+ *arg.pullVal = qvar.toULongLong();
+ } else {
+ arg.vt = VT_UI8;
+ arg.ullVal = qvar.toULongLong();
+ if (out) {
+ arg.pullVal = new ULONGLONG(arg.ullVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#else
+ } else {
+ arg.vt = VT_CY;
+ arg.cyVal.int64 = qvar.toULongLong();
+ if (out) {
+ arg.pcyVal = new CY(arg.cyVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+
+#endif
+
+ break;
+
+ case QVariant::Bool:
+ if (out && arg.vt == (VT_BOOL|VT_BYREF)) {
+ *arg.pboolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE;
+ } else {
+ arg.vt = VT_BOOL;
+ arg.boolVal = qvar.toBool() ? VARIANT_TRUE : VARIANT_FALSE;
+ if (out) {
+ arg.pboolVal = new short(arg.boolVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+ case QVariant::Double:
+ if (out && arg.vt == (VT_R8|VT_BYREF)) {
+ *arg.pdblVal = qvar.toDouble();
+ } else {
+ arg.vt = VT_R8;
+ arg.dblVal = qvar.toDouble();
+ if (out) {
+ if (typeName == "float") {
+ arg.vt = VT_R4;
+ arg.pfltVal = new float(arg.dblVal);
+ } else {
+ arg.pdblVal = new double(arg.dblVal);
+ }
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+ case QVariant::Color:
+ if (out && arg.vt == (VT_COLOR|VT_BYREF)) {
+
+ *arg.plVal = QColorToOLEColor(qvariant_cast<QColor>(qvar));
+ } else {
+ arg.vt = VT_COLOR;
+ arg.lVal = QColorToOLEColor(qvariant_cast<QColor>(qvar));
+ if (out) {
+ arg.plVal = new long(arg.lVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ case QVariant::Date:
+ case QVariant::Time:
+ case QVariant::DateTime:
+ if (out && arg.vt == (VT_DATE|VT_BYREF)) {
+ *arg.pdate = QDateTimeToDATE(qvar.toDateTime());
+ } else {
+ arg.vt = VT_DATE;
+ arg.date = QDateTimeToDATE(qvar.toDateTime());
+ if (out) {
+ arg.pdate = new DATE(arg.date);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+#if 0 // not a value with min/max semantics
+ case QVariant::Font:
+ if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
+ if (*arg.ppdispVal)
+ (*arg.ppdispVal)->Release();
+ *arg.ppdispVal = QFontToIFont(qvariant_cast<QFont>(qvar));
+ } else {
+ arg.vt = VT_DISPATCH;
+ arg.pdispVal = QFontToIFont(qvariant_cast<QFont>(qvar));
+ if (out) {
+ arg.ppdispVal = new IDispatch*(arg.pdispVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+ case QVariant::Pixmap:
+ if (out && arg.vt == (VT_DISPATCH|VT_BYREF)) {
+ if (*arg.ppdispVal)
+ (*arg.ppdispVal)->Release();
+ *arg.ppdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar));
+ } else {
+ arg.vt = VT_DISPATCH;
+ arg.pdispVal = QPixmapToIPicture(qvariant_cast<QPixmap>(qvar));
+ if (out) {
+ arg.ppdispVal = new IDispatch*(arg.pdispVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+ case QVariant::Cursor:
+ {
+#ifndef QT_NO_CURSOR
+ int shape = qvariant_cast<QCursor>(qvar).shape();
+ if (out && (arg.vt & VT_BYREF)) {
+ switch (arg.vt & ~VT_BYREF) {
+ case VT_I4:
+ *arg.plVal = shape;
+ break;
+ case VT_I2:
+ *arg.piVal = shape;
+ break;
+ case VT_UI4:
+ *arg.pulVal = shape;
+ break;
+ case VT_UI2:
+ *arg.puiVal = shape;
+ break;
+ case VT_INT:
+ *arg.pintVal = shape;
+ break;
+ case VT_UINT:
+ *arg.puintVal = shape;
+ break;
+ }
+ } else {
+ arg.vt = VT_I4;
+ arg.lVal = shape;
+ if (out) {
+ arg.plVal = new long(arg.lVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+#endif
+ }
+ break;
+
+ case QVariant::List:
+ {
+ const QList<QVariant> list = qvar.toList();
+ const int count = list.count();
+ VARTYPE vt = VT_VARIANT;
+ QVariant::Type listType = QVariant::LastType; // == QVariant
+ if (!typeName.isEmpty() && typeName.startsWith("QList<")) {
+ const QByteArray listTypeName = typeName.mid(6, typeName.length() - 7); // QList<int> -> int
+ listType = QVariant::nameToType(listTypeName);
+ }
+
+ VARIANT variant;
+ void *pElement = &variant;
+ switch (listType) {
+ case QVariant::Int:
+ vt = VT_I4;
+ pElement = &variant.lVal;
+ break;
+ case QVariant::Double:
+ vt = VT_R8;
+ pElement = &variant.dblVal;
+ break;
+ case QVariant::DateTime:
+ vt = VT_DATE;
+ pElement = &variant.date;
+ break;
+ case QVariant::Bool:
+ vt = VT_BOOL;
+ pElement = &variant.boolVal;
+ break;
+ case QVariant::LongLong:
+#if !defined(Q_OS_WINCE) && defined(_MSC_VER) && _MSC_VER >= 1400
+ vt = VT_I8;
+ pElement = &variant.llVal;
+#else
+ vt = VT_CY;
+ pElement = &variant.cyVal;
+#endif
+ break;
+ default:
+ break;
+ }
+ SAFEARRAY *array = 0;
+ bool is2D = false;
+ // If the first element in the array is a list the whole list is
+ // treated as a 2D array. The column count is taken from the 1st element.
+ if (count) {
+ QVariantList col = list.at(0).toList();
+ int maxColumns = col.count();
+ if (maxColumns) {
+ is2D = true;
+ SAFEARRAYBOUND rgsabound[2] = { {0} };
+ rgsabound[0].cElements = count;
+ rgsabound[1].cElements = maxColumns;
+ array = SafeArrayCreate(VT_VARIANT, 2, rgsabound);
+ LONG rgIndices[2];
+ for (LONG i = 0; i < count; ++i) {
+ rgIndices[0] = i;
+ QVariantList columns = list.at(i).toList();
+ int columnCount = qMin(maxColumns, columns.count());
+ for (LONG j = 0; j < columnCount; ++j) {
+ QVariant elem = columns.at(j);
+ VariantInit(&variant);
+ QVariantToVARIANT(elem, variant, elem.typeName());
+ rgIndices[1] = j;
+ SafeArrayPutElement(array, rgIndices, pElement);
+ clearVARIANT(&variant);
+ }
+ }
+
+ }
+ }
+ if (!is2D) {
+ array = SafeArrayCreateVector(vt, 0, count);
+ for (LONG index = 0; index < count; ++index) {
+ QVariant elem = list.at(index);
+ if (listType != QVariant::LastType)
+ elem.convert(listType);
+ VariantInit(&variant);
+ QVariantToVARIANT(elem, variant, elem.typeName());
+ SafeArrayPutElement(array, &index, pElement);
+ clearVARIANT(&variant);
+ }
+ }
+ if (out && arg.vt == (VT_ARRAY|vt|VT_BYREF)) {
+ if (*arg.pparray)
+ SafeArrayDestroy(*arg.pparray);
+ *arg.pparray = array;
+ } else {
+ arg.vt = VT_ARRAY|vt;
+ arg.parray = array;
+ if (out) {
+ arg.pparray = new SAFEARRAY*(arg.parray);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ }
+ break;
+
+ case QVariant::StringList:
+ {
+ const QStringList list = qvar.toStringList();
+ const int count = list.count();
+ SAFEARRAY *array = SafeArrayCreateVector(VT_BSTR, 0, count);
+ for (LONG index = 0; index < count; ++index) {
+ QString elem = list.at(index);
+ BSTR bstr = QStringToBSTR(elem);
+ SafeArrayPutElement(array, &index, bstr);
+ SysFreeString(bstr);
+ }
+
+ if (out && arg.vt == (VT_ARRAY|VT_BSTR|VT_BYREF)) {
+ if (*arg.pparray)
+ SafeArrayDestroy(*arg.pparray);
+ *arg.pparray = array;
+ } else {
+ arg.vt = VT_ARRAY|VT_BSTR;
+ arg.parray = array;
+ if (out) {
+ arg.pparray = new SAFEARRAY*(arg.parray);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ }
+ break;
+
+ case QVariant::ByteArray:
+ {
+ const QByteArray bytes = qvar.toByteArray();
+ const uint count = bytes.count();
+ SAFEARRAY *array = SafeArrayCreateVector(VT_UI1, 0, count);
+ if (count) {
+ const char *data = bytes.constData();
+ char *dest;
+ SafeArrayAccessData(array, (void **)&dest);
+ memcpy(dest, data, count);
+ SafeArrayUnaccessData(array);
+ }
+
+ if (out && arg.vt == (VT_ARRAY|VT_UI1|VT_BYREF)) {
+ if (*arg.pparray)
+ SafeArrayDestroy(*arg.pparray);
+ *arg.pparray = array;
+ } else {
+ arg.vt = VT_ARRAY|VT_UI1;
+ arg.parray = array;
+ if (out) {
+ arg.pparray = new SAFEARRAY*(arg.parray);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ }
+ break;
+
+#ifdef QAX_SERVER
+ case QVariant::Rect:
+ case QVariant::Size:
+ case QVariant::Point:
+ {
+ typedef HRESULT(WINAPI* PGetRecordInfoFromTypeInfo)(ITypeInfo *, IRecordInfo **);
+ static PGetRecordInfoFromTypeInfo pGetRecordInfoFromTypeInfo = 0;
+ static bool resolved = false;
+ if (!resolved) {
+ QSystemLibrary oleaut32(QLatin1String("oleaut32"));
+ pGetRecordInfoFromTypeInfo = (PGetRecordInfoFromTypeInfo)oleaut32.resolve("GetRecordInfoFromTypeInfo");
+ resolved = true;
+ }
+ if (!pGetRecordInfoFromTypeInfo)
+ break;
+
+ ITypeInfo *typeInfo = 0;
+ IRecordInfo *recordInfo = 0;
+ CLSID clsid = qvar.type() == QVariant::Rect ? CLSID_QRect
+ :qvar.type() == QVariant::Size ? CLSID_QSize
+ :CLSID_QPoint;
+ qAxTypeLibrary->GetTypeInfoOfGuid(clsid, &typeInfo);
+ if (!typeInfo)
+ break;
+ pGetRecordInfoFromTypeInfo(typeInfo, &recordInfo);
+ typeInfo->Release();
+ if (!recordInfo)
+ break;
+
+ void *record = 0;
+ switch (qvar.type()) {
+ case QVariant::Rect:
+ {
+ QRect qrect(qvar.toRect());
+ recordInfo->RecordCreateCopy(&qrect, &record);
+ }
+ break;
+ case QVariant::Size:
+ {
+ QSize qsize(qvar.toSize());
+ recordInfo->RecordCreateCopy(&qsize, &record);
+ }
+ break;
+ case QVariant::Point:
+ {
+ QPoint qpoint(qvar.toPoint());
+ recordInfo->RecordCreateCopy(&qpoint, &record);
+ }
+ break;
+ }
+
+ arg.vt = VT_RECORD;
+ arg.pRecInfo = recordInfo,
+ arg.pvRecord = record;
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for records");
+ return false;
+ }
+ }
+ break;
+#endif // QAX_SERVER
+ case QVariant::UserType:
+ {
+ QByteArray subType = qvar.typeName();
+#ifdef QAX_SERVER
+ if (subType.endsWith('*'))
+ subType.truncate(subType.length() - 1);
+#endif
+ if (!qstrcmp(qvar.typeName(), "IDispatch*")) {
+ arg.vt = VT_DISPATCH;
+ arg.pdispVal = *(IDispatch**)qvar.data();
+ if (arg.pdispVal)
+ arg.pdispVal->AddRef();
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for IDispatch");
+ return false;
+ }
+ } else if (!qstrcmp(qvar.typeName(), "IDispatch**")) {
+ arg.vt = VT_DISPATCH;
+ arg.ppdispVal = *(IDispatch***)qvar.data();
+ if (out)
+ arg.vt |= VT_BYREF;
+ } else if (!qstrcmp(qvar.typeName(), "IUnknown*")) {
+ arg.vt = VT_UNKNOWN;
+ arg.punkVal = *(IUnknown**)qvar.data();
+ if (arg.punkVal)
+ arg.punkVal->AddRef();
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for IUnknown");
+ return false;
+ }
+#ifdef QAX_SERVER
+ } else if (qAxFactory()->metaObject(QString::fromLatin1(subType.constData()))) {
+ arg.vt = VT_DISPATCH;
+ void *user = *(void**)qvar.constData();
+// qVariantGet(qvar, user, qvar.typeName());
+ if (!user) {
+ arg.pdispVal = 0;
+ } else {
+ qAxFactory()->createObjectWrapper(static_cast<QObject*>(user), &arg.pdispVal);
+ }
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for subtype");
+ return false;
+ }
+#else
+ } else if (QMetaType::type(subType)) {
+ QAxObject *object = *(QAxObject**)qvar.constData();
+// qVariantGet(qvar, object, subType);
+ arg.vt = VT_DISPATCH;
+ object->queryInterface(IID_IDispatch, (void**)&arg.pdispVal);
+ if (out) {
+ qWarning("QVariantToVARIANT: out-parameter not supported for subtype");
+ return false;
+ }
+#endif
+ } else {
+ return false;
+ }
+ }
+ break;
+#endif
+
+ case QVariant::Invalid: // default-parameters not set
+ if (out && arg.vt == (VT_ERROR|VT_BYREF)) {
+ *arg.plVal = DISP_E_PARAMNOTFOUND;
+ } else {
+ arg.vt = VT_ERROR;
+ arg.lVal = DISP_E_PARAMNOTFOUND;
+ if (out) {
+ arg.plVal = new long(arg.lVal);
+ arg.vt |= VT_BYREF;
+ }
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ Q_ASSERT(!out || (arg.vt & VT_BYREF));
+ return true;
+}
+
diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.h b/src/plugins/platforms/windows/accessible/comutils.h
index 6ea1b2ad3c..08420cc46c 100644
--- a/src/plugins/platforms/uikit/quikitwindowsurface.h
+++ b/src/plugins/platforms/windows/accessible/comutils.h
@@ -38,27 +38,24 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef COMUTILS_H
+#define COMUTILS_H
-#ifndef QUIKITWINDOWSURFACE_H
-#define QUIKITWINDOWSURFACE_H
+#if !defined(_WINDOWS_) && !defined(_WINDOWS_H) && !defined(__WINDOWS__)
+#error Must include windows.h first!
+#endif
-#include <QtGui/QPlatformIntegration>
+#include <ocidl.h>
+#include <QtCore/qstring.h>
-QT_BEGIN_NAMESPACE
+class QVariant;
-class QUIKitWindowSurface : public QWindowSurface
-{
-public:
- QUIKitWindowSurface(QWidget *window);
-
- QPaintDevice *paintDevice();
- void flush(QWidget *widget, const QRegion &region, const QPoint &offset);
- WindowSurfaceFeatures features() const;
+bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &typeName, bool out);
-private:
- QPaintDevice *mPaintDevice;
-};
+inline BSTR QStringToBSTR(const QString &str)
+{
+ return SysAllocStringLen((OLECHAR*)str.unicode(), str.length());
+}
-QT_END_NAMESPACE
+#endif // COMUTILS_H
-#endif // QUIKITWINDOWSURFACE_H
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
new file mode 100644
index 0000000000..f22349714f
--- /dev/null
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -0,0 +1,1467 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore/QtConfig>
+#ifndef QT_NO_ACCESSIBILITY
+
+#include "iaccessible2.h"
+#include "qwindowsaccessibility.h"
+
+#include <QtGui/qaccessible2.h>
+#include <QtWidgets/qapplication.h>
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+/**************************************************************\
+ * AccessibleApplication *
+ **************************************************************/
+// IUnknown
+HRESULT STDMETHODCALLTYPE AccessibleApplication::QueryInterface(REFIID id, LPVOID *iface)
+{
+ *iface = 0;
+ if (id == IID_IUnknown) {
+ accessibleDebug("AccessibleApplication::QI(): IID_IUnknown");
+ *iface = (IUnknown*)this;
+ } else if (id == IID_IAccessibleApplication) {
+ accessibleDebug("AccessibleApplication::QI(): IID_IAccessibleApplication");
+ *iface = static_cast<IAccessibleApplication*>(this);
+ }
+
+ if (*iface) {
+ AddRef();
+ return S_OK;
+ }
+ return E_NOINTERFACE;
+}
+
+ULONG STDMETHODCALLTYPE AccessibleApplication::AddRef()
+{
+ return ++m_ref;
+}
+
+ULONG STDMETHODCALLTYPE AccessibleApplication::Release()
+{
+ if (!--m_ref) {
+ delete this;
+ return 0;
+ }
+ return m_ref;
+}
+
+/* IAccessibleApplication */
+HRESULT STDMETHODCALLTYPE AccessibleApplication::get_appName(/* [retval][out] */ BSTR *name)
+{
+ const QString appName = QGuiApplication::applicationName();
+ *name = QStringToBSTR(appName);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE AccessibleApplication::get_appVersion(/* [retval][out] */ BSTR *version)
+{
+ const QString appName = QGuiApplication::applicationVersion();
+ *version = QStringToBSTR(appName);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitName(/* [retval][out] */ BSTR *name)
+{
+ *name = ::SysAllocString(L"Qt");
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE AccessibleApplication::get_toolkitVersion(/* [retval][out] */ BSTR *version)
+{
+ *version = ::SysAllocString(QT_UNICODE_LITERAL(QT_VERSION_STR));
+ return S_OK;
+}
+
+
+
+/*!
+ \internal
+ Client allocates and deallocates array
+ (see "Special Consideration when using Arrays", in Accessible2.idl)
+ */
+HRESULT STDMETHODCALLTYPE AccessibleRelation::get_target(
+ /* [in] */ long targetIndex,
+ /* [retval][out] */ IUnknown **target)
+{
+ if (targetIndex >= 0 && targetIndex < m_targets.count()) {
+ QAccessibleInterface *iface = m_targets.at(targetIndex);
+ *target = QWindowsAccessibility::wrap(iface);
+ if (*target)
+ return S_OK;
+ return E_FAIL;
+ }
+ return E_INVALIDARG;
+}
+
+/*!
+ \internal
+ Client allocates and deallocates \a targets array
+ (see "Special Consideration when using Arrays", in Accessible2.idl)
+ */
+HRESULT STDMETHODCALLTYPE AccessibleRelation::get_targets(
+ /* [in] */ long maxTargets, // Hmmm, ignore ???
+ /* [length_is][size_is][out] */ IUnknown **targets,
+ /* [retval][out] */ long *nTargets)
+{
+
+ const int numTargets = qMin((int)maxTargets, m_targets.count());
+ for (int i = 0; i < numTargets; ++i) {
+ QAccessibleInterface *iface = m_targets.at(i);
+ IAccessible *iacc = QWindowsAccessibility::wrap(iface);
+ if (!iacc)
+ return E_FAIL;
+ *targets = iacc;
+ ++targets;
+ }
+ *nTargets = numTargets;
+ // \a targets array is allocated by client.
+ return numTargets > 0 ? S_OK : S_FALSE;
+}
+
+
+/**************************************************************\
+ * *
+ * IUnknown *
+ * *
+ **************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryInterface(REFIID id, LPVOID *iface)
+{
+ *iface = 0;
+
+ QByteArray strIID = IIDToString(id);
+ if (!strIID.isEmpty()) {
+ QString ss; QDebug dbg(&ss); dbg << accessible;
+ accessibleDebug("QWindowsIA2Accessible::QI() - IID:%s, iface:%s ", strIID.constData(), qPrintable(ss));
+ }
+ if (id == IID_IUnknown) {
+ *iface = (IUnknown*)(IDispatch*)this;
+ } else if (id == IID_IDispatch) {
+ *iface = (IDispatch*)this;
+ } else if (id == IID_IAccessible) {
+ *iface = (IAccessible*)this;
+ } else if (id == IID_IOleWindow) {
+ *iface = (IOleWindow*)this;
+ } else if (id == IID_IServiceProvider) {
+ *iface = (IServiceProvider*)this;
+ } else if (id == IID_IAccessible2) {
+ *iface = (IAccessible2*)this;
+ } else if (id == IID_IAccessibleAction) {
+ if (accessible->actionInterface())
+ *iface = (IAccessibleAction*)this;
+ } else if (id == IID_IAccessibleComponent) {
+ *iface = (IAccessibleComponent*)this;
+ } else if (id == IID_IAccessibleEditableText) {
+ //if (accessible->editableTextInterface()) {
+ //*iface = (IAccessibleEditableText*)this;
+ //}
+ } else if (id == IID_IAccessibleHyperlink) {
+ //*iface = (IAccessibleHyperlink*)this;
+ } else if (id == IID_IAccessibleHypertext) {
+ //*iface = (IAccessibleHypertext*)this;
+ } else if (id == IID_IAccessibleImage) {
+ //*iface = (IAccessibleImage*)this;
+ } else if (id == IID_IAccessibleRelation) {
+ *iface = (IAccessibleRelation*)this;
+ } else if (id == IID_IAccessibleTable) {
+ //*iface = (IAccessibleTable*)this; // not supported
+ } else if (id == IID_IAccessibleTable2) {
+ if (accessible->tableInterface())
+ *iface = (IAccessibleTable2*)this;
+ } else if (id == IID_IAccessibleTableCell) {
+ if (accessible->tableCellInterface())
+ *iface = (IAccessibleTableCell*)this;
+ } else if (id == IID_IAccessibleText) {
+ if (accessible->textInterface())
+ *iface = (IAccessibleText*)this;
+ } else if (id == IID_IAccessibleValue) {
+ if (accessible->valueInterface())
+ *iface = (IAccessibleValue*)this;
+ }
+ if (*iface) {
+ AddRef();
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+ULONG STDMETHODCALLTYPE QWindowsIA2Accessible::AddRef()
+{
+ return ++ref;
+}
+
+ULONG STDMETHODCALLTYPE QWindowsIA2Accessible::Release()
+{
+ if (!--ref) {
+ delete this;
+ return 0;
+ }
+ return ref;
+}
+
+
+
+/**************************************************************\
+ * *
+ * IAccessible2 *
+ * *
+ **************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nRelations(long *nRelations)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!nRelations)
+ return E_INVALIDARG;
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ return getRelationsHelper(0, 0, 0, nRelations);
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_relation(long relationIndex, IAccessibleRelation **relation)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!relation)
+ return E_INVALIDARG;
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ return getRelationsHelper(relation, relationIndex, 1);
+}
+
+/*!
+ \internal
+ Client allocates and deallocates array
+ (see "Special Consideration when using Arrays", in Accessible2.idl)
+ */
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_relations(long maxRelations,
+ IAccessibleRelation **relations,
+ long *nRelations)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ return getRelationsHelper(relations, 0, maxRelations, nRelations);
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::role(long *ia2role)
+{
+ accessibleDebugClientCalls(accessible);
+ //### Change QAccessibleInterface::role() to return both MSAA and IA2 roles.
+ // When that is completed, we must patch the MSAA bridge not not return any
+ // IA2-specific roles from get_accRole().
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *ia2role = accessible->role();
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollTo(enum IA2ScrollType /*scrollType*/)
+{
+ //### Ignore for now
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollToPoint(enum IA2CoordinateType /*coordinateType*/, long /*x*/, long /*y*/)
+{
+ //### Ignore for now
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_groupPosition(long *groupLevel,
+ long *similarItemsInGroup,
+ long *positionInGroup)
+{
+ // ### Ignore for now. Not sure what this is used for.....
+ *groupLevel = 0; // Not applicable
+ *similarItemsInGroup = 0; // Not applicable
+ *positionInGroup = 0; // Not applicable
+ return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_states(AccessibleStates *states)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ if (!states)
+ return E_POINTER;
+ QAccessible::State st = accessible->state();
+ AccessibleStates ia2states = 0;
+ if (st.active)
+ ia2states |= IA2_STATE_ACTIVE;
+ if (st.invalid)
+ ia2states |= IA2_STATE_DEFUNCT;
+ if (st.editable)
+ ia2states |= IA2_STATE_EDITABLE;
+ if (st.multiLine)
+ ia2states |= IA2_STATE_MULTI_LINE;
+ if (st.selectableText)
+ ia2states |= IA2_STATE_SELECTABLE_TEXT;
+ if (st.supportsAutoCompletion)
+ ia2states |= IA2_STATE_SUPPORTS_AUTOCOMPLETION;
+
+ *states = ia2states;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_extendedRole(BSTR *extendedRole)
+{
+ //###
+ *extendedRole = 0;
+ return E_NOTIMPL; // mozilla does this
+ //return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_localizedExtendedRole(BSTR *localizedExtendedRole)
+{
+ //###
+ *localizedExtendedRole = 0;
+ return E_NOTIMPL; // mozilla does this
+ //return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nExtendedStates(long *nExtendedStates)
+{
+ // Who will ever intepret these values into something meaningful??
+ *nExtendedStates = 0;
+ return E_NOTIMPL; // mozilla does this
+ //return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_extendedStates(long /*maxExtendedStates*/,
+ BSTR **extendedStates,
+ long *nExtendedStates)
+{
+ *extendedStates = 0;
+ *nExtendedStates = 0;
+ return E_NOTIMPL; // mozilla does this
+ //return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_localizedExtendedStates(long /*maxLocalizedExtendedStates*/,
+ BSTR **localizedExtendedStates,
+ long *nLocalizedExtendedStates)
+{
+ *localizedExtendedStates = 0;
+ *nLocalizedExtendedStates = 0;
+ return E_NOTIMPL; // mozilla does this
+ //return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_uniqueID(long *outUniqueID)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ // ### FIXME SERIOUSLY, NOT A STABLE SOLUTION IF NODES ARE DELETED ETC
+ // Return 0 if no object and no parent. This is really an error case.
+ uint uid = uniqueID();
+ accessibleDebug("uniqueID: %08x", uid);
+
+ *outUniqueID = (long)uid;
+ return uid ? S_OK : S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_windowHandle(HWND *windowHandle)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ return GetWindow(windowHandle);
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_indexInParent(long *indexInParent)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ if (!indexInParent)
+ return E_INVALIDARG;
+ QAccessibleInterface *par = accessible->parent();
+ if (!par) {
+ *indexInParent = -1;
+ return S_FALSE;
+ }
+ int indexOfChild = par->indexOfChild(accessible);
+ delete par;
+ Q_ASSERT(indexOfChild >= 0);
+ *indexInParent = indexOfChild;
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locale(IA2Locale *locale)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ IA2Locale res;
+ QLocale l;
+ res.country = QStringToBSTR(QLocale::countryToString(l.country()));
+ res.language = QStringToBSTR(QLocale::languageToString(l.language()));
+ *locale = res;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_attributes(BSTR *attributes)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *attributes = 0;//QStringToBSTR(QString());
+ return S_FALSE;
+}
+
+/**************************************************************\
+ * IAccessibleAction *
+ **************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::nActions(long *nActions)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *nActions = 0;
+
+ if (QAccessibleActionInterface *actionIface = actionInterface())
+ *nActions = actionIface->actionNames().count();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::doAction(long actionIndex)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ if (QAccessibleActionInterface *actionIface = actionInterface()) {
+ const QStringList actionNames = actionIface->actionNames();
+ if (actionIndex < 0 || actionIndex >= actionNames.count())
+ return E_INVALIDARG;
+ const QString actionName = actionNames.at(actionIndex);
+ actionIface->doAction(actionName);
+ return S_OK;
+ }
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_description(long actionIndex, BSTR *description)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *description = 0;
+ if (QAccessibleActionInterface *actionIface = actionInterface()) {
+ const QStringList actionNames = actionIface->actionNames();
+ if (actionIndex < 0 || actionIndex >= actionNames.count())
+ return E_INVALIDARG;
+ const QString actionName = actionNames.at(actionIndex);
+ *description = QStringToBSTR(actionIface->localizedActionDescription(actionName));
+ }
+ return *description ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_keyBinding(long actionIndex, long nMaxBindings, BSTR **keyBindings, long *nBindings)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ Q_UNUSED(nMaxBindings);
+ BSTR *arrayOfBindingsToReturn = 0;
+ int numBindings = 0;
+ if (QAccessibleActionInterface *actionIface = actionInterface()) {
+ const QStringList actionNames = actionIface->actionNames();
+ if (actionIndex < 0 || actionIndex >= actionNames.count())
+ return E_INVALIDARG;
+ const QString actionName = actionNames.at(actionIndex);
+ const QStringList keyBindings = actionIface->keyBindingsForAction(actionName);
+ numBindings = keyBindings.count();
+ if (numBindings > 0) {
+ // The IDL documents that the client must free with CoTaskMemFree
+ arrayOfBindingsToReturn = (BSTR*)::CoTaskMemAlloc(sizeof(BSTR) * numBindings);
+ for (int i = 0; i < numBindings; ++i)
+ arrayOfBindingsToReturn[i] = QStringToBSTR(keyBindings.at(i));
+ }
+ }
+ *keyBindings = arrayOfBindingsToReturn;
+ *nBindings = numBindings;
+
+ return numBindings ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_name(long actionIndex, BSTR *name)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *name = 0;
+ if (QAccessibleActionInterface *actionIface = actionInterface()) {
+ const QStringList actionNames = actionIface->actionNames();
+ if (actionIndex < 0 || actionIndex >= actionNames.count())
+ return E_INVALIDARG;
+ const QString actionName = actionNames.at(actionIndex);
+ *name = QStringToBSTR(actionName);
+ }
+ return *name ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_localizedName(long actionIndex, BSTR *localizedName)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *localizedName = 0;
+ if (QAccessibleActionInterface *actionIface = actionInterface()) {
+ const QStringList actionNames = actionIface->actionNames();
+ if (actionIndex < 0 || actionIndex >= actionNames.count())
+ return E_INVALIDARG;
+
+ const QString actionName = actionNames.at(actionIndex);
+ *localizedName = QStringToBSTR(actionIface->localizedActionName(actionName));
+ }
+ return *localizedName ? S_OK : S_FALSE;
+}
+
+/**************************************************************\
+ * IAccessibleComponent *
+ **************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locationInParent(long *x, long *y)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QPoint topLeft = accessible->rect().topLeft();
+
+ if (QAccessibleInterface *parentIface = accessible->parent())
+ topLeft -= parentIface->rect().topLeft();
+
+ *x = topLeft.x();
+ *y = topLeft.y();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_foreground(IA2Color *foreground)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ // IA2Color is a typedef for long
+ *foreground = (IA2Color)accessible->foregroundColor().rgb();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_background(IA2Color *background)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ // IA2Color is a typedef for long
+ *background = (IA2Color)accessible->backgroundColor().rgb();
+ return S_OK;
+}
+
+/**************************************************************\
+ * IAccessibleTable2 *
+ **************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_cellAt( long row, long column, IUnknown **cell)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *cell = 0;
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ if (QAccessibleInterface *qtCell = tableIface->cellAt(row, column)) {
+ *cell = QWindowsAccessibility::wrap(qtCell);
+ }
+ }
+ accessibleDebug("found cell? %p", *cell);
+ return *cell ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_caption( IUnknown **captionInterface)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *captionInterface = 0;
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ if (QAccessibleInterface *iface = tableIface->caption())
+ *captionInterface = QWindowsAccessibility::wrap(iface);
+ }
+ return *captionInterface ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnDescription( long column, BSTR *description)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *description = 0;
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ const QString qtDesc = tableIface->columnDescription(column);
+ if (!qtDesc.isEmpty())
+ *description = QStringToBSTR(qtDesc);
+ }
+ return *description ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nColumns( long *columnCount)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ *columnCount = tableIface->columnCount();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nRows(long *rowCount)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ *rowCount = tableIface->rowCount();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelectedCells(long *cellCount)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ *cellCount = tableIface->selectedCellCount();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelectedColumns(long *columnCount)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ *columnCount = tableIface->selectedColumnCount();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelectedRows(long *rowCount)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ *rowCount = tableIface->selectedRowCount();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowDescription(long row, BSTR *description)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *description = 0;
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ const QString qtDesc = tableIface->columnDescription(row);
+ if (!qtDesc.isEmpty())
+ *description = QStringToBSTR(qtDesc);
+ }
+ return *description ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedCells(IUnknown ***cells, long *nSelectedCells)
+{
+ accessibleDebugClientCalls(accessible);
+ Q_UNUSED(cells);
+ Q_UNUSED(nSelectedCells);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QList<QAccessibleInterface*> selectedCells = tableInterface()->selectedCells();
+ return wrapListOfCells(selectedCells, cells, nSelectedCells);
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedColumns(long **selectedColumns, long *nColumns)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ const QList<int> selectedIndices = tableIface->selectedColumns();
+ const int &count = selectedIndices.count();
+ long *selected = (count ? (long*)::CoTaskMemAlloc(sizeof(long) * count) : (long*)0);
+ for (int i = 0; i < count; ++i)
+ selected[i] = selectedIndices.at(i);
+ *selectedColumns = selected;
+ *nColumns = count;
+ return count ? S_OK : S_FALSE;
+ }
+ return E_FAIL;
+
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selectedRows(long **selectedRows, long *nRows)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ const QList<int> selectedIndices = tableIface->selectedRows();
+ const int &count = selectedIndices.count();
+ long *selected = (count ? (long*)::CoTaskMemAlloc(sizeof(long) * count) : (long*)0);
+ for (int i = 0; i < count; ++i)
+ selected[i] = selectedIndices.at(i);
+ *selectedRows = selected;
+ *nRows = count;
+ return count ? S_OK : S_FALSE;
+ }
+ return E_FAIL;
+
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_summary(IUnknown **summaryInterface)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *summaryInterface = 0;
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ if (QAccessibleInterface *iface = tableIface->summary())
+ *summaryInterface = QWindowsAccessibility::wrap(iface);
+ }
+ return *summaryInterface ? S_OK : S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_isColumnSelected(long column, boolean *isSelected)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ *isSelected = tableIface->isColumnSelected(column);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_isRowSelected(long row, boolean *isSelected)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ *isSelected = tableIface->isRowSelected(row);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::selectRow(long row)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ bool ok = tableIface->selectRow(row);
+ return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails???
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::selectColumn(long column)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ bool ok = tableIface->selectColumn(column);
+ return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails???
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::unselectRow(long row)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ bool ok = tableIface->unselectRow(row);
+ return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails???
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::unselectColumn(long column)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ if (QAccessibleTableInterface *tableIface = tableInterface()) {
+ bool ok = tableIface->unselectColumn(column);
+ return ok ? S_OK : E_INVALIDARG; //### Not sure of the return value if it fails???
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_modelChange( IA2TableModelChange * /*modelChange*/)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ return E_NOTIMPL;
+}
+
+/**************************************************************\
+ * IAccessibleTableCell *
+\**************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnExtent(long *nColumnsSpanned)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ *nColumnsSpanned = tableCellInterface()->columnExtent();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnHeaderCells(IUnknown ***cellAccessibles,
+ long *nColumnHeaderCells)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ const QList<QAccessibleInterface*> headerCells = tableCellInterface()->columnHeaderCells();
+ return wrapListOfCells(headerCells, cellAccessibles, nColumnHeaderCells);
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_columnIndex(long *columnIndex)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *columnIndex = tableCellInterface()->columnIndex();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowExtent(long *nRowsSpanned)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *nRowsSpanned = tableCellInterface()->rowExtent();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowHeaderCells(IUnknown ***cellAccessibles,
+ long *nRowHeaderCells)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ const QList<QAccessibleInterface*> headerCells = tableCellInterface()->rowHeaderCells();
+ return wrapListOfCells(headerCells, cellAccessibles, nRowHeaderCells);
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowIndex(long *rowIndex)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *rowIndex = tableCellInterface()->rowIndex();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_isSelected( boolean *isSelected)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ *isSelected = tableCellInterface()->isSelected();
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_rowColumnExtents(long *row, long *column,
+ long *rowExtents, long *columnExtents,
+ boolean *isSelected)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ tableCellInterface()->rowColumnExtents((int*)row, (int*)column, (int*)rowExtents, (int*)columnExtents, (bool*)isSelected);
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_table(IUnknown **table)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+
+ QAccessibleInterface *tableIface = tableCellInterface()->table();
+
+ *table = QWindowsAccessibility::wrap(tableIface);
+ return S_OK;
+}
+
+/**************************************************************\
+ * IAccessibleText *
+\**************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::addSelection(long startOffset,
+ long endOffset)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *text = textInterface()) {
+ text->addSelection(startOffset, endOffset);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_attributes(long offset,
+ long *startOffset,
+ long *endOffset,
+ BSTR *textAttributes)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *text = textInterface()) {
+ const QString attrs = text->attributes(offset, (int*)startOffset, (int*)endOffset);
+ *textAttributes = QStringToBSTR(attrs);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_caretOffset(long *offset)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *text = textInterface()) {
+ *offset = text->cursorPosition();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_characterExtents(long offset,
+ enum IA2CoordinateType coordType,
+ long *x,
+ long *y,
+ long *width,
+ long *height)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *text = textInterface()) {
+ const QRect rect = text->characterRect(offset, (QAccessible2::CoordinateType)coordType);
+ *x = rect.x();
+ *y = rect.y();
+ *width = rect.width();
+ *height = rect.height();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nSelections(long *nSelections)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *text = textInterface()) {
+ *nSelections = text->selectionCount();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_offsetAtPoint(long x,
+ long y,
+ enum IA2CoordinateType coordType,
+ long *offset)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *text = textInterface()) {
+ *offset = text->offsetAtPoint(QPoint(x,y), (QAccessible2::CoordinateType)coordType);
+ return (*offset >=0 ? S_OK : S_FALSE);
+ }
+ return E_FAIL;
+
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_selection(long selectionIndex,
+ long *startOffset,
+ long *endOffset)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *text = textInterface()) {
+ text->selection(selectionIndex, (int*)startOffset, (int*)endOffset);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_text(long startOffset,
+ long endOffset,
+ BSTR *text)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textif = textInterface()) {
+ const QString t = textif->text(startOffset, endOffset);
+ if (!t.isEmpty()) {
+ *text = QStringToBSTR(t);
+ return S_OK;
+ }
+ return E_INVALIDARG;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textBeforeOffset(long offset,
+ enum IA2TextBoundaryType boundaryType,
+ long *startOffset,
+ long *endOffset,
+ BSTR *text)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ const QString txt = textIface->textBeforeOffset(offset, (QAccessible2::BoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
+ if (!txt.isEmpty()) {
+ *text = QStringToBSTR(txt);
+ return S_OK;
+ }
+ return S_FALSE;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAfterOffset(
+ long offset,
+ enum IA2TextBoundaryType boundaryType,
+ long *startOffset,
+ long *endOffset,
+ BSTR *text)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ const QString txt = textIface->textAfterOffset(offset, (QAccessible2::BoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
+ if (!txt.isEmpty()) {
+ *text = QStringToBSTR(txt);
+ return S_OK;
+ }
+ return S_FALSE;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_textAtOffset(long offset,
+ enum IA2TextBoundaryType boundaryType,
+ long *startOffset,
+ long *endOffset,
+ BSTR *text)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ const QString txt = textIface->textAtOffset(offset, (QAccessible2::BoundaryType)boundaryType, (int*)startOffset, (int*)endOffset);
+ if (!txt.isEmpty()) {
+ *text = QStringToBSTR(txt);
+ return S_OK;
+ }
+ return S_FALSE;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::removeSelection(long selectionIndex)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ textIface->removeSelection(selectionIndex);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setCaretOffset(long offset)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ textIface->setCursorPosition(offset);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setSelection(long selectionIndex,
+ long startOffset,
+ long endOffset)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ textIface->setSelection(selectionIndex, startOffset, endOffset);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_nCharacters(long *nCharacters)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ *nCharacters = textIface->characterCount();
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollSubstringTo(long startIndex,
+ long endIndex,
+ enum IA2ScrollType scrollType)
+{
+ accessibleDebugClientCalls(accessible);
+ if (QAccessibleTextInterface *textIface = textInterface()) {
+ Q_UNUSED(scrollType); //###
+ textIface->scrollToSubstring(startIndex, endIndex);
+ return S_OK;
+ }
+ return E_FAIL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::scrollSubstringToPoint(long startIndex,
+ long endIndex,
+ enum IA2CoordinateType coordinateType,
+ long x,
+ long y)
+{
+ Q_UNUSED(startIndex);
+ Q_UNUSED(endIndex);
+ Q_UNUSED(coordinateType);
+ Q_UNUSED(x);
+ Q_UNUSED(y);
+
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_newText(IA2TextSegment *newText)
+{
+ Q_UNUSED(newText);
+ return E_NOTIMPL;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_oldText(IA2TextSegment *oldText)
+{
+ Q_UNUSED(oldText);
+ return E_NOTIMPL;
+}
+
+/**************************************************************\
+ * IAccessibleValue *
+ **************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_currentValue(VARIANT *currentValue)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ if (QAccessibleValueInterface *valueIface = valueInterface()) {
+ const QVariant var = valueIface->currentValue();
+ if (QVariantToVARIANT(var, *currentValue, QByteArray(), false))
+ return S_OK;
+
+ }
+ currentValue->vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::setCurrentValue(VARIANT value)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ HRESULT hr = S_FALSE;
+ if (QAccessibleValueInterface *valueIface = valueInterface()) {
+ hr = VariantChangeType(&value, &value, 0, VT_R8);
+ if (SUCCEEDED(hr)) {
+ // ### works only for numbers (not date, strings, etc)
+ valueIface->setCurrentValue(QVariant(value.dblVal));
+ }
+ }
+ return hr;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_maximumValue(VARIANT *maximumValue)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ if (QAccessibleValueInterface *valueIface = valueInterface()) {
+ const QVariant var = valueIface->maximumValue();
+ if (QVariantToVARIANT(var, *maximumValue, QByteArray(), false))
+ return S_OK;
+ }
+ maximumValue->vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_minimumValue(VARIANT *minimumValue)
+{
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
+ if (QAccessibleValueInterface *valueIface = valueInterface()) {
+ const QVariant var = valueIface->minimumValue();
+ if (QVariantToVARIANT(var, *minimumValue, QByteArray(), false))
+ return S_OK;
+ }
+ minimumValue->vt = VT_EMPTY;
+ return S_FALSE;
+}
+
+
+/**************************************************************\
+ * IServiceProvider *
+ **************************************************************/
+/*!
+ \internal
+ Reimplemented from IServiceProvider
+*/
+HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::QueryService(REFGUID guidService, REFIID riid, void **iface)
+{
+ if (!iface)
+ return E_POINTER;
+ Q_UNUSED(guidService);
+ *iface = 0;
+ accessibleDebug("QWindowsIA2Accessible::QS(): %s", IIDToString(riid).constData());
+ if (riid == IID_IAccessible || riid == IID_IUnknown || riid == IID_IDispatch) {
+ *iface = static_cast<IAccessible*>(this);
+ } else if (/*guidService == IID_IAccessible && */riid == IID_IAccessible2) {
+ *iface = static_cast<IAccessible2*>(this);
+ } else if (riid == IID_IAccessibleApplication) {
+ *iface = new AccessibleApplication;
+ return S_OK;
+ } else {
+ QueryInterface(riid, iface);
+ }
+ if (*iface) {
+ AddRef();
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+
+/*!
+ \internal
+ private function..
+ \a maxRelations max number of relations to return in \a relations
+ \a relations the array of relations matching
+ \a startIndex Index to start to return from,
+ it will return only that specific relation in \a relations
+
+ If \a relations is null, \a startIndex and \a maxRelations are ignored, causing
+ it to return the number of relations in \a nRelations
+*/
+HRESULT QWindowsIA2Accessible::getRelationsHelper(IAccessibleRelation **relations, int startIndex, long maxRelations, long *nRelations /* = 0*/)
+{
+ if (nRelations)
+ *nRelations = 0;
+ typedef QPair<QAccessibleInterface *, QAccessible::Relation> RelationEntry;
+ QVector<RelationEntry> rels = accessible->relations();
+ QMap<QAccessible::Relation, QAccessibleInterface *> relationMap;
+ for (QVector<RelationEntry>::const_iterator it = rels.constBegin(); it != rels.constEnd(); ++it)
+ {
+ RelationEntry e = *it;
+ relationMap.insertMulti(e.second, e.first);
+ }
+
+ QList<QAccessible::Relation> keys = relationMap.keys();
+ const int numRelations = keys.count();
+ if (relations) {
+ for (int i = startIndex; i < qMin(startIndex + (int)maxRelations, numRelations); ++i) {
+ QAccessible::Relation relation = keys.at(i);
+ QList<QAccessibleInterface*> targets = relationMap.values(relation);
+ AccessibleRelation *rel = new AccessibleRelation(targets, relation);
+ *relations = rel;
+ ++relations;
+ }
+ }
+ if (nRelations)
+ *nRelations = numRelations;
+
+ return numRelations > 0 ? S_OK : S_FALSE;
+}
+
+
+
+
+/*!
+ \internal
+ helper to wrap a QList<QAccessibleInterface*> inside an array of IAccessible*
+ The IAccessible* array is returned as a IUnknown*
+*/
+HRESULT QWindowsIA2Accessible::wrapListOfCells(const QList<QAccessibleInterface*> &inputCells, IUnknown ***outputAccessibles, long *nCellCount)
+{
+ const int count = inputCells.count();
+ // Server allocates array
+ IUnknown **outputCells = count ? (IUnknown**)::CoTaskMemAlloc(sizeof(IUnknown*) * count ) : (IUnknown**)0;
+ for (int i = 0; i < count; ++i)
+ outputCells[i] = QWindowsAccessibility::wrap(inputCells.at(i));
+
+ *outputAccessibles = outputCells;
+ *nCellCount = count;
+ return count > 0 ? S_OK : S_FALSE;
+}
+
+uint QWindowsIA2Accessible::uniqueID() const
+{
+ uint uid = 0;
+ if (QObject *obj = accessible->object())
+ uid = qHash(obj);
+
+ if (!uid) {
+ QAccessibleInterface *acc = accessible;
+ QVector<int> indexOfNodes;
+ while (acc && !acc->object()) {
+ QAccessibleInterface *par = acc->parent();
+ indexOfNodes.append(par->indexOfChild(acc));
+ if (acc != accessible)
+ delete acc;
+ acc = par;
+ }
+ if (acc) {
+ if (acc->object()) {
+ uid = qHash(acc->object());
+ for (int i = 0; i < indexOfNodes.count(); ++i)
+ uid = qHash(uid + indexOfNodes.at(i));
+
+ }
+ if (acc != accessible)
+ delete acc;
+ }
+ }
+ return uid;
+}
+
+
+#define IF_EQUAL_RETURN_IIDSTRING(id, iid) if (id == iid) return QByteArray(#iid)
+
+QByteArray QWindowsIA2Accessible::IIDToString(REFIID id)
+{
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IUnknown);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IDispatch);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessible);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IOleWindow);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IServiceProvider);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessible2);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleAction);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleApplication);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleComponent);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleEditableText);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleHyperlink);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleHypertext);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleImage);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleRelation);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleTable);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleTable2);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleTableCell);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleText);
+ IF_EQUAL_RETURN_IIDSTRING(id, IID_IAccessibleValue);
+
+ // else...
+ QByteArray strGuid;
+#if 0 // Can be useful for debugging, but normally we'd like to reduce the noise a bit...
+ OLECHAR szGuid[39]={0};
+ ::StringFromGUID2(id, szGuid, 39);
+ strGuid.reserve(40);
+ ::WideCharToMultiByte(CP_UTF8, 0, szGuid, 39, strGuid.data(), 39, NULL, NULL);
+ strGuid[38] = '\0';
+#endif
+ return strGuid;
+}
+
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.h b/src/plugins/platforms/windows/accessible/iaccessible2.h
new file mode 100644
index 0000000000..a59263fba1
--- /dev/null
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.h
@@ -0,0 +1,379 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef IACCESSIBLE2_H
+#define IACCESSIBLE2_H
+
+#include <QtCore/QtConfig>
+#ifndef QT_NO_ACCESSIBILITY
+
+#include "qwindowsmsaaaccessible.h"
+#include "comutils.h"
+
+#include "Accessible2.h"
+#include "AccessibleAction.h"
+#include "AccessibleApplication.h"
+#include "AccessibleComponent.h"
+#include "AccessibleEditableText.h"
+#include "AccessibleHyperlink.h"
+#include "AccessibleHypertext.h"
+#include "AccessibleImage.h"
+#include "AccessibleRelation.h"
+#include "AccessibleTable.h"
+#include "AccessibleTable2.h"
+#include "AccessibleTableCell.h"
+#include "AccessibleText.h"
+#include "AccessibleValue.h"
+
+#include "AccessibleEventID.h"
+#include "AccessibleRole.h"
+#include "AccessibleStates.h"
+
+#ifdef Q_CC_MINGW
+# include <servprov.h>
+#endif
+
+QT_BEGIN_NAMESPACE
+
+class QWindowsIA2Accessible : public QWindowsMsaaAccessible,
+ public IAccessibleAction,
+ public IAccessibleComponent,
+ /*public IAccessibleEditableText,*/
+ public IAccessibleTable2,
+ public IAccessibleTableCell,
+ public IAccessibleText,
+ public IAccessibleValue,
+ public IServiceProvider
+{
+public:
+ QWindowsIA2Accessible(QAccessibleInterface *a) : QWindowsMsaaAccessible(a) {}
+
+ /* IUnknown */
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ /* IAccessible2 */
+ HRESULT STDMETHODCALLTYPE get_nRelations(long *nRelations);
+ HRESULT STDMETHODCALLTYPE get_relation(long relationIndex, IAccessibleRelation **relation);
+ HRESULT STDMETHODCALLTYPE get_relations(long maxRelations, IAccessibleRelation **relations, long *nRelations);
+ HRESULT STDMETHODCALLTYPE role(long *role);
+ HRESULT STDMETHODCALLTYPE scrollTo(enum IA2ScrollType scrollType);
+ HRESULT STDMETHODCALLTYPE scrollToPoint(enum IA2CoordinateType coordinateType, long x, long y);
+ HRESULT STDMETHODCALLTYPE get_groupPosition(long *groupLevel, long *similarItemsInGroup, long *positionInGroup);
+ HRESULT STDMETHODCALLTYPE get_states(AccessibleStates *states);
+ HRESULT STDMETHODCALLTYPE get_extendedRole(BSTR *extendedRole);
+ HRESULT STDMETHODCALLTYPE get_localizedExtendedRole(BSTR *localizedExtendedRole);
+ HRESULT STDMETHODCALLTYPE get_nExtendedStates(long *nExtendedStates);
+ HRESULT STDMETHODCALLTYPE get_extendedStates(long maxExtendedStates, BSTR **extendedStates, long *nExtendedStates);
+ HRESULT STDMETHODCALLTYPE get_localizedExtendedStates(long maxLocalizedExtendedStates, BSTR **localizedExtendedStates, long *nLocalizedExtendedStates);
+ HRESULT STDMETHODCALLTYPE get_uniqueID(long *uniqueID);
+ HRESULT STDMETHODCALLTYPE get_windowHandle(HWND *windowHandle);
+ HRESULT STDMETHODCALLTYPE get_indexInParent(long *indexInParent);
+ HRESULT STDMETHODCALLTYPE get_locale(IA2Locale *locale);
+ HRESULT STDMETHODCALLTYPE get_attributes(BSTR *attributes);
+
+ /* IAccessibleAction */
+ HRESULT STDMETHODCALLTYPE nActions(long *nActions);
+ HRESULT STDMETHODCALLTYPE doAction(long actionIndex);
+ HRESULT STDMETHODCALLTYPE get_description(long actionIndex, BSTR *description);
+ HRESULT STDMETHODCALLTYPE get_keyBinding(long actionIndex, long nMaxBindings, BSTR **keyBindings, long *nBindings);
+ HRESULT STDMETHODCALLTYPE get_name(long actionIndex, BSTR *name);
+ HRESULT STDMETHODCALLTYPE get_localizedName(long actionIndex, BSTR *localizedName);
+
+ /* IAccessibleComponent */
+ HRESULT STDMETHODCALLTYPE get_locationInParent(long *x,long *y);
+ HRESULT STDMETHODCALLTYPE get_foreground(IA2Color *foreground);
+ HRESULT STDMETHODCALLTYPE get_background(IA2Color *background);
+
+ /* IAccessibleEditableText */
+ /*
+ HRESULT STDMETHODCALLTYPE copyText(long startOffset, long endOffset);
+ HRESULT STDMETHODCALLTYPE deleteText(long startOffset, long endOffset);
+ HRESULT STDMETHODCALLTYPE insertText(long offset, BSTR *text);
+ HRESULT STDMETHODCALLTYPE cutText(long startOffset, long endOffset);
+ HRESULT STDMETHODCALLTYPE pasteText(long offset);
+ HRESULT STDMETHODCALLTYPE replaceText(long startOffset, long endOffset, BSTR *text);
+ HRESULT STDMETHODCALLTYPE setAttributes(long startOffset, long endOffset, BSTR *attributes);
+ */
+
+ /* IAccessibleTable2 */
+ HRESULT STDMETHODCALLTYPE get_cellAt( long row, long column, IUnknown **cell);
+ HRESULT STDMETHODCALLTYPE get_caption( IUnknown **accessible);
+ HRESULT STDMETHODCALLTYPE get_columnDescription( long column, BSTR *description);
+ HRESULT STDMETHODCALLTYPE get_nColumns( long *columnCount);
+ HRESULT STDMETHODCALLTYPE get_nRows( long *rowCount);
+ HRESULT STDMETHODCALLTYPE get_nSelectedCells( long *cellCount);
+ HRESULT STDMETHODCALLTYPE get_nSelectedColumns( long *columnCount);
+ HRESULT STDMETHODCALLTYPE get_nSelectedRows( long *rowCount);
+ HRESULT STDMETHODCALLTYPE get_rowDescription( long row, BSTR *description);
+ HRESULT STDMETHODCALLTYPE get_selectedCells( IUnknown ***cells, long *nSelectedCells);
+ HRESULT STDMETHODCALLTYPE get_selectedColumns( long **selectedColumns, long *nColumns);
+ HRESULT STDMETHODCALLTYPE get_selectedRows( long **selectedRows, long *nRows);
+ HRESULT STDMETHODCALLTYPE get_summary( IUnknown **accessible);
+ HRESULT STDMETHODCALLTYPE get_isColumnSelected( long column, boolean *isSelected);
+ HRESULT STDMETHODCALLTYPE get_isRowSelected( long row, boolean *isSelected);
+ HRESULT STDMETHODCALLTYPE selectRow( long row);
+ HRESULT STDMETHODCALLTYPE selectColumn( long column);
+ HRESULT STDMETHODCALLTYPE unselectRow( long row);
+ HRESULT STDMETHODCALLTYPE unselectColumn( long column);
+ HRESULT STDMETHODCALLTYPE get_modelChange( IA2TableModelChange *modelChange);
+
+ /* IAccessibleTableCell */
+ HRESULT STDMETHODCALLTYPE get_columnExtent(long *nColumnsSpanned);
+ HRESULT STDMETHODCALLTYPE get_columnHeaderCells(IUnknown ***cellAccessibles, long *nColumnHeaderCells);
+ HRESULT STDMETHODCALLTYPE get_columnIndex(long *columnIndex);
+ HRESULT STDMETHODCALLTYPE get_rowExtent(long *nRowsSpanned);
+ HRESULT STDMETHODCALLTYPE get_rowHeaderCells(IUnknown ***cellAccessibles, long *nRowHeaderCells);
+ HRESULT STDMETHODCALLTYPE get_rowIndex(long *rowIndex);
+ HRESULT STDMETHODCALLTYPE get_isSelected( boolean *isSelected);
+ HRESULT STDMETHODCALLTYPE get_rowColumnExtents(long *row, long *column,
+ long *rowExtents, long *columnExtents,
+ boolean *isSelected);
+ HRESULT STDMETHODCALLTYPE get_table(IUnknown **table);
+
+
+ /* IAccessibleText */
+ HRESULT STDMETHODCALLTYPE addSelection(long startOffset, long endOffset);
+ HRESULT STDMETHODCALLTYPE get_attributes(long offset, long *startOffset,
+ long *endOffset, BSTR *textAttributes);
+ HRESULT STDMETHODCALLTYPE get_caretOffset(long *offset);
+ HRESULT STDMETHODCALLTYPE get_characterExtents(long offset, enum IA2CoordinateType coordType,
+ long *x, long *y,
+ long *width, long *height);
+ HRESULT STDMETHODCALLTYPE get_nSelections(long *nSelections);
+ HRESULT STDMETHODCALLTYPE get_offsetAtPoint(long x, long y, enum IA2CoordinateType coordType, long *offset);
+ HRESULT STDMETHODCALLTYPE get_selection(long selectionIndex, long *startOffset, long *endOffset);
+ HRESULT STDMETHODCALLTYPE get_text(long startOffset, long endOffset, BSTR *text);
+ HRESULT STDMETHODCALLTYPE get_textBeforeOffset(long offset, enum IA2TextBoundaryType boundaryType,
+ long *startOffset, long *endOffset, BSTR *text);
+ HRESULT STDMETHODCALLTYPE get_textAfterOffset(long offset, enum IA2TextBoundaryType boundaryType,
+ long *startOffset, long *endOffset, BSTR *text);
+ HRESULT STDMETHODCALLTYPE get_textAtOffset(long offset, enum IA2TextBoundaryType boundaryType,
+ long *startOffset, long *endOffset, BSTR *text);
+ HRESULT STDMETHODCALLTYPE removeSelection(long selectionIndex);
+ HRESULT STDMETHODCALLTYPE setCaretOffset(long offset);
+ HRESULT STDMETHODCALLTYPE setSelection(long selectionIndex, long startOffset, long endOffset);
+ HRESULT STDMETHODCALLTYPE get_nCharacters(long *nCharacters);
+ HRESULT STDMETHODCALLTYPE scrollSubstringTo(long startIndex, long endIndex, enum IA2ScrollType scrollType);
+ HRESULT STDMETHODCALLTYPE scrollSubstringToPoint(long startIndex, long endIndex,
+ enum IA2CoordinateType coordinateType, long x, long y);
+ HRESULT STDMETHODCALLTYPE get_newText(IA2TextSegment *newText);
+ HRESULT STDMETHODCALLTYPE get_oldText(IA2TextSegment *oldText);
+
+ /* IAccessibleValue */
+ HRESULT STDMETHODCALLTYPE get_currentValue(VARIANT *currentValue);
+ HRESULT STDMETHODCALLTYPE setCurrentValue(VARIANT value);
+ HRESULT STDMETHODCALLTYPE get_maximumValue(VARIANT *maximumValue);
+ HRESULT STDMETHODCALLTYPE get_minimumValue(VARIANT *minimumValue);
+
+ /* IServiceProvider */
+ HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void **ppv);
+
+ /* private helper functions */
+private:
+ inline QAccessibleTextInterface *textInterface() const {
+ return accessible->isValid() ? accessible->textInterface() : static_cast<QAccessibleTextInterface *>(0);
+ }
+
+ inline QAccessibleActionInterface *actionInterface() const {
+ return accessible->actionInterface();
+ }
+
+ inline QAccessibleValueInterface *valueInterface() const {
+ return accessible->valueInterface();
+ }
+
+ inline QAccessibleTableInterface *tableInterface() const {
+ return accessible->tableInterface();
+ }
+
+ inline QAccessibleTableCellInterface *tableCellInterface() const {
+ return accessible->tableCellInterface();
+ }
+
+ HRESULT getRelationsHelper(IAccessibleRelation **relations, int startIndex, long maxRelations, long *nRelations = 0);
+ HRESULT wrapListOfCells(const QList<QAccessibleInterface*> &inputCells, IUnknown ***outputAccessibles, long *nCellCount);
+ uint uniqueID() const;
+ QByteArray IIDToString(REFIID id);
+
+private:
+ ULONG ref;
+
+};
+
+/**************************************************************\
+ * AccessibleApplication *
+ **************************************************************/
+class AccessibleApplication : public IAccessibleApplication
+{
+public:
+ AccessibleApplication() : m_ref(1)
+ {
+
+ }
+
+ virtual ~AccessibleApplication() {}
+
+ /* IUnknown */
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *);
+ ULONG STDMETHODCALLTYPE AddRef();
+ ULONG STDMETHODCALLTYPE Release();
+
+ /* IAccessibleApplication */
+ HRESULT STDMETHODCALLTYPE get_appName(/* [retval][out] */ BSTR *name);
+ HRESULT STDMETHODCALLTYPE get_appVersion(/* [retval][out] */ BSTR *version);
+ HRESULT STDMETHODCALLTYPE get_toolkitName(/* [retval][out] */ BSTR *name);
+ HRESULT STDMETHODCALLTYPE get_toolkitVersion(/* [retval][out] */ BSTR *version);
+private:
+ ULONG m_ref;
+};
+
+
+
+/**************************************************************\
+ * IAccessibleRelation *
+ **************************************************************/
+struct AccessibleRelation : public IAccessibleRelation
+{
+ AccessibleRelation(const QList<QAccessibleInterface *> &targets,
+ QAccessible::Relation relation)
+ : m_targets(targets), m_relation(relation), m_ref(1)
+ {
+ Q_ASSERT(m_targets.count());
+ }
+
+
+ /* IUnknown */
+ HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, LPVOID *iface)
+ {
+ *iface = 0;
+ if (id == IID_IUnknown)
+ *iface = (IUnknown*)this;
+
+ if (*iface) {
+ AddRef();
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+ }
+
+ ULONG STDMETHODCALLTYPE AddRef()
+ {
+ return ++m_ref;
+ }
+
+ ULONG STDMETHODCALLTYPE Release()
+ {
+ if (!--m_ref) {
+ delete this;
+ return 0;
+ }
+ return m_ref;
+ }
+
+ /* IAccessibleRelation */
+ HRESULT STDMETHODCALLTYPE get_relationType(
+ /* [retval][out] */ BSTR *relationType)
+ {
+ *relationType = relationToBSTR(m_relation);
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE get_localizedRelationType(
+ /* [retval][out] */ BSTR *localizedRelationType)
+ {
+ // Who ever needs this???
+ *localizedRelationType = relationToBSTR(m_relation);
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE get_nTargets(
+ /* [retval][out] */ long *nTargets)
+ {
+ // ### always one target
+ *nTargets = m_targets.count();
+ return S_OK;
+ }
+
+ HRESULT STDMETHODCALLTYPE get_target(long targetIndex, IUnknown **target);
+
+
+ /*!
+ \internal
+ Client allocates and deallocates \a targets array
+ (see "Special Consideration when using Arrays", in Accessible2.idl)
+ */
+ HRESULT STDMETHODCALLTYPE get_targets(
+ /* [in] */ long maxTargets, // Hmmm, ignore ???
+ /* [length_is][size_is][out] */ IUnknown **targets,
+ /* [retval][out] */ long *nTargets);
+
+private:
+ static BSTR relationToBSTR(QAccessible::Relation relation)
+ {
+ wchar_t *constRelationString = 0;
+ switch (relation) {
+ case QAccessible::Controlled:
+ constRelationString = IA2_RELATION_CONTROLLED_BY;
+ break;
+ }
+
+ if (constRelationString) {
+ BSTR bstrVal;
+ const UINT wlen = (UINT)wcslen(constRelationString);
+ bstrVal = ::SysAllocStringLen(constRelationString, wlen);
+ return bstrVal;
+ }
+ return 0;
+ }
+
+
+ QList<QAccessibleInterface *> m_targets;
+ QAccessible::Relation m_relation;
+ ULONG m_ref;
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ACCESSIBILITY
+
+#endif // IACCESSIBLE2_H
diff --git a/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
new file mode 100644
index 0000000000..4f92b910b2
--- /dev/null
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.cpp
@@ -0,0 +1,319 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QtConfig>
+#ifndef QT_NO_ACCESSIBILITY
+
+
+#include <private/qsystemlibrary_p.h>
+
+#include <QtCore/qlocale.h>
+#include <QtCore/qmap.h>
+#include <QtCore/qpair.h>
+#include <QtCore/qsettings.h>
+#include <QtGui/qaccessible.h>
+#include <QtGui/qaccessible2.h>
+#include <QtGui/qplatformnativeinterface_qpa.h>
+#include <QtGui/qwindow.h>
+#include <QtGui/qguiapplication.h>
+
+#include "qwindowsaccessibility.h"
+
+#ifndef Q_CC_MINGW
+# include "iaccessible2.h"
+#endif // !Q_CC_MINGW
+
+#include "comutils.h"
+
+#include <oleacc.h>
+
+//#include <uiautomationcoreapi.h>
+#ifndef UiaRootObjectId
+#define UiaRootObjectId -25
+#endif
+
+#include <winuser.h>
+#if !defined(WINABLEAPI)
+# if defined(Q_OS_WINCE)
+# include <bldver.h>
+# endif
+# include <winable.h>
+#endif
+
+#include <oleacc.h>
+#include <servprov.h>
+#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU)
+#include <comdef.h>
+#endif
+
+#ifdef Q_OS_WINCE
+#include "../qguifunctions_wince.h"
+#endif
+
+#include "../qtwindows_additional.h"
+
+
+// This stuff is used for widgets/items with no window handle:
+typedef QMap<int, QPair<QObject*,int> > NotifyMap;
+Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents)
+
+
+QT_BEGIN_NAMESPACE
+
+
+/*!
+ \!internal
+ \class QWindowsAccessibility
+
+ Implements QPlatformAccessibility
+
+*/
+QWindowsAccessibility::QWindowsAccessibility()
+{
+}
+
+void QWindowsAccessibility::notifyAccessibilityUpdate(const QAccessibleEvent &event)
+{
+ QString soundName;
+ switch (event.type()) {
+ case QAccessible::PopupMenuStart:
+ soundName = QLatin1String("MenuPopup");
+ break;
+
+ case QAccessible::MenuCommand:
+ soundName = QLatin1String("MenuCommand");
+ break;
+
+ case QAccessible::Alert:
+ {
+ /* ### FIXME
+#ifndef QT_NO_MESSAGEBOX
+ QMessageBox *mb = qobject_cast<QMessageBox*>(o);
+ if (mb) {
+ switch (mb->icon()) {
+ case QMessageBox::Warning:
+ soundName = QLatin1String("SystemExclamation");
+ break;
+ case QMessageBox::Critical:
+ soundName = QLatin1String("SystemHand");
+ break;
+ case QMessageBox::Information:
+ soundName = QLatin1String("SystemAsterisk");
+ break;
+ default:
+ break;
+ }
+ } else
+#endif // QT_NO_MESSAGEBOX
+*/
+ {
+ soundName = QLatin1String("SystemAsterisk");
+ }
+
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!soundName.isEmpty()) {
+#ifndef QT_NO_SETTINGS
+ QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName,
+ QSettings::NativeFormat);
+ QString file = settings.value(QLatin1String(".Current/.")).toString();
+#else
+ QString file;
+#endif
+ if (!file.isEmpty()) {
+ PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
+ }
+ }
+
+ typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG);
+
+#if defined(Q_OS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0
+ // There is no user32.lib nor NotifyWinEvent for CE
+ return;
+#else
+ static PtrNotifyWinEvent ptrNotifyWinEvent = 0;
+ static bool resolvedNWE = false;
+ if (!resolvedNWE) {
+ resolvedNWE = true;
+ ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent");
+ }
+ if (!ptrNotifyWinEvent)
+ return;
+
+ // An event has to be associated with a window,
+ // so find the first parent that is a widget and that has a WId
+ QAccessibleInterface *iface = event.accessibleInterface();
+ QWindow *window = iface ? QWindowsAccessibility::windowHelper(iface) : 0;
+ delete iface;
+
+ if (!window) {
+ window = QGuiApplication::activeWindow();
+ if (!window)
+ return;
+ }
+
+ QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
+ HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window);
+
+ static int eventNum = 0;
+ if (event.type() != QAccessible::MenuCommand) { // MenuCommand is faked
+ // See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE"
+ eventNum %= 50; //[0..49]
+ int eventId = - (eventNum - 1);
+
+ qAccessibleRecentSentEvents()->insert(eventId, qMakePair(event.object(), event.child()));
+ ptrNotifyWinEvent(event.type(), hWnd, OBJID_CLIENT, eventId );
+
+ ++eventNum;
+ }
+#endif // Q_OS_WINCE
+}
+
+QWindow *QWindowsAccessibility::windowHelper(const QAccessibleInterface *iface)
+{
+ QWindow *window = iface->window();
+ if (!window) {
+ QAccessibleInterface *acc = iface->parent();
+ while (acc && !window) {
+ window = acc->window();
+ QAccessibleInterface *par = acc->parent();
+ delete acc;
+ acc = par;
+ }
+ }
+ return window;
+}
+
+/*!
+ \internal
+ helper to wrap a QAccessibleInterface inside a IAccessible*
+*/
+IAccessible *QWindowsAccessibility::wrap(QAccessibleInterface *acc)
+{
+#ifdef Q_CC_MINGW
+ return 0;
+#else
+ if (!acc)
+ return 0;
+ QWindowsIA2Accessible *wacc = new QWindowsIA2Accessible(acc);
+ IAccessible *iacc = 0;
+ wacc->QueryInterface(IID_IAccessible, (void**)&iacc);
+ return iacc;
+#endif
+}
+
+/*!
+ \internal
+*/
+QPair<QObject*, int> QWindowsAccessibility::getCachedObject(int entryId)
+{
+ return qAccessibleRecentSentEvents()->value(entryId);
+}
+
+/*
+void QWindowsAccessibility::setRootObject(QObject *o)
+{
+
+}
+
+void QWindowsAccessibility::initialize()
+{
+
+}
+
+void QWindowsAccessibility::cleanup()
+{
+
+}
+
+*/
+
+bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
+{
+ if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) {
+ /* For UI Automation */
+ } else if ((DWORD)lParam == OBJID_CLIENT) {
+#if 1
+ // Ignoring all requests while starting up
+ // ### Maybe QPA takes care of this???
+ if (QCoreApplication::startingUp() || QCoreApplication::closingDown())
+ return false;
+#endif
+
+ typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
+ static PtrLresultFromObject ptrLresultFromObject = 0;
+ static bool oleaccChecked = false;
+
+ if (!oleaccChecked) {
+ oleaccChecked = true;
+#if !defined(Q_OS_WINCE)
+ ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
+#endif
+ }
+
+ if (ptrLresultFromObject) {
+ QWindow *window = QWindowsContext::instance()->findWindow(hwnd);
+ if (window) {
+ QAccessibleInterface *acc = window->accessibleRoot();
+ if (acc) {
+ if (IAccessible *iface = wrap(acc)) {
+ *lResult = ptrLresultFromObject(IID_IAccessible, wParam, iface); // ref == 2
+ if (*lResult) {
+ iface->Release(); // the client will release the object again, and then it will destroy itself
+ }
+ return true;
+ } else {
+ delete acc;
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.h b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h
index 9294f23565..0c3aca0a03 100644
--- a/src/plugins/platforms/windows/qwindowsaccessibility.h
+++ b/src/plugins/platforms/windows/accessible/qwindowsaccessibility.h
@@ -42,9 +42,12 @@
#ifndef QWINDOWSACCESSIBILITY_H
#define QWINDOWSACCESSIBILITY_H
-#include "qtwindowsglobal.h"
+#include "../qtwindowsglobal.h"
+#include "../qwindowscontext.h"
#include <QtGui/QPlatformAccessibility>
+#include <oleacc.h>
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -59,6 +62,10 @@ public:
virtual void initialize();
virtual void cleanup();
*/
+ static IAccessible *wrap(QAccessibleInterface *acc);
+ static QWindow *windowHelper(const QAccessibleInterface *iface);
+
+ static QPair<QObject*, int> getCachedObject(int entryId);
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsaccessibility.cpp b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
index 134b1c81ce..8791bbdcfb 100644
--- a/src/plugins/platforms/windows/qwindowsaccessibility.cpp
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.cpp
@@ -42,104 +42,44 @@
#include <QtCore/QtConfig>
#ifndef QT_NO_ACCESSIBILITY
-
+#include "qwindowsmsaaaccessible.h"
#include "qwindowsaccessibility.h"
-#include "qwindowscontext.h"
-
-#include <private/qsystemlibrary_p.h>
+#include <oleacc.h>
+#include <servprov.h>
+#include <winuser.h>
+#include "comutils.h"
+#include <QtCore/qdebug.h>
#include <QtCore/qmap.h>
-#include <QtCore/qsettings.h>
-#include <QtCore/qsharedpointer.h>
#include <QtCore/qpair.h>
-#include <QtWidgets/qapplication.h>
-#include <QtWidgets/qmessagebox.h>
-#include <QtWidgets/qgraphicsitem.h>
-#include <QtWidgets/qgraphicsview.h>
+#include <QtCore/qsettings.h>
#include <QtGui/qaccessible.h>
+#include <QtGui/qaccessible2.h>
+#include <QtGui/qguiapplication.h>
#include <QtGui/qplatformnativeinterface_qpa.h>
#include <QtGui/qwindow.h>
-#include <QtGui/qaccessible2.h>
-#include <oleacc.h>
+#include <QtWidgets/qapplication.h>
+#include <QtWidgets/qgraphicsitem.h>
+#include <QtWidgets/qgraphicsview.h>
+#include <QtWidgets/qmessagebox.h>
//#include <uiautomationcoreapi.h>
#ifndef UiaRootObjectId
#define UiaRootObjectId -25
#endif
-#include <winuser.h>
-#if !defined(WINABLEAPI)
-# if defined(Q_OS_WINCE)
-# include <bldver.h>
-# endif
-# include <winable.h>
-#endif
-
-#include <oleacc.h>
#if !defined(Q_CC_BOR) && !defined (Q_CC_GNU)
#include <comdef.h>
#endif
#ifdef Q_OS_WINCE
-#include "qguifunctions_wince.h"
+#include "../qguifunctions_wince.h"
#endif
-#include "qtwindows_additional.h"
-
-QT_BEGIN_NAMESPACE
-
-#ifndef QT_NO_DEBUG
-QT_BEGIN_INCLUDE_NAMESPACE
-# include <qdebug.h>
-QT_END_INCLUDE_NAMESPACE
-static inline bool debug_accessibility()
-{
- static signed int debugging = -1;
- if (debugging == -1)
- debugging = qgetenv("QT_DEBUG_ACCESSIBILITY").toInt();
- return !!debugging;
-}
-# define accessibleDebug !debug_accessibility() ? (void)0 : qDebug
-#else
-# define accessibleDebug()
-#endif
-
-//#define DEBUG_SHOW_ATCLIENT_COMMANDS
-#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS)
-void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface)
-{
- QString str;
- QDebug dbg(&str);
- dbg << iface << QLatin1String(funcName);
- accessibleDebug("%s", qPrintable(str));
-}
-# define accessibleDebugClientCalls(iface) accessibleDebugClientCalls_helper(Q_FUNC_INFO, iface)
-#else
-# define accessibleDebugClientCalls(iface)
-#endif
-
-
-typedef QSharedPointer<QAccessibleInterface> QAIPointer;
-
-static bool compareAccessible(QAccessibleInterface *one, QAccessibleInterface *other)
-{
- if (one == other) return true;
- if (!one || !other) return false;
-
- if (one->object() && other->object() && (one->object() == other->object()))
- return true;
- QAIPointer onePar(one->parent());
- QAIPointer otherPar(other->parent());
+#include "../qtwindows_additional.h"
- if (compareAccessible(onePar.data(), otherPar.data()))
- return onePar->indexOfChild(one) == otherPar->indexOfChild(other);
- return false;
-}
-// This stuff is used for widgets/items with no window handle:
-typedef QMap<int, QPair<QObject*,int> > NotifyMap;
-Q_GLOBAL_STATIC(NotifyMap, qAccessibleRecentSentEvents)
-static int eventNum = 0;
+QT_BEGIN_NAMESPACE
class QWindowsEnumerate : public IEnumVARIANT
{
@@ -249,140 +189,60 @@ HRESULT STDMETHODCALLTYPE QWindowsEnumerate::Skip(unsigned long celt)
return S_OK;
}
-/*
-*/
-class QWindowsAccessible : public IAccessible, IOleWindow
-{
-public:
- QWindowsAccessible(QAccessibleInterface *a)
- : ref(0), accessible(a)
- {
- }
-
- virtual ~QWindowsAccessible()
- {
- delete accessible;
- }
-
- /* IUnknown */
- HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID *);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- /* IDispatch */
- HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *);
- HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int, unsigned long, ITypeInfo **);
- HRESULT STDMETHODCALLTYPE GetIDsOfNames(const _GUID &, wchar_t **, unsigned int, unsigned long, long *);
- HRESULT STDMETHODCALLTYPE Invoke(long, const _GUID &, unsigned long, unsigned short, tagDISPPARAMS *, tagVARIANT *, tagEXCEPINFO *, unsigned int *);
-
- /* IAccessible */
- HRESULT STDMETHODCALLTYPE accHitTest(long xLeft, long yTop, VARIANT *pvarID);
- HRESULT STDMETHODCALLTYPE accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID);
- HRESULT STDMETHODCALLTYPE accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd);
- HRESULT STDMETHODCALLTYPE get_accChild(VARIANT varChildID, IDispatch** ppdispChild);
- HRESULT STDMETHODCALLTYPE get_accChildCount(long* pcountChildren);
- HRESULT STDMETHODCALLTYPE get_accParent(IDispatch** ppdispParent);
-
- HRESULT STDMETHODCALLTYPE accDoDefaultAction(VARIANT varID);
- HRESULT STDMETHODCALLTYPE get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction);
- HRESULT STDMETHODCALLTYPE get_accDescription(VARIANT varID, BSTR* pszDescription);
- HRESULT STDMETHODCALLTYPE get_accHelp(VARIANT varID, BSTR *pszHelp);
- HRESULT STDMETHODCALLTYPE get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild, long *pidTopic);
- HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut);
- HRESULT STDMETHODCALLTYPE get_accName(VARIANT varID, BSTR* pszName);
- HRESULT STDMETHODCALLTYPE put_accName(VARIANT varChild, BSTR szName);
- HRESULT STDMETHODCALLTYPE get_accRole(VARIANT varID, VARIANT *pvarRole);
- HRESULT STDMETHODCALLTYPE get_accState(VARIANT varID, VARIANT *pvarState);
- HRESULT STDMETHODCALLTYPE get_accValue(VARIANT varID, BSTR* pszValue);
- HRESULT STDMETHODCALLTYPE put_accValue(VARIANT varChild, BSTR szValue);
-
- HRESULT STDMETHODCALLTYPE accSelect(long flagsSelect, VARIANT varID);
- HRESULT STDMETHODCALLTYPE get_accFocus(VARIANT *pvarID);
- HRESULT STDMETHODCALLTYPE get_accSelection(VARIANT *pvarChildren);
-
- /* IOleWindow */
- HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
- HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
-
-private:
- ULONG ref;
- QAccessibleInterface *accessible;
-
- QAIPointer childPointer(VARIANT varID)
- {
- return QAIPointer(accessible->child(varID.lVal - 1));
- }
-};
-
-static inline BSTR QStringToBSTR(const QString &str)
+static bool compareAccessible(QAccessibleInterface *one, QAccessibleInterface *other)
{
- BSTR bstrVal;
-
- int wlen = str.length()+1;
- bstrVal = SysAllocStringByteLen(0, wlen*2);
- memcpy(bstrVal, str.unicode(), sizeof(QChar)*(wlen));
- bstrVal[wlen] = 0;
-
- return bstrVal;
-}
-
-/*
-*/
+ if (one == other) return true;
+ if (!one || !other) return false;
-/*
- IUnknown
-*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::QueryInterface(REFIID id, LPVOID *iface)
-{
- *iface = 0;
- if (id == IID_IUnknown)
- *iface = (IUnknown*)(IDispatch*)this;
- else if (id == IID_IDispatch)
- *iface = (IDispatch*)this;
- else if (id == IID_IAccessible)
- *iface = (IAccessible*)this;
- else if (id == IID_IOleWindow)
- *iface = (IOleWindow*)this;
- else
- return E_NOINTERFACE;
+ if (one->object() && other->object() && (one->object() == other->object()))
+ return true;
+ QAIPointer onePar(one->parent());
+ QAIPointer otherPar(other->parent());
- AddRef();
- return S_OK;
+ if (compareAccessible(onePar.data(), otherPar.data()))
+ return onePar->indexOfChild(one) == otherPar->indexOfChild(other);
+ return false;
}
-ULONG STDMETHODCALLTYPE QWindowsAccessible::AddRef()
+#ifndef QT_NO_DEBUG
+bool debug_accessibility()
{
- return ++ref;
+ static int debugging = -1;
+ if (debugging == -1)
+ debugging = qgetenv("QT_DEBUG_ACCESSIBILITY").toInt();
+ return !!debugging;
}
+#endif
-ULONG STDMETHODCALLTYPE QWindowsAccessible::Release()
+#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS)
+void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface)
{
- if (!--ref) {
- delete this;
- return 0;
- }
- return ref;
+ QString str;
+ QDebug dbg(&str);
+ dbg << iface << QLatin1String(funcName);
+ accessibleDebug("%s", qPrintable(str));
}
+#endif
/*
IDispatch
*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetTypeInfoCount(unsigned int * pctinfo)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetTypeInfoCount(unsigned int * pctinfo)
{
// We don't use a type library
*pctinfo = 0;
return S_OK;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetTypeInfo(unsigned int, unsigned long, ITypeInfo **pptinfo)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetTypeInfo(unsigned int, unsigned long, ITypeInfo **pptinfo)
{
// We don't use a type library
*pptinfo = 0;
return S_OK;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetIDsOfNames(const _GUID &, wchar_t **rgszNames, unsigned int, unsigned long, long *rgdispid)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetIDsOfNames(const _GUID &, wchar_t **rgszNames, unsigned int, unsigned long, long *rgdispid)
{
#if !defined(Q_CC_BOR) && !defined(Q_CC_GNU)
// PROPERTIES: Hierarchical
@@ -440,7 +300,13 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetIDsOfNames(const _GUID &, wchar
#endif
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::Invoke(long dispIdMember, const _GUID &, unsigned long, unsigned short wFlags, tagDISPPARAMS *pDispParams, tagVARIANT *pVarResult, tagEXCEPINFO *, unsigned int *)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::Invoke(long dispIdMember,
+ const _GUID &,
+ unsigned long,
+ unsigned short wFlags,
+ tagDISPPARAMS *pDispParams,
+ tagVARIANT *pVarResult,
+ tagEXCEPINFO *, unsigned int *)
{
HRESULT hr = DISP_E_MEMBERNOTFOUND;
@@ -621,9 +487,8 @@ IAccessible::accHitTest documents the value returned in pvarID like this:
| | | interface pointer |
+--------------------------------------------------------+-------------+-------------------------+
*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarID)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accHitTest(long xLeft, long yTop, VARIANT *pvarID)
{
-
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
@@ -637,9 +502,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop,
return S_OK;
}
} else {
- QWindowsAccessible* wacc = new QWindowsAccessible(child);
- IDispatch *iface = 0;
- wacc->QueryInterface(IID_IDispatch, (void**)&iface);
+ IAccessible *iface = QWindowsAccessibility::wrap(child);
if (iface) {
(*pvarID).vt = VT_DISPATCH;
(*pvarID).pdispVal = iface;
@@ -662,7 +525,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accHitTest(long xLeft, long yTop,
can be ignored. All stuff prefixed with "moz" are information from that page.
*/
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -686,7 +549,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accLocation(long *pxLeft, long *py
}
// moz: [important, but no need to implement up/down/left/right]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -809,16 +672,14 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT v
(*pvarEnd).vt = VT_EMPTY;
return S_FALSE;
}
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- IDispatch *iface = 0;
- wacc->QueryInterface(IID_IDispatch, (void**)&iface);
- if (iface) {
+ if (IAccessible *iface = QWindowsAccessibility::wrap(acc)) {
(*pvarEnd).vt = VT_DISPATCH;
(*pvarEnd).pdispVal = iface;
return S_OK;
} else {
- delete wacc;
+ if (acc != accessible)
+ delete acc;
}
(*pvarEnd).vt = VT_EMPTY;
@@ -826,13 +687,13 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accNavigate(long navDir, VARIANT v
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, IDispatch** ppdispChild)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChild(VARIANT varChildID, IDispatch** ppdispChild)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
return E_FAIL;
- if (varChildID.vt == VT_EMPTY)
+ if (varChildID.vt != VT_I4)
return E_INVALIDARG;
@@ -841,7 +702,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, I
if (childIndex < 0) {
const int entry = childIndex;
- QPair<QObject*, int> ref = qAccessibleRecentSentEvents()->value(entry);
+ QPair<QObject*, int> ref = QWindowsAccessibility::getCachedObject(entry);
if (ref.first) {
acc = QAccessible::queryAccessibleInterface(ref.first);
if (acc && ref.second >= 0) {
@@ -851,6 +712,8 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, I
return E_INVALIDARG;
acc = res;
}
+ } else {
+ qWarning("get_accChild got a negative varChildID, but did not find it in cache");
}
} else {
if (childIndex) {
@@ -868,17 +731,15 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChild(VARIANT varChildID, I
}
if (acc) {
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- wacc->QueryInterface(IID_IDispatch, (void**)ppdispChild);
+ *ppdispChild = QWindowsAccessibility::wrap(acc);
return S_OK;
}
- *ppdispChild = 0;
- return S_FALSE;
+ return E_FAIL;
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChildCount(long* pcountChildren)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accChildCount(long* pcountChildren)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -889,7 +750,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accChildCount(long* pcountChil
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accParent(IDispatch** ppdispParent)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accParent(IDispatch** ppdispParent)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -897,11 +758,12 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accParent(IDispatch** ppdispPa
QAccessibleInterface *acc = accessible->parent();
if (acc) {
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- wacc->QueryInterface(IID_IDispatch, (void**)ppdispParent);
-
- if (*ppdispParent)
+ if (IAccessible *iface = QWindowsAccessibility::wrap(acc)) {
+ *ppdispParent = iface;
return S_OK;
+ } else {
+ delete acc;
+ }
}
*ppdispParent = 0;
@@ -911,7 +773,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accParent(IDispatch** ppdispPa
/*
Properties and methods
*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accDoDefaultAction(VARIANT varID)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accDoDefaultAction(VARIANT varID)
{
Q_UNUSED(varID);
accessibleDebugClientCalls(accessible);
@@ -928,7 +790,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accDoDefaultAction(VARIANT varID)
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction)
{
Q_UNUSED(varID);
accessibleDebugClientCalls(accessible);
@@ -944,7 +806,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDefaultAction(VARIANT varID
return *pszDefaultAction ? S_OK : S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDescription(VARIANT varID, BSTR* pszDescription)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accDescription(VARIANT varID, BSTR* pszDescription)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -969,7 +831,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accDescription(VARIANT varID,
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelp(VARIANT varID, BSTR *pszHelp)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelp(VARIANT varID, BSTR *pszHelp)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -993,12 +855,12 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelp(VARIANT varID, BSTR *p
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accHelpTopic(BSTR *, VARIANT, long *)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accHelpTopic(BSTR *, VARIANT, long *)
{
return DISP_E_MEMBERNOTFOUND;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut)
{
Q_UNUSED(varID);
accessibleDebugClientCalls(accessible);
@@ -1029,7 +891,7 @@ static QAccessibleInterface *relatedInterface(QAccessibleInterface *iface, QAcce
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* pszName)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accName(VARIANT varID, BSTR* pszName)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -1065,14 +927,14 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accName(VARIANT varID, BSTR* p
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accName(VARIANT, BSTR)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accName(VARIANT, BSTR)
{
accessibleDebugClientCalls(accessible);
return DISP_E_MEMBERNOTFOUND;
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accRole(VARIANT varID, VARIANT *pvarRole)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accRole(VARIANT varID, VARIANT *pvarRole)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -1100,7 +962,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accRole(VARIANT varID, VARIANT
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIANT *pvarState)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VARIANT *pvarState)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -1176,11 +1038,15 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accState(VARIANT varID, VARIAN
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accValue(VARIANT varID, BSTR* pszValue)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accValue(VARIANT varID, BSTR* pszValue)
{
accessibleDebugClientCalls(accessible);
- if (!accessible->isValid() || varID.lVal)
+ if (varID.vt != VT_I4)
+ return E_INVALIDARG;
+
+ if (!accessible->isValid() || varID.lVal) {
return E_FAIL;
+ }
QString value;
if (accessible->valueInterface()) {
@@ -1194,17 +1060,18 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accValue(VARIANT varID, BSTR*
}
*pszValue = 0;
+ accessibleDebug("return S_FALSE");
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::put_accValue(VARIANT, BSTR)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::put_accValue(VARIANT, BSTR)
{
accessibleDebugClientCalls(accessible);
return DISP_E_MEMBERNOTFOUND;
}
// moz: [important]
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::accSelect(long flagsSelect, VARIANT varID)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::accSelect(long flagsSelect, VARIANT varID)
{
Q_UNUSED(flagsSelect);
Q_UNUSED(varID);
@@ -1250,7 +1117,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::accSelect(long flagsSelect, VARIAN
+-------------+------------------------------------------------------------------------------+
moz: [important]
*/
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accFocus(VARIANT *pvarID)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -1263,12 +1130,11 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID)
delete acc;
return S_OK;
} else {
- QWindowsAccessible* wacc = new QWindowsAccessible(acc);
- IDispatch *iface = 0;
- wacc->QueryInterface(IID_IDispatch, (void**)&iface);
- (*pvarID).vt = VT_DISPATCH;
- (*pvarID).pdispVal = iface;
- return S_OK;
+ if (IAccessible *iface = QWindowsAccessibility::wrap(acc)) {
+ (*pvarID).vt = VT_DISPATCH;
+ (*pvarID).pdispVal = iface;
+ return S_OK;
+ }
}
delete acc;
}
@@ -1276,7 +1142,7 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accFocus(VARIANT *pvarID)
return S_FALSE;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accSelection(VARIANT *pvarChildren)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accSelection(VARIANT *pvarChildren)
{
accessibleDebugClientCalls(accessible);
if (!accessible->isValid())
@@ -1314,212 +1180,34 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accSelection(VARIANT *pvarChil
return S_OK;
}
-static QWindow *window_helper(const QAccessibleInterface *iface)
-{
- QWindow *window = iface->window();
- if (!window) {
- QAccessibleInterface *acc = iface->parent();
- while (acc && !window) {
- window = acc->window();
- QAccessibleInterface *par = acc->parent();
- delete acc;
- acc = par;
- }
- }
- return window;
-}
-
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::GetWindow(HWND *phwnd)
+/**************************************************************\
+ * IOleWindow *
+ **************************************************************/
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::GetWindow(HWND *phwnd)
{
*phwnd = 0;
+ accessibleDebugClientCalls(accessible);
+ if (!accessible->isValid())
+ return E_FAIL;
if (!accessible->isValid())
return E_UNEXPECTED;
- QWindow *window = window_helper(accessible);
+ QWindow *window = QWindowsAccessibility::windowHelper(accessible);
if (!window)
return E_FAIL;
QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
Q_ASSERT(platform);
*phwnd = (HWND)platform->nativeResourceForWindow("handle", window);
+ accessibleDebug("QWindowsAccessible::GetWindow(): %p", *phwnd);
return S_OK;
}
-HRESULT STDMETHODCALLTYPE QWindowsAccessible::ContextSensitiveHelp(BOOL)
+HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::ContextSensitiveHelp(BOOL)
{
return S_OK;
}
-
-QWindowsAccessibility::QWindowsAccessibility()
-{
-}
-
-
-void QWindowsAccessibility::notifyAccessibilityUpdate(const QAccessibleEvent &event)
-{
- QString soundName;
- switch (event.type()) {
- case QAccessible::PopupMenuStart:
- soundName = QLatin1String("MenuPopup");
- break;
-
- case QAccessible::MenuCommand:
- soundName = QLatin1String("MenuCommand");
- break;
-
- case QAccessible::Alert:
- {
- /* ### FIXME
-#ifndef QT_NO_MESSAGEBOX
- QMessageBox *mb = qobject_cast<QMessageBox*>(o);
- if (mb) {
- switch (mb->icon()) {
- case QMessageBox::Warning:
- soundName = QLatin1String("SystemExclamation");
- break;
- case QMessageBox::Critical:
- soundName = QLatin1String("SystemHand");
- break;
- case QMessageBox::Information:
- soundName = QLatin1String("SystemAsterisk");
- break;
- default:
- break;
- }
- } else
-#endif // QT_NO_MESSAGEBOX
-*/
- {
- soundName = QLatin1String("SystemAsterisk");
- }
-
- }
- break;
- default:
- break;
- }
-
- if (!soundName.isEmpty()) {
-#ifndef QT_NO_SETTINGS
- QSettings settings(QLatin1String("HKEY_CURRENT_USER\\AppEvents\\Schemes\\Apps\\.Default\\") + soundName,
- QSettings::NativeFormat);
- QString file = settings.value(QLatin1String(".Current/.")).toString();
-#else
- QString file;
-#endif
- if (!file.isEmpty()) {
- PlaySound(reinterpret_cast<const wchar_t *>(soundName.utf16()), 0, SND_ALIAS | SND_ASYNC | SND_NODEFAULT | SND_NOWAIT);
- }
- }
-
- typedef void (WINAPI *PtrNotifyWinEvent)(DWORD, HWND, LONG, LONG);
-
-#if defined(Q_OS_WINCE) // ### TODO: check for NotifyWinEvent in CE 6.0
- // There is no user32.lib nor NotifyWinEvent for CE
- return;
-#else
- static PtrNotifyWinEvent ptrNotifyWinEvent = 0;
- static bool resolvedNWE = false;
- if (!resolvedNWE) {
- resolvedNWE = true;
- ptrNotifyWinEvent = (PtrNotifyWinEvent)QSystemLibrary::resolve(QLatin1String("user32"), "NotifyWinEvent");
- }
- if (!ptrNotifyWinEvent)
- return;
-
- // An event has to be associated with a window,
- // so find the first parent that is a widget and that has a WId
- QAccessibleInterface *iface = event.accessibleInterface();
- QWindow *window = iface ? window_helper(iface) : 0;
- delete iface;
-
- if (!window) {
- window = QGuiApplication::activeWindow();
- if (!window)
- return;
- }
-
- QPlatformNativeInterface *platform = QGuiApplication::platformNativeInterface();
- HWND hWnd = (HWND)platform->nativeResourceForWindow("handle", window);
-
- if (event.type() != QAccessible::MenuCommand) { // MenuCommand is faked
- // See comment "SENDING EVENTS TO OBJECTS WITH NO WINDOW HANDLE"
- eventNum %= 50; //[0..49]
- int eventId = - eventNum - 1;
-
- qAccessibleRecentSentEvents()->insert(eventId, qMakePair(event.object(), event.child()));
- ptrNotifyWinEvent(event.type(), hWnd, OBJID_CLIENT, eventId );
-
- ++eventNum;
- }
-#endif // Q_OS_WINCE
-}
-
-/*
-void QWindowsAccessibility::setRootObject(QObject *o)
-{
-
-}
-
-void QWindowsAccessibility::initialize()
-{
-
-}
-
-void QWindowsAccessibility::cleanup()
-{
-
-}
-
-*/
-
-bool QWindowsAccessibility::handleAccessibleObjectFromWindowRequest(HWND hwnd, WPARAM wParam, LPARAM lParam, LRESULT *lResult)
-{
- if (static_cast<long>(lParam) == static_cast<long>(UiaRootObjectId)) {
- /* For UI Automation
- */
- } else if ((DWORD)lParam == OBJID_CLIENT) {
-#if 1
- // Ignoring all requests while starting up
- // ### Maybe QPA takes care of this???
- if (QApplication::startingUp() || QApplication::closingDown())
- return false;
-#endif
-
- typedef LRESULT (WINAPI *PtrLresultFromObject)(REFIID, WPARAM, LPUNKNOWN);
- static PtrLresultFromObject ptrLresultFromObject = 0;
- static bool oleaccChecked = false;
-
- if (!oleaccChecked) {
- oleaccChecked = true;
-#if !defined(Q_OS_WINCE)
- ptrLresultFromObject = (PtrLresultFromObject)QSystemLibrary::resolve(QLatin1String("oleacc"), "LresultFromObject");
-#endif
- }
-
- if (ptrLresultFromObject) {
- QWindow *window = QWindowsContext::instance()->findWindow(hwnd);
- if (window) {
- QAccessibleInterface *acc = window->accessibleRoot();
- if (acc) {
- QWindowsAccessible *winacc = new QWindowsAccessible(acc);
- IAccessible *iface;
- HRESULT hr = winacc->QueryInterface(IID_IAccessible, (void**)&iface);
- if (SUCCEEDED(hr)) {
- *lResult = ptrLresultFromObject(IID_IAccessible, wParam, iface); // ref == 2
- if (*lResult) {
- iface->Release(); // the client will release the object again, and then it will destroy itself
- }
- return true;
- }
- }
- }
- }
- }
- return false;
-}
-
QT_END_NAMESPACE
#endif //QT_NO_ACCESSIBILITY
diff --git a/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
new file mode 100644
index 0000000000..9cb56c954c
--- /dev/null
+++ b/src/plugins/platforms/windows/accessible/qwindowsmsaaaccessible.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef QWINDOWSMSAAACCESSIBLE_H
+#define QWINDOWSMSAAACCESSIBLE_H
+
+#include <QtCore/QtConfig>
+#ifndef QT_NO_ACCESSIBILITY
+
+#include "../qtwindows_additional.h"
+#include <oleacc.h>
+#include "Accessible2.h"
+#include <QtCore/qsharedpointer.h>
+#include <QtGui/qaccessible.h>
+
+QT_BEGIN_NAMESPACE
+
+#ifndef QT_NO_DEBUG
+bool debug_accessibility();
+# define accessibleDebug !debug_accessibility() ? (void)0 : qDebug
+#else
+# define accessibleDebug
+#endif
+
+#define DEBUG_SHOW_ATCLIENT_COMMANDS
+#if defined(DEBUG_SHOW_ATCLIENT_COMMANDS)
+void accessibleDebugClientCalls_helper(const char* funcName, const QAccessibleInterface *iface);
+# define accessibleDebugClientCalls(iface) accessibleDebugClientCalls_helper(Q_FUNC_INFO, iface)
+#else
+# define accessibleDebugClientCalls(iface)
+#endif
+
+typedef QSharedPointer<QAccessibleInterface> QAIPointer;
+
+QWindow *window_helper(const QAccessibleInterface *iface);
+
+/**************************************************************\
+ * QWindowsAccessible *
+ **************************************************************/
+class QWindowsMsaaAccessible : public IAccessible2, public IOleWindow
+{
+public:
+ QWindowsMsaaAccessible(QAccessibleInterface *a)
+ : accessible(a)
+ {
+ }
+
+ virtual ~QWindowsMsaaAccessible()
+ {
+ delete accessible;
+ }
+
+
+ /* IDispatch */
+ HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *);
+ HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int, unsigned long, ITypeInfo **);
+ HRESULT STDMETHODCALLTYPE GetIDsOfNames(const _GUID &, wchar_t **, unsigned int, unsigned long, long *);
+ HRESULT STDMETHODCALLTYPE Invoke(long, const _GUID &, unsigned long, unsigned short, tagDISPPARAMS *, tagVARIANT *, tagEXCEPINFO *, unsigned int *);
+
+ /* IAccessible */
+ HRESULT STDMETHODCALLTYPE accHitTest(long xLeft, long yTop, VARIANT *pvarID);
+ HRESULT STDMETHODCALLTYPE accLocation(long *pxLeft, long *pyTop, long *pcxWidth, long *pcyHeight, VARIANT varID);
+ HRESULT STDMETHODCALLTYPE accNavigate(long navDir, VARIANT varStart, VARIANT *pvarEnd);
+ HRESULT STDMETHODCALLTYPE get_accChild(VARIANT varChildID, IDispatch** ppdispChild);
+ HRESULT STDMETHODCALLTYPE get_accChildCount(long* pcountChildren);
+ HRESULT STDMETHODCALLTYPE get_accParent(IDispatch** ppdispParent);
+
+ HRESULT STDMETHODCALLTYPE accDoDefaultAction(VARIANT varID);
+ HRESULT STDMETHODCALLTYPE get_accDefaultAction(VARIANT varID, BSTR* pszDefaultAction);
+ HRESULT STDMETHODCALLTYPE get_accDescription(VARIANT varID, BSTR* pszDescription);
+ HRESULT STDMETHODCALLTYPE get_accHelp(VARIANT varID, BSTR *pszHelp);
+ HRESULT STDMETHODCALLTYPE get_accHelpTopic(BSTR *pszHelpFile, VARIANT varChild, long *pidTopic);
+ HRESULT STDMETHODCALLTYPE get_accKeyboardShortcut(VARIANT varID, BSTR *pszKeyboardShortcut);
+ HRESULT STDMETHODCALLTYPE get_accName(VARIANT varID, BSTR* pszName);
+ HRESULT STDMETHODCALLTYPE put_accName(VARIANT varChild, BSTR szName);
+ HRESULT STDMETHODCALLTYPE get_accRole(VARIANT varID, VARIANT *pvarRole);
+ HRESULT STDMETHODCALLTYPE get_accState(VARIANT varID, VARIANT *pvarState);
+ HRESULT STDMETHODCALLTYPE get_accValue(VARIANT varID, BSTR* pszValue);
+ HRESULT STDMETHODCALLTYPE put_accValue(VARIANT varChild, BSTR szValue);
+
+ HRESULT STDMETHODCALLTYPE accSelect(long flagsSelect, VARIANT varID);
+ HRESULT STDMETHODCALLTYPE get_accFocus(VARIANT *pvarID);
+ HRESULT STDMETHODCALLTYPE get_accSelection(VARIANT *pvarChildren);
+
+ /* IOleWindow */
+ HRESULT STDMETHODCALLTYPE GetWindow(HWND *phwnd);
+ HRESULT STDMETHODCALLTYPE ContextSensitiveHelp(BOOL fEnterMode);
+
+protected:
+ QAccessibleInterface *accessible;
+
+ QAIPointer childPointer(VARIANT varID)
+ {
+ return QAIPointer(accessible->child(varID.lVal - 1));
+ }
+};
+
+QT_END_NAMESPACE
+
+#endif //QT_NO_ACCESSIBILITY
+
+#endif // QWINDOWSMSAAACCESSIBLE_H
diff --git a/src/plugins/platforms/windows/qtwindows_additional.h b/src/plugins/platforms/windows/qtwindows_additional.h
index ac768e2dab..3465d4ab1e 100644
--- a/src/plugins/platforms/windows/qtwindows_additional.h
+++ b/src/plugins/platforms/windows/qtwindows_additional.h
@@ -71,6 +71,16 @@
#define IFACEMETHODIMP STDMETHODIMP
#define IFACEMETHODIMP_(type) STDMETHODIMP_(type)
+// For accessibility:
+#ifdef __cplusplus
+ #define EXTERN_C extern "C"
+#else
+ #define EXTERN_C extern
+#endif
+
+#define CHILDID_SELF 0
+#define WM_GETOBJECT 0x003D
+
#if !defined(__MINGW64_VERSION_MAJOR)
#define STATE_SYSTEM_HASPOPUP 0x40000000
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 2706e02cf8..f61e40ef77 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -47,7 +47,7 @@
#include "qtwindowsglobal.h"
#include "qwindowsmime.h"
#include "qwindowsinputcontext.h"
-#include "qwindowsaccessibility.h"
+#include "accessible/qwindowsaccessibility.h"
#include "qwindowsscreen.h"
#include "qwindowstheme.h"
@@ -788,7 +788,8 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
QWindowSystemInterface::handleCloseEvent(platformWindow->window());
return true;
case QtWindows::ThemeChanged: // ### fixme: Compress these events?
- QWindowsTheme::instance()->windowsThemeChanged(platformWindow->window());
+ if (QWindowsTheme *theme = QWindowsTheme::instance())
+ theme->windowsThemeChanged(platformWindow->window());
return true;
default:
break;
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 5094ad9dc3..e0be731b53 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -1065,9 +1065,17 @@ static inline int verticalDPI()
return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
}
-QFont QWindowsFontDatabase::defaultFont() const
+QFont QWindowsFontDatabase::systemDefaultFont()
{
- return QWindowsFontDatabaseFT::systemDefaultFont();
+ LOGFONT lf;
+ GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
+ QFont systemFont = QWindowsFontDatabase::LOGFONT_to_QFont(lf);
+ // "MS Shell Dlg 2" is the correct system font >= Win2k
+ if (systemFont.family() == QStringLiteral("MS Shell Dlg"))
+ systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
+ if (QWindowsContext::verboseFonts)
+ qDebug() << __FUNCTION__ << systemFont;
+ return systemFont;
}
QFont QWindowsFontDatabase::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h
index 04d6ccdd91..f8f2a1eb85 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h
@@ -85,7 +85,8 @@ public:
virtual void releaseHandle(void *handle);
virtual QString fontDir() const;
- virtual QFont defaultFont() const;
+ virtual QFont defaultFont() const { return systemDefaultFont(); }
+ static QFont systemDefaultFont();
static QFontEngine *createEngine(int script, const QFontDef &request,
HDC fontHdc, int dpi, bool rawMode,
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
index fcce87d0bd..f90a880cd3 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qwindowsfontdatabase_ft.h"
+#include "qwindowsfontdatabase.h"
#include "qwindowscontext.h"
#include <ft2build.h>
@@ -460,17 +461,9 @@ static inline int verticalDPI()
return GetDeviceCaps(QWindowsContext::instance()->displayContext(), LOGPIXELSY);
}
-QFont QWindowsFontDatabaseFT::systemDefaultFont()
+QFont QWindowsFontDatabaseFT::defaultFont() const
{
- LOGFONT lf;
- GetObject(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
- QFont systemFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(lf);
- // "MS Shell Dlg 2" is the correct system font >= Win2k
- if (systemFont.family() == QStringLiteral("MS Shell Dlg"))
- systemFont.setFamily(QStringLiteral("MS Shell Dlg 2"));
- if (QWindowsContext::verboseFonts)
- qDebug() << __FUNCTION__ << systemFont;
- return systemFont;
+ return QWindowsFontDatabase::systemDefaultFont();
}
QFont QWindowsFontDatabaseFT::LOGFONT_to_QFont(const LOGFONT& logFont, int verticalDPI_In)
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
index 4136b75dd8..24810c9202 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.h
@@ -59,8 +59,7 @@ public:
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
virtual QString fontDir() const;
- virtual QFont defaultFont() const { return systemDefaultFont(); }
- static QFont systemDefaultFont();
+ virtual QFont defaultFont() const;
static HFONT systemFont();
static QFont LOGFONT_to_QFont(const LOGFONT& lf, int verticalDPI = 0);
diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp
index 3c2ece58d0..ee58a19ca9 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.cpp
+++ b/src/plugins/platforms/windows/qwindowsintegration.cpp
@@ -55,8 +55,8 @@
#include "qwindowsclipboard.h"
#include "qwindowsdrag.h"
#include "qwindowsinputcontext.h"
-#include "qwindowsaccessibility.h"
#include "qwindowskeymapper.h"
+#include "accessible/qwindowsaccessibility.h"
#include <QtGui/QPlatformNativeInterface>
#include <QtGui/QWindowSystemInterface>
@@ -183,7 +183,6 @@ struct QWindowsIntegrationPrivate
QOpenGLStaticContextPtr m_staticOpenGLContext;
QWindowsInputContext m_inputContext;
QWindowsAccessibility m_accessibility;
- QWindowsTheme m_theme;
QWindowsServices m_services;
};
@@ -362,9 +361,16 @@ QAbstractEventDispatcher * QWindowsIntegration::guiThreadEventDispatcher() const
return d->m_eventDispatcher;
}
-QPlatformTheme *QWindowsIntegration::platformTheme() const
+QStringList QWindowsIntegration::themeNames() const
{
- return &d->m_theme;
+ return QStringList(QLatin1String(QWindowsTheme::name));
+}
+
+QPlatformTheme *QWindowsIntegration::createPlatformTheme(const QString &name) const
+{
+ if (name == QLatin1String(QWindowsTheme::name))
+ return new QWindowsTheme;
+ return QPlatformIntegration::createPlatformTheme(name);
}
QPlatformServices *QWindowsIntegration::services() const
diff --git a/src/plugins/platforms/windows/qwindowsintegration.h b/src/plugins/platforms/windows/qwindowsintegration.h
index 6dd65a02e4..20fd790bfe 100644
--- a/src/plugins/platforms/windows/qwindowsintegration.h
+++ b/src/plugins/platforms/windows/qwindowsintegration.h
@@ -69,7 +69,8 @@ public:
virtual QPlatformAccessibility *accessibility() const;
virtual QPlatformNativeInterface *nativeInterface() const;
virtual QPlatformFontDatabase *fontDatabase() const;
- virtual QPlatformTheme *platformTheme() const;
+ virtual QStringList themeNames() const;
+ virtual QPlatformTheme *createPlatformTheme(const QString &name) const;
QPlatformServices *services() const;
virtual QVariant styleHint(StyleHint hint) const;
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 10b4682ad8..f3a9d91d00 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -44,7 +44,7 @@
#include "qwindowscontext.h"
#include "qwindowsintegration.h"
#include "qt_windows.h"
-#include "qwindowsfontdatabase_ft.h"
+#include "qwindowsfontdatabase.h"
#include <QtCore/QVariant>
#include <QtCore/QCoreApplication>
@@ -229,8 +229,12 @@ static inline QPalette *menuBarPalette(const QPalette &menuPalette)
return result;
}
+const char *QWindowsTheme::name = "windows";
+QWindowsTheme *QWindowsTheme::m_instance = 0;
+
QWindowsTheme::QWindowsTheme()
{
+ m_instance = this;
qFill(m_fonts, m_fonts + NFonts, static_cast<QFont *>(0));
qFill(m_palettes, m_palettes + NPalettes, static_cast<QPalette *>(0));
refresh();
@@ -240,11 +244,7 @@ QWindowsTheme::~QWindowsTheme()
{
clearPalettes();
clearFonts();
-}
-
-QWindowsTheme *QWindowsTheme::instance()
-{
- return static_cast<QWindowsTheme *>(QWindowsIntegration::instance()->platformTheme());
+ m_instance = 0;
}
static inline QStringList iconThemeSearchPaths()
@@ -325,16 +325,16 @@ void QWindowsTheme::refreshFonts()
ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICS, lfMessageFont) + sizeof(LOGFONT);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, ncm.cbSize , &ncm, 0);
- const QFont menuFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfMenuFont);
- const QFont messageBoxFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfMessageFont);
- const QFont statusFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfStatusFont);
- const QFont titleFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(ncm.lfCaptionFont);
+ const QFont menuFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMenuFont);
+ const QFont messageBoxFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfMessageFont);
+ const QFont statusFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfStatusFont);
+ const QFont titleFont = QWindowsFontDatabase::LOGFONT_to_QFont(ncm.lfCaptionFont);
LOGFONT lfIconTitleFont;
SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lfIconTitleFont), &lfIconTitleFont, 0);
- const QFont iconTitleFont = QWindowsFontDatabaseFT::LOGFONT_to_QFont(lfIconTitleFont);
+ const QFont iconTitleFont = QWindowsFontDatabase::LOGFONT_to_QFont(lfIconTitleFont);
- m_fonts[SystemFont] = new QFont(QWindowsFontDatabaseFT::systemDefaultFont());
+ m_fonts[SystemFont] = new QFont(QWindowsFontDatabase::systemDefaultFont());
m_fonts[MenuFont] = new QFont(menuFont);
m_fonts[MenuBarFont] = new QFont(menuFont);
m_fonts[MessageBoxFont] = new QFont(messageBoxFont);
diff --git a/src/plugins/platforms/windows/qwindowstheme.h b/src/plugins/platforms/windows/qwindowstheme.h
index 37346eed3a..7515a13a72 100644
--- a/src/plugins/platforms/windows/qwindowstheme.h
+++ b/src/plugins/platforms/windows/qwindowstheme.h
@@ -57,7 +57,7 @@ public:
QWindowsTheme();
~QWindowsTheme();
- static QWindowsTheme *instance();
+ static QWindowsTheme *instance() { return m_instance; }
virtual bool usePlatformNativeDialog(DialogType type) const;
virtual QPlatformDialogHelper *createPlatformDialogHelper(DialogType type) const;
@@ -69,6 +69,8 @@ public:
void windowsThemeChanged(QWindow *window);
+ static const char *name;
+
private:
void refresh() { refreshPalettes(); refreshFonts(); }
void clearPalettes();
@@ -76,6 +78,7 @@ private:
void clearFonts();
void refreshFonts();
+ static QWindowsTheme *m_instance;
QPalette *m_palettes[NPalettes];
QFont *m_fonts[NFonts];
};
diff --git a/src/plugins/platforms/windows/windows.pro b/src/plugins/platforms/windows/windows.pro
index bb41fe87fc..87bc7245c4 100644
--- a/src/plugins/platforms/windows/windows.pro
+++ b/src/plugins/platforms/windows/windows.pro
@@ -45,7 +45,6 @@ SOURCES += \
qwindowsdrag.cpp \
qwindowscursor.cpp \
qwindowsinputcontext.cpp \
- qwindowsaccessibility.cpp \
qwindowstheme.cpp \
qwindowsdialoghelpers.cpp \
qwindowsservices.cpp
@@ -73,7 +72,6 @@ HEADERS += \
qwindowscursor.h \
array.h \
qwindowsinputcontext.h \
- qwindowsaccessibility.h \
qwindowstheme.h \
qwindowsdialoghelpers.h \
qwindowsservices.h
@@ -151,5 +149,6 @@ contains(QT_CONFIG, freetype) {
OTHER_FILES += windows.json
+include(accessible/accessible.pri)
target.path += $$[QT_INSTALL_PLUGINS]/platforms
INSTALLS += target
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index fe33bd7153..50d3c4f1b5 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -82,14 +82,15 @@
#include <QtGui/QOpenGLContext>
#include <QtGui/QScreen>
+#ifndef QT_NO_ACCESSIBILITY
#include <QtGui/QPlatformAccessibility>
+#endif
QT_BEGIN_NAMESPACE
QXcbIntegration::QXcbIntegration(const QStringList &parameters)
: m_eventDispatcher(createUnixEventDispatcher()),
- m_services(new QGenericUnixServices),
- m_theme(QGenericUnixTheme::createUnixTheme())
+ m_services(new QGenericUnixServices)
{
QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
@@ -114,7 +115,9 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters)
m_fontDatabase.reset(new QGenericUnixFontDatabase());
m_inputContext.reset(QPlatformInputContextFactory::create());
+#ifndef QT_NO_ACCESSIBILITY
m_accessibility.reset(new QPlatformAccessibility());
+#endif
#if defined(QT_USE_XCB_SHARED_GRAPHICS_CACHE)
m_sharedGraphicsCache.reset(new QXcbSharedGraphicsCache);
@@ -247,10 +250,12 @@ QPlatformInputContext *QXcbIntegration::inputContext() const
return m_inputContext.data();
}
+#ifndef QT_NO_ACCESSIBILITY
QPlatformAccessibility *QXcbIntegration::accessibility() const
{
return m_accessibility.data();
}
+#endif
#if defined(QT_USE_XCB_SHARED_GRAPHICS_CACHE)
static bool sharedGraphicsCacheDisabled()
@@ -277,9 +282,14 @@ QPlatformServices *QXcbIntegration::services() const
return m_services.data();
}
-QPlatformTheme *QXcbIntegration::platformTheme() const
+QStringList QXcbIntegration::themeNames() const
+{
+ return QGenericUnixTheme::themeNames();
+}
+
+QPlatformTheme *QXcbIntegration::createPlatformTheme(const QString &name) const
{
- return m_theme.data();
+ return QGenericUnixTheme::createUnixTheme(name);
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 457f90d6e0..58eebfe716 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -77,7 +77,9 @@ public:
QPlatformInputContext *inputContext() const;
+#ifndef QT_NO_ACCESSIBILITY
QPlatformAccessibility *accessibility() const;
+#endif
#if defined(QT_USE_XCB_SHARED_GRAPHICS_CACHE)
QPlatformSharedGraphicsCache *createPlatformSharedGraphicsCache(const char *cacheId) const;
@@ -85,7 +87,8 @@ public:
QPlatformServices *services() const;
- QPlatformTheme *platformTheme() const;
+ QStringList themeNames() const;
+ QPlatformTheme *createPlatformTheme(const QString &name) const;
private:
QList<QXcbConnection *> m_connections;
@@ -96,14 +99,15 @@ private:
QScopedPointer<QPlatformInputContext> m_inputContext;
QAbstractEventDispatcher *m_eventDispatcher;
+#ifndef QT_NO_ACCESSIBILITY
QScopedPointer<QPlatformAccessibility> m_accessibility;
+#endif
#if defined(QT_USE_XCB_SHARED_GRAPHICS_CACHE)
QScopedPointer<QPlatformSharedGraphicsCache> m_sharedGraphicsCache;
#endif
QScopedPointer<QPlatformServices> m_services;
- QScopedPointer<QPlatformTheme> m_theme;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 055defde08..4de3734c22 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -549,7 +549,8 @@ void QXcbWindow::show()
updateNetWmStateBeforeMap();
}
- updateNetWmUserTime(connection()->time());
+ if (connection()->time() != CurrentTime)
+ updateNetWmUserTime(connection()->time());
Q_XCB_CALL(xcb_map_window(xcb_connection(), m_window));
xcb_flush(xcb_connection());
@@ -1306,7 +1307,7 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
{
bool fromSendEvent = (event->response_type & 0x80);
QPoint pos(event->x, event->y);
- if (!fromSendEvent) {
+ if (!parent() && !fromSendEvent) {
// Do not trust the position, query it instead.
xcb_translate_coordinates_cookie_t cookie = xcb_translate_coordinates(xcb_connection(), xcb_window(),
m_screen->root(), 0, 0);
diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp
index 51621408b9..b2d44cf084 100644
--- a/src/plugins/platforms/xlib/qglxintegration.cpp
+++ b/src/plugins/platforms/xlib/qglxintegration.cpp
@@ -41,7 +41,6 @@
#include <QDebug>
#include <QLibrary>
-#include <QGLFormat>
#include "qxlibwindow.h"
#include "qxlibscreen.h"
diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.cpp b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
index 590d582661..1ebf22b7ba 100644
--- a/src/plugins/platforms/xlib/qxlibkeyboard.cpp
+++ b/src/plugins/platforms/xlib/qxlibkeyboard.cpp
@@ -48,6 +48,10 @@
#include <QtCore/QTextCodec>
+#if defined(QT_LINUXBASE)
+# include <X11/keysymdef.h>
+#endif
+
#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
#endif
diff --git a/src/plugins/platforms/xlib/qxlibwindow.cpp b/src/plugins/platforms/xlib/qxlibwindow.cpp
index 94c4332e65..00403aed64 100644
--- a/src/plugins/platforms/xlib/qxlibwindow.cpp
+++ b/src/plugins/platforms/xlib/qxlibwindow.cpp
@@ -62,7 +62,8 @@
#include <QtGui/QWindowSystemInterface>
#include <QSocketNotifier>
-#include <QApplication>
+#include <QGuiApplication>
+#include <QStyleHints>
#include <QDebug>
//#define MYX11_DEBUG
@@ -379,10 +380,11 @@ void QXlibWindow::mousePressEvent(XButtonEvent *e)
QEvent::Type type = QEvent::MouseButtonPress;
- if (e->window == prevWindow && long(e->time) - prevTime < QApplication::doubleClickInterval()
+ const int doubleClickInterval = qApp->styleHints()->mouseDoubleClickInterval();
+ if (e->window == prevWindow && long(e->time) - prevTime < doubleClickInterval
&& qAbs(e->x - prevX) < 5 && qAbs(e->y - prevY) < 5) {
type = QEvent::MouseButtonDblClick;
- prevTime = e->time - QApplication::doubleClickInterval(); //no double click next time
+ prevTime = e->time - doubleClickInterval; //no double click next time
} else {
prevTime = e->time;
}
@@ -724,7 +726,7 @@ void QXlibWindow::doSizeHints()
s.flags |= USSize;
s.flags |= PSize;
s.flags |= PWinGravity;
- s.win_gravity = QApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
+ s.win_gravity = QGuiApplication::isRightToLeft() ? NorthEastGravity : NorthWestGravity;
XSetWMNormalHints(mScreen->display()->nativeDisplay(), x_window, &s);
}
diff --git a/src/plugins/platforms/xlib/xlib.pro b/src/plugins/platforms/xlib/xlib.pro
index 463130a64b..a4e006f837 100644
--- a/src/plugins/platforms/xlib/xlib.pro
+++ b/src/plugins/platforms/xlib/xlib.pro
@@ -43,7 +43,6 @@ mac {
CONFIG += qpa/genericunixfontdatabase
contains(QT_CONFIG, opengl) {
- QT += opengl
!contains(QT_CONFIG, opengles2) {
# load(qpa/glx/convenience)
HEADERS += qglxintegration.h
diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro
index 177f64c71b..0855847177 100644
--- a/src/plugins/plugins.pro
+++ b/src/plugins/plugins.pro
@@ -2,7 +2,7 @@ TEMPLATE = subdirs
SUBDIRS *= sqldrivers bearer
!contains(QT_CONFIG, no-gui): SUBDIRS *= imageformats
-!isEmpty(QT.widgets.name): SUBDIRS += accessible
+!contains(QT_CONFIG, no-widgets): SUBDIRS += accessible
SUBDIRS += platforms platforminputcontexts generic
diff --git a/src/plugins/printsupport/cocoa/cocoa.json b/src/plugins/printsupport/cocoa/cocoa.json
new file mode 100644
index 0000000000..85c38c42be
--- /dev/null
+++ b/src/plugins/printsupport/cocoa/cocoa.json
@@ -0,0 +1,3 @@
+{
+ "Keys": [ "cocoaprintersupport" ]
+}
diff --git a/src/plugins/printsupport/cocoa/cocoa.pro b/src/plugins/printsupport/cocoa/cocoa.pro
new file mode 100644
index 0000000000..353094cbae
--- /dev/null
+++ b/src/plugins/printsupport/cocoa/cocoa.pro
@@ -0,0 +1,13 @@
+TARGET = cocoaprintersupport
+load(qt_plugin)
+DESTDIR = $$QT.gui.plugins/printsupport
+
+QT += printsupport
+LIBS += -framework Cocoa
+
+SOURCES += main.cpp
+
+OTHER_FILES += cocoa.json
+
+target.path += $$[QT_INSTALL_PLUGINS]/printsupport
+INSTALLS += target
diff --git a/src/plugins/platforms/vnc/main.cpp b/src/plugins/printsupport/cocoa/main.cpp
index 7ec780af53..bc8f2e072c 100644
--- a/src/plugins/platforms/vnc/main.cpp
+++ b/src/plugins/printsupport/cocoa/main.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
-** This file is part of the plugins of the Qt Toolkit.
+** This file is part of the QtPrintSupport module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
@@ -39,35 +39,46 @@
**
****************************************************************************/
-#include "qvncintegration.h"
-#include <qstringlist.h>
-#include <QtGui/QPlatformIntegrationPlugin>
+#include <QtCore/QMetaMethod>
+#include <QtGui/QGuiApplication>
+#include <QtGui/QPlatformNativeInterface>
+#include <QtPrintSupport/QPlatformPrinterSupportPlugin>
QT_BEGIN_NAMESPACE
-class QVNCIntegrationPlugin : public QPlatformIntegrationPlugin
+class QCocoaPrinterSupportPlugin : public QPlatformPrinterSupportPlugin
{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.QPlatformPrinterSupportFactoryInterface" FILE "cocoa.json")
+
public:
QStringList keys() const;
- QPlatformIntegration *create(const QString&, const QStringList &);
+ QPlatformPrinterSupport *create(const QString &);
};
-QStringList QVNCIntegrationPlugin::keys() const
+QStringList QCocoaPrinterSupportPlugin::keys() const
{
- QStringList list;
- list << "VNC";
- return list;
+ return QStringList(QStringLiteral("cocoaprintersupport"));
}
-QPlatformIntegration* QVNCIntegrationPlugin::create(const QString& system, const QStringList& paramList)
+QPlatformPrinterSupport *QCocoaPrinterSupportPlugin::create(const QString &key)
{
- Q_UNUSED(paramList);
- if (system.toLower() == "vnc")
- return new QVNCIntegration(paramList);
-
- return 0;
+ if (key.compare(key, QStringLiteral("cocoaprintersupport"), Qt::CaseInsensitive) != 0)
+ return 0;
+ QGuiApplication *app = qobject_cast<QGuiApplication *>(QCoreApplication::instance());
+ if (!app)
+ return 0;
+ QPlatformNativeInterface *platformNativeInterface = app->platformNativeInterface();
+ int at = platformNativeInterface->metaObject()->indexOfMethod("createPlatformPrinterSupport()");
+ if (at == -1)
+ return 0;
+ QMetaMethod createPlatformPrinterSupport = platformNativeInterface->metaObject()->method(at);
+ QPlatformPrinterSupport *platformPrinterSupport = 0;
+ if (!createPlatformPrinterSupport.invoke(platformNativeInterface, Q_RETURN_ARG(QPlatformPrinterSupport *, platformPrinterSupport)))
+ return 0;
+ return platformPrinterSupport;
}
-Q_EXPORT_PLUGIN2(vnc, QVNCIntegrationPlugin)
-
QT_END_NAMESPACE
+
+#include "main.moc"
diff --git a/src/plugins/printsupport/printsupport.pro b/src/plugins/printsupport/printsupport.pro
index 9298e7981f..547ac42c9e 100644
--- a/src/plugins/printsupport/printsupport.pro
+++ b/src/plugins/printsupport/printsupport.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
+mac: SUBDIRS += cocoa
win32: SUBDIRS += windows