diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2011-07-19 15:14:39 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2011-07-19 15:14:39 (GMT) |
commit | 9ba4a9b4a4068b9b865d0664d43041692d9185d8 (patch) | |
tree | 89a73b70f71f53d4f4312b1bd9b27302a13c8cac | |
parent | 910ac28a68658825dfc5cef894095ec5f93b4759 (diff) | |
parent | 0b720f5126d5a9a22a008914a03f4d276076c12e (diff) | |
download | Qt-9ba4a9b4a4068b9b865d0664d43041692d9185d8.zip Qt-9ba4a9b4a4068b9b865d0664d43041692d9185d8.tar.gz Qt-9ba4a9b4a4068b9b865d0664d43041692d9185d8.tar.bz2 |
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-doc-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-doc-team: (68 commits)
Doc: Added a link to the How to Learn Qt document.
Doc: Fixed shader program snippet.
Doc: Fixed page step sizes in a snippet for QAbstractScrollArea.
Doc: Moved general notes about character conversion.
Fix the timeout calculation for futexes in QMutex.
namespace fix
fix build
get rid of unwanted dependencies and unused header includes
sync qws_dataDir() with coreapp's internal qws_dataDir()
Added Solaris build fix to the changes file.
Documentation fix.
make argument quoting code on windows less arcane
fix argument quoting on windows
Fix potential crash when clicking in a text edit
Compensate for different rounding rule in CG engine
Remove broken link to Symbian.org documentation.
Check engine existence before increasing reference count
Keep reference count for cached font engines in QTextEngine
Optimize text layout.
Fix compiler warning in qtextdocument.cpp
...
72 files changed, 1890 insertions, 864 deletions
diff --git a/dist/changes-4.8.0 b/dist/changes-4.8.0 index ae6d2c5..247a25a 100644 --- a/dist/changes-4.8.0 +++ b/dist/changes-4.8.0 @@ -27,7 +27,9 @@ General Improvements Third party components ---------------------- - - Updated libpng to version x.y.z + - Updated libpng to version 1.5.1 + - Updated libjpeg to version 8c + - Updated zlib to version 1.2.5 **************************************************************************** @@ -62,9 +64,19 @@ QtGui - QTabBar: reduced minimumSizeHint if ElideMode is set. - QComboBox: Fixed a color propagation issue with the lineedit. [QTBUG-5950] + - QGraphicsLayout: Made setInstantInvalidatePropagation() public - Deprecate qGenericMatrixFromMatrix4x4 and qGenericMatrixToMatrix4x4 - QListView diverses optimisations [QTBUG-11438] - QTreeWidget/QListWidget: use localeAwareCompare for string comparisons [QTBUG-10839] + - PNG image I/O: Much improved support for text annotations, including iTXt fields. + - QRawFont and QGlyphRun are introduced for low-level text rendering. [QTBUG-18252] + - QFont: hintingPreference() is introduced to control hinting in font rendering and + subpixel positioning of glyphs for Windows, Mac OS X and X11/raster. [QTBUG-10615] + - Subpixel positioned text layout is supported in raster and OpenGL paint engines. + - QFont: styleName() is added to allow selecting fonts with irregular style names + like UltraLight. [QTBUG-19366] + - Visual text cursor movement behavior is added to QTextEdit and QLineEdit controls, + which can be used as an optional mode for bi-directional text editing. [QTBUG-13859] - Fixed a rare race condition when showing toplevel windows on X11 - Accessibility: Fix potential crash in QDockWidget. - Accessibility: Fix crash when asking for relations of child accessibles. @@ -76,7 +88,8 @@ QtGui - Accessibility: Make QTabWidget child hierarchy consistent. - Accessibility: Report correct window title and application name. - Accessibility: Return text attributes for QTextEdit. - + - Accessibility: Make accessibility work on Windows with alien widgets + - Accessibility: Several enablers for accessible graphicsview and Qt Quick applications. QtNetwork --------- @@ -118,16 +131,23 @@ QtScript Qt for Linux/X11 ---------------- + - Now takes font hinting settings from GConf by default if running in + GNOME desktop. + - Various fixes to FontConfig font matching code to make it consistent + with other X11 programs. [QTBUG-2148, QTBUG-19947, QTBUG-14269] - Added experimental support for armCC - Qt for Windows -------------- - + - DirectWrite experimental text shaping engine is added with subpixel + positioning support. [QTBUG-12678] Qt for Mac OS X --------------- - + - raster graphics system is now made as the default paint engine for + Mac OS X. [QTBUG-12615] + - HarfBuzz can now be used as an optional text layout engine on Mac OS X. + [QTBUG-17728] Qt for Embedded Linux --------------------- @@ -156,7 +176,8 @@ Qt for Windows CE **************************************************************************** * Compiler Specific Changes * **************************************************************************** - +- Sun Studio 12 + * Fixed build issues in the OpenGL module on Solaris with CC 5.9. [QTBUG-19641] **************************************************************************** * Tools * diff --git a/doc/src/deployment/deployment.qdoc b/doc/src/deployment/deployment.qdoc index 47219bf..a13e2b8 100644 --- a/doc/src/deployment/deployment.qdoc +++ b/doc/src/deployment/deployment.qdoc @@ -746,7 +746,7 @@ If the shared library has dependencies that are different from the application using it, the manifest file needs to be embedded into the DLL - binary. Since Qt 4.1.3, the follwoing \c CONFIG options are available for + binary. Since Qt 4.1.3, the following \c CONFIG options are available for embedding manifests: \snippet doc/src/snippets/code/doc_src_deployment.qdoc 20 @@ -1555,15 +1555,4 @@ For more information about creating a \c .sis file and installing it to device see also \l {The Symbian platform - Introduction to Qt#Installing your own applications}{here}. - - \section1 Further Reading - - This document aims to cover the common case for developers who want to - deploy Qt applications on devices using the Smart Installer. It does not - aim to cover every possible way of installing applications, Qt and other - dependencies on a device. - - A wider selection of deployment methods is described in the - \l{Deploying a Qt Application article} on the Symbian Foundation - Developer Wiki. */ diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index 63e11c8..f528bf2 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -425,11 +425,6 @@ */ /*! - \externalpage http://developer.symbian.org/wiki/index.php/Deploying_a_Qt_Application - \title Deploying a Qt Application article -*/ - -/*! \externalpage http://www.ecma-international.org/publications/standards/Ecma-262.htm \title ECMAScript Language Specification */ diff --git a/doc/src/index.qdoc b/doc/src/index.qdoc index bd21a12..af418e0 100644 --- a/doc/src/index.qdoc +++ b/doc/src/index.qdoc @@ -37,7 +37,8 @@ \enddiv \list \o \l{Qt Features Overview} - \o \l{Introduction to Qt Quick}{Qt Quick} + \o \l{How to Learn Qt} + \o \l{Introduction to Qt Quick} \o \l{external: Qt Mobility Manual}{Qt Mobility} \o \l{Qt WebKit} \endlist diff --git a/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp b/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp index aa5225a..812adf9 100644 --- a/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp +++ b/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp @@ -52,7 +52,7 @@ program.bind(); //! [1] program.addShaderFromSourceCode(QGLShader::Vertex, "attribute highp vec4 vertex;\n" - "attribute mediump mat4 matrix;\n" + "uniform highp mat4 matrix;\n" "void main(void)\n" "{\n" " gl_Position = matrix * vertex;\n" @@ -67,7 +67,7 @@ program.link(); program.bind(); int vertexLocation = program.attributeLocation("vertex"); -int matrixLocation = program.attributeLocation("matrix"); +int matrixLocation = program.uniformLocation("matrix"); int colorLocation = program.uniformLocation("color"); //! [1] diff --git a/doc/src/snippets/myscrollarea.cpp b/doc/src/snippets/myscrollarea.cpp index 93b487d..9a41ed8 100644 --- a/doc/src/snippets/myscrollarea.cpp +++ b/doc/src/snippets/myscrollarea.cpp @@ -98,8 +98,8 @@ void MyScrollArea::updateArea() QSize areaSize = viewport()->size(); QSize widgetSize = widget->size(); - verticalScrollBar()->setPageStep(widgetSize.height()); - horizontalScrollBar()->setPageStep(widgetSize.width()); + verticalScrollBar()->setPageStep(areaSize.height()); + horizontalScrollBar()->setPageStep(areaSize.width()); verticalScrollBar()->setRange(0, widgetSize.height() - areaSize.height()); horizontalScrollBar()->setRange(0, widgetSize.width() - areaSize.width()); updateWidgetPosition(); diff --git a/mkspecs/unsupported/win32-g++-cross/qmake.conf b/mkspecs/unsupported/win32-g++-cross/qmake.conf index 01e2f10..0538e86 100644 --- a/mkspecs/unsupported/win32-g++-cross/qmake.conf +++ b/mkspecs/unsupported/win32-g++-cross/qmake.conf @@ -62,6 +62,8 @@ QMAKE_LFLAGS_WINDOWS = -Wl,-subsystem,windows QMAKE_LFLAGS_DLL = -shared QMAKE_LINK_OBJECT_MAX = 10 QMAKE_LINK_OBJECT_SCRIPT= object_script +QMAKE_PREFIX_STATICLIB = lib +QMAKE_EXTENSION_STATICLIB = a QMAKE_LIBS = diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 99479d0..e247533 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -546,6 +546,7 @@ public: AA_S60DontConstructApplicationPanes = 8, AA_S60DisablePartialScreenInputMode = 9, AA_X11InitThreads = 10, + AA_CaptureMultimediaKeys = 11, // Add new attributes before this line AA_AttributeCount diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index ad9e113..dc92866 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -171,6 +171,15 @@ construction in order to make Xlib calls thread-safe. This attribute must be set before QApplication is constructed. + \value AA_CaptureMultimediaKeys Enables application to receive multimedia key events + (play, next, previous etc). This includes also external sources such as headsets. + Application can not use Remote Control framework on Symbian if this attribute is + set. On Symbian, multimedia key event routing may vary between different devices. + For example, application on background may receive multimedia key events only if + it has active audio stream i.e. it is playing music or video. This attribute must + be set before QApplication is constructed. This attribute is only supported in Symbian + platform. + \omitvalue AA_AttributeCount */ diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 1761c0e..510f723 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -46,6 +46,7 @@ #include <qdatetime.h> #include <qdir.h> #include <qfileinfo.h> +#include <qregexp.h> #include <qtimer.h> #include <qthread.h> #include <qmutex.h> @@ -256,24 +257,19 @@ static QString qt_create_commandline(const QString &program, const QStringList & for (int i=0; i<arguments.size(); ++i) { QString tmp = arguments.at(i); - // in the case of \" already being in the string the \ must also be escaped - tmp.replace( QLatin1String("\\\""), QLatin1String("\\\\\"") ); - // escape a single " because the arguments will be parsed - tmp.replace( QLatin1Char('\"'), QLatin1String("\\\"") ); + // Quotes are escaped and their preceding backslashes are doubled. + tmp.replace(QRegExp(QLatin1String("(\\\\*)\"")), QLatin1String("\\1\\1\\\"")); if (tmp.isEmpty() || tmp.contains(QLatin1Char(' ')) || tmp.contains(QLatin1Char('\t'))) { // The argument must not end with a \ since this would be interpreted // as escaping the quote -- rather put the \ behind the quote: e.g. // rather use "foo"\ than "foo\" - QString endQuote(QLatin1Char('\"')); int i = tmp.length(); - while (i>0 && tmp.at(i-1) == QLatin1Char('\\')) { + while (i > 0 && tmp.at(i - 1) == QLatin1Char('\\')) --i; - endQuote += QLatin1Char('\\'); - } - args += QLatin1String(" \"") + tmp.left(i) + endQuote; - } else { - args += QLatin1Char(' ') + tmp; + tmp.insert(i, QLatin1Char('"')); + tmp.prepend(QLatin1Char('"')); } + args += QLatin1Char(' ') + tmp; } return args; } diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d551009..4226f9e 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -106,6 +106,19 @@ folding rules in QUrl conform to \l{RFC 3491} (Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)). + \section2 Character Conversions + + Follow these rules to avoid erroneous character conversion when + dealing with URLs and strings: + + \list + \o When creating an QString to contain a URL from a QByteArray or a + char*, always use QString::fromUtf8(). + \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of + QUrl(string) and QUrl::toString() when converting a QUrl to or from + a string. + \endlist + \sa QUrlInfo */ @@ -6514,16 +6527,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \o hostname becomes http://hostname \o /home/user/test.html becomes file:///home/user/test.html \endlist - - \section2 Tips to avoid erroneous character conversion when dealing with - URLs and strings: - - \list - \o When creating an URL QString from a QByteArray or a char*, always use - QString::fromUtf8(). - \o Favor the use of QUrl::fromEncoded() and QUrl::toEncoded() instead of - QUrl(string) and QUrl::toString() when converting QUrl to/from string. - \endlist */ QUrl QUrl::fromUserInput(const QString &userInput) { diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index 12bc795..e692e19 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -60,6 +60,7 @@ # include <linux/futex.h> # include <sys/syscall.h> # include <unistd.h> +# include <QtCore/qelapsedtimer.h> #endif QT_BEGIN_NAMESPACE @@ -138,16 +139,31 @@ static inline int _q_futex(volatile int *addr, int op, int val, const struct tim bool QMutexPrivate::wait(int timeout) { + struct timespec ts, *pts = 0; + QElapsedTimer timer; + if (timeout >= 0) { + ts.tv_nsec = ((timeout % 1000) * 1000) * 1000; + ts.tv_sec = (timeout / 1000); + pts = &ts; + timer.start(); + } while (contenders.fetchAndStoreAcquire(2) > 0) { - struct timespec ts, *pts = 0; - if (timeout >= 0) { - ts.tv_nsec = ((timeout % 1000) * 1000) * 1000; - ts.tv_sec = (timeout / 1000); - pts = &ts; - } int r = _q_futex(&contenders._q_value, FUTEX_WAIT, 2, pts, 0, 0); if (r != 0 && errno == ETIMEDOUT) return false; + + if (pts) { + // recalculate the timeout + qint64 xtimeout = timeout * 1000 * 1000; + xtimeout -= timer.nsecsElapsed(); + if (xtimeout < 0) { + // timer expired after we returned + return false; + } + + ts.tv_sec = timeout / Q_INT64_C(1000) / 1000 / 1000; + ts.tv_nsec = timeout % (Q_INT64_C(1000) * 1000 * 1000); + } } return true; } diff --git a/src/corelib/tools/qelapsedtimer_win.cpp b/src/corelib/tools/qelapsedtimer_win.cpp index cd076a6..d79dc5d 100644 --- a/src/corelib/tools/qelapsedtimer_win.cpp +++ b/src/corelib/tools/qelapsedtimer_win.cpp @@ -42,14 +42,14 @@ #include "qelapsedtimer.h" #include <windows.h> -// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable -static quint64 counterFrequency = 0; - typedef ULONGLONG (WINAPI *PtrGetTickCount64)(void); static PtrGetTickCount64 ptrGetTickCount64 = 0; QT_BEGIN_NAMESPACE +// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable +static quint64 counterFrequency = 0; + static void resolveLibs() { static bool done = false; diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index 36a9c60..e68ddd5 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -237,7 +237,7 @@ void **QListData::append(int n) if (b - n >= 2 * d->alloc / 3) { // we have enough space. Just not at the end -> move it. e -= b; - ::memcpy(d->array, d->array + b, e * sizeof(void *)); + ::memmove(d->array, d->array + b, e * sizeof(void *)); d->begin = 0; } else { realloc(grow(d->alloc + n)); diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h index 2159512..f4689b4 100644 --- a/src/corelib/tools/qstringlist.h +++ b/src/corelib/tools/qstringlist.h @@ -71,7 +71,7 @@ public: inline QStringList(const QStringList &l) : QList<QString>(l) { } inline QStringList(const QList<QString> &l) : QList<QString>(l) { } #ifdef Q_COMPILER_INITIALIZER_LISTS - inline QStringList(std::initializer_list<QString> args) : QList(args) { } + inline QStringList(std::initializer_list<QString> args) : QList<QString>(args) { } #endif inline void sort(); diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro index 08c9ea1..d21b380 100644 --- a/src/dbus/dbus.pro +++ b/src/dbus/dbus.pro @@ -44,7 +44,8 @@ PUB_HEADERS = qdbusargument.h \ qdbusmetatype.h \ qdbuspendingcall.h \ qdbuspendingreply.h \ - qdbuscontext.h + qdbuscontext.h \ + qdbusvirtualobject.h HEADERS += $$PUB_HEADERS \ qdbusconnection_p.h \ qdbusmessage_p.h \ @@ -60,7 +61,8 @@ HEADERS += $$PUB_HEADERS \ qdbuspendingcall_p.h \ qdbus_symbols_p.h \ qdbusservicewatcher.h \ - qdbusunixfiledescriptor.h + qdbusunixfiledescriptor.h \ + qdbusvirtualobject.h SOURCES += qdbusconnection.cpp \ qdbusconnectioninterface.cpp \ qdbuserror.cpp \ @@ -87,4 +89,5 @@ SOURCES += qdbusconnection.cpp \ qdbuspendingreply.cpp \ qdbus_symbols.cpp \ qdbusservicewatcher.cpp \ - qdbusunixfiledescriptor.cpp + qdbusunixfiledescriptor.cpp \ + qdbusvirtualobject.cpp diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 0b4133c..e524103 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -222,6 +222,18 @@ void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionP */ /*! + \internal + \since 4.8 + \enum QDBusConnection::VirtualObjectRegisterOption + Specifies the options for registering virtual objects with the connection. The possible values are: + + \value SingleNode register a virtual object to handle one path only + \value SubPath register a virtual object so that it handles all sub paths + + \sa registerVirtualObject(), QDBusVirtualObject +*/ + +/*! \enum QDBusConnection::UnregisterMode The mode for unregistering an object path: @@ -801,9 +813,21 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis // this node exists // consider it free if there's no object here and the user is not trying to // replace the object sub-tree - if ((options & ExportChildObjects && !node->children.isEmpty()) || node->obj) + if (node->obj) return false; + if (options & QDBusConnectionPrivate::VirtualObject) { + // technically the check for children needs to go even deeper + if (options & SubPath) { + foreach (const QDBusConnectionPrivate::ObjectTreeNode &child, node->children) { + if (child.obj) + return false; + } + } + } else { + if ((options & ExportChildObjects && !node->children.isEmpty())) + return false; + } // we can add the object here node->obj = object; node->flags = options; @@ -813,6 +837,13 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis return true; } + // if a virtual object occupies this path, return false + if (node->obj && (node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath)) { + qDebug("Cannot register object at %s because QDBusVirtualObject handles all sub-paths.", + qPrintable(path)); + return false; + } + // find the position where we'd insert the node QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = qLowerBound(node->children.begin(), node->children.end(), pathComponents.at(i)); @@ -841,6 +872,21 @@ bool QDBusConnection::registerObject(const QString &path, QObject *object, Regis } /*! + \internal + \since 4.8 + Registers a QDBusTreeNode for a path. It can handle a path including all child paths, thus + handling multiple DBus nodes. + + To unregister a QDBusTreeNode use the unregisterObject() function with its path. +*/ +bool QDBusConnection::registerVirtualObject(const QString &path, QDBusVirtualObject *treeNode, + VirtualObjectRegisterOption options) +{ + int opts = options | QDBusConnectionPrivate::VirtualObject; + return registerObject(path, (QObject*) treeNode, (RegisterOptions) opts); +} + +/*! Unregisters an object that was registered with the registerObject() at the object path given by \a path and, if \a mode is QDBusConnection::UnregisterTree, all of its sub-objects too. @@ -905,6 +951,8 @@ QObject *QDBusConnection::objectRegisteredAt(const QString &path) const while (node) { if (pathComponents.count() == i) return node->obj; + if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath)) + return node->obj; QDBusConnectionPrivate::ObjectTreeNode::DataList::ConstIterator it = qLowerBound(node->children.constBegin(), node->children.constEnd(), pathComponents.at(i)); @@ -917,6 +965,8 @@ QObject *QDBusConnection::objectRegisteredAt(const QString &path) const return 0; } + + /*! Returns a QDBusConnectionInterface object that represents the D-Bus server interface on this connection. diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h index 4bdd055..8b126af 100644 --- a/src/dbus/qdbusconnection.h +++ b/src/dbus/qdbusconnection.h @@ -69,6 +69,7 @@ class QDBusError; class QDBusMessage; class QDBusPendingCall; class QDBusConnectionInterface; +class QDBusVirtualObject; class QObject; class QDBusConnectionPrivate; @@ -104,8 +105,8 @@ public: // Qt 4.2 had a misspelling here ExportAllSignal = ExportAllSignals, #endif - ExportChildObjects = 0x1000 + // Reserved = 0xff000000 }; enum UnregisterMode { UnregisterNode, @@ -113,6 +114,15 @@ public: }; Q_DECLARE_FLAGS(RegisterOptions, RegisterOption) + enum VirtualObjectRegisterOption { + SingleNode = 0x0, + SubPath = 0x1 + // Reserved = 0xff000000 + }; +#ifndef Q_QDOC + Q_DECLARE_FLAGS(VirtualObjectRegisterOptions, VirtualObjectRegisterOption) +#endif + enum ConnectionCapability { UnixFileDescriptorPassing = 0x0001 }; @@ -163,6 +173,9 @@ public: void unregisterObject(const QString &path, UnregisterMode mode = UnregisterNode); QObject *objectRegisteredAt(const QString &path) const; + bool registerVirtualObject(const QString &path, QDBusVirtualObject *object, + VirtualObjectRegisterOption options = SingleNode); + bool registerService(const QString &serviceName); bool unregisterService(const QString &serviceName); @@ -192,6 +205,7 @@ private: }; Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::RegisterOptions) +Q_DECLARE_OPERATORS_FOR_FLAGS(QDBusConnection::VirtualObjectRegisterOptions) QT_END_NAMESPACE diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 12bcb21..d481cf1 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -129,6 +129,11 @@ public: QByteArray matchRule; }; + enum TreeNodeType { + Object = 0x0, + VirtualObject = 0x01000000 + }; + struct ObjectTreeNode { typedef QVector<ObjectTreeNode> DataList; @@ -143,8 +148,12 @@ public: { return QStringRef(&name) < other; } QString name; - QObject* obj; + union { + QObject *obj; + QDBusVirtualObject *treeNode; + }; int flags; + DataList children; }; @@ -333,7 +342,7 @@ extern bool qDBusInterfaceInObject(QObject *obj, const QString &interface_name); extern QString qDBusInterfaceFromMetaObject(const QMetaObject *mo); // in qdbusinternalfilters.cpp -extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node); +extern QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node, const QString &path); extern QDBusMessage qDBusPropertyGet(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg); extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNode &node, diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index f3f3d0b..2cde07e 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -57,6 +57,7 @@ #include "qdbusabstractadaptor.h" #include "qdbusabstractadaptor_p.h" #include "qdbusutil_p.h" +#include "qdbusvirtualobject.h" #include "qdbusmessage_p.h" #include "qdbuscontext_p.h" #include "qdbuspendingcall_p.h" @@ -442,7 +443,11 @@ static bool findObject(const QDBusConnectionPrivate::ObjectTreeNode *root, // walk the object tree const QDBusConnectionPrivate::ObjectTreeNode *node = root; - while (start < length && node && !(node->flags & QDBusConnection::ExportChildObjects)) { + while (start < length && node) { + if (node->flags & QDBusConnection::ExportChildObjects) + break; + if ((node->flags & QDBusConnectionPrivate::VirtualObject) && (node->flags & QDBusConnection::SubPath)) + break; int end = fullpath.indexOf(QLatin1Char('/'), start); end = (end == -1 ? length : end); QStringRef pathComponent(&fullpath, start, end - start); @@ -1328,7 +1333,7 @@ bool QDBusConnectionPrivate::activateInternalFilters(const ObjectTreeNode &node, if (interface.isEmpty() || interface == QLatin1String(DBUS_INTERFACE_INTROSPECTABLE)) { if (msg.member() == QLatin1String("Introspect") && msg.signature().isEmpty()) { //qDebug() << "QDBusConnectionPrivate::activateInternalFilters introspect" << msg.d_ptr->msg; - QDBusMessage reply = msg.createReply(qDBusIntrospectObject(node)); + QDBusMessage reply = msg.createReply(qDBusIntrospectObject(node, msg.path())); send(reply); return true; } @@ -1375,6 +1380,15 @@ void QDBusConnectionPrivate::activateObject(ObjectTreeNode &node, const QDBusMes // object may be null + if (node.flags & QDBusConnectionPrivate::VirtualObject) { + if (node.treeNode->handleMessage(msg, q(this))) { + return; + } else { + if (activateInternalFilters(node, msg)) + return; + } + } + if (pathStartPos != msg.path().length()) { node.flags &= ~QDBusConnection::ExportAllSignals; node.obj = findChildObject(&node, msg.path(), pathStartPos); diff --git a/src/dbus/qdbusinternalfilters.cpp b/src/dbus/qdbusinternalfilters.cpp index 2b142a7..b874a64 100644 --- a/src/dbus/qdbusinternalfilters.cpp +++ b/src/dbus/qdbusinternalfilters.cpp @@ -56,6 +56,7 @@ #include "qdbusmetatype_p.h" #include "qdbusmessage_p.h" #include "qdbusutil_p.h" +#include "qdbusvirtualobject.h" #ifndef QT_NO_DBUS @@ -108,7 +109,7 @@ static QString generateSubObjectXml(QObject *object) // declared as extern in qdbusconnection_p.h -QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node) +QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node, const QString &path) { // object may be null @@ -155,6 +156,11 @@ QString qDBusIntrospectObject(const QDBusConnectionPrivate::ObjectTreeNode &node } } + // is it a virtual node that handles introspection itself? + if (node.flags & QDBusConnectionPrivate::VirtualObject) { + xml_data += node.treeNode->introspect(path); + } + xml_data += QLatin1String( propertiesInterfaceXml ); } diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h b/src/dbus/qdbusvirtualobject.cpp index 41b1d28..992ccbf 100644 --- a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.h +++ b/src/dbus/qdbusvirtualobject.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtDBus module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,55 +39,59 @@ ** ****************************************************************************/ -#ifndef QGRAPHICSSYSTEM_VGLITE_H -#define QGRAPHICSSYSTEM_VGLITE_H +#include "qdbusvirtualobject.h" -#include <QtGui/private/qgraphicssystem_p.h> -#include <QtGui/private/qegl_p.h> -#include <QtGui/qimage.h> +#ifndef QT_NO_DBUS QT_BEGIN_NAMESPACE -class QVGLiteWindowSurface; +QDBusVirtualObject::QDBusVirtualObject(QObject *parent) : + QObject(parent) +{ +} -class QVGLiteGraphicsSystem : public QGraphicsSystem, - public QGraphicsSystemScreen +QDBusVirtualObject::~QDBusVirtualObject() { -public: - QVGLiteGraphicsSystem(); - ~QVGLiteGraphicsSystem(); +} - QPixmapData *createPixmapData(QPixmapData::PixelType type) const; - QWindowSurface *createWindowSurface(QWidget *widget) const; - QList<QGraphicsSystemScreen *> screens() const { return mScreens; } +QT_END_NAMESPACE - QRect geometry() const { return QRect(0, 0, w, h); } - int depth() const { return d; } - QImage::Format format() const { return screenFormat; } - QSize physicalSize() const { return QSize(physWidth, physHeight); } -private: - friend class QVGLiteWindowSurface; +/*! + \internal + \class QDBusVirtualObject + \inmodule QtDBus + \since 4.8 - int w; - int h; - int d; + \brief The QDBusVirtualObject class is used to handle several DBus paths with one class. +*/ - int dw; - int dh; +/*! + \internal + \fn bool QDBusVirtualObject::handleMessage(const QDBusMessage &message, const QDBusConnection &connection) = 0 - int physWidth; - int physHeight; + This function needs to handle all messages to the path of the + virtual object, when the SubPath option is specified. + The service, path, interface and methos are all part of the message. + Must return true when the message is handled, otherwise false (will generate dbus error message). +*/ - mutable QVGLiteWindowSurface *surface; - QEglContext *context; - EGLSurface rootWindow; - QImage::Format screenFormat; - bool preservedSwap; - QList<QGraphicsSystemScreen *> mScreens; -}; +/*! + \internal + \fn QString QDBusVirtualObject::introspect(const QString &path) const -QT_END_NAMESPACE + This function needs to handle the introspection of the + virtual object. It must return xml of the form: + + \code +<interface name="com.trolltech.QtDBus.MyObject" > + <property access="readwrite" type="i" name="prop1" /> +</interface> + \endcode + + If you pass the SubPath option, this introspection has to include all child nodes. + Otherwise QDBus handles the introspection of the child nodes. +*/ -#endif +#endif // QT_NO_DBUS diff --git a/src/plugins/platforms/openvglite/main.cpp b/src/dbus/qdbusvirtualobject.h index 19220a6..be323de 100644 --- a/src/plugins/platforms/openvglite/main.cpp +++ b/src/dbus/qdbusvirtualobject.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the QtDBus module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,33 +39,43 @@ ** ****************************************************************************/ -#include <private/qgraphicssystemplugin_p.h> -#include "qgraphicssystem_vglite.h" +#ifndef QDBUSTREENODE_H +#define QDBUSTREENODE_H + +#include <QtDBus/qdbusmacros.h> +#include <QtCore/qstring.h> +#include <QtCore/qobject.h> + +#ifndef QT_NO_DBUS + +QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QVGGraphicsSystemPlugin : public QGraphicsSystemPlugin -{ -public: - QStringList keys() const; - QGraphicsSystem *create(const QString&); -}; +QT_MODULE(DBus) -QStringList QVGGraphicsSystemPlugin::keys() const -{ - QStringList list; - list << "OpenVG"; - return list; -} +class QDBusMessage; +class QDBusConnection; -QGraphicsSystem* QVGGraphicsSystemPlugin::create(const QString& system) +class QDBusVirtualObjectPrivate; +class Q_DBUS_EXPORT QDBusVirtualObject : public QObject { - if (system.toLower() == "openvg") - return new QVGLiteGraphicsSystem; + Q_OBJECT +public: + explicit QDBusVirtualObject(QObject *parent = 0); + virtual ~QDBusVirtualObject(); - return 0; -} + virtual QString introspect(const QString &path) const = 0; + virtual bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) = 0; -Q_EXPORT_PLUGIN2(openvg, QVGGraphicsSystemPlugin) +private: + Q_DECLARE_PRIVATE(QDBusVirtualObject) + Q_DISABLE_COPY(QDBusVirtualObject) +}; QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QT_NO_DBUS +#endif diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 7014571..3fd4fcd 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -560,13 +560,11 @@ QRect QDeclarativeTextInput::cursorRectangle() const \qmlproperty int TextInput::selectionStart The cursor position before the first character in the current selection. - Setting this and selectionEnd allows you to specify a selection in the - text edit. - Note that if selectionStart == selectionEnd then there is no current - selection. + This property is read-only. To change the selection, use select(start,end), + selectAll(), or selectWord(). - \sa selectionEnd, cursorPosition, selectedText, select() + \sa selectionEnd, cursorPosition, selectedText */ int QDeclarativeTextInput::selectionStart() const { @@ -578,13 +576,11 @@ int QDeclarativeTextInput::selectionStart() const \qmlproperty int TextInput::selectionEnd The cursor position after the last character in the current selection. - Setting this and selectionStart allows you to specify a selection in the - text edit. - Note that if selectionStart == selectionEnd then there is no current - selection. + This property is read-only. To change the selection, use select(start,end), + selectAll(), or selectWord(). - \sa selectionStart, cursorPosition, selectedText, select() + \sa selectionStart, cursorPosition, selectedText */ int QDeclarativeTextInput::selectionEnd() const { diff --git a/src/gui/accessible/qaccessible2.cpp b/src/gui/accessible/qaccessible2.cpp index 35b24f6..078ff13 100644 --- a/src/gui/accessible/qaccessible2.cpp +++ b/src/gui/accessible/qaccessible2.cpp @@ -42,6 +42,7 @@ #include "qaccessible2.h" #include "qapplication.h" #include "qclipboard.h" +#include "qtextboundaryfinder.h" #ifndef QT_NO_ACCESSIBILITY @@ -132,6 +133,117 @@ QT_BEGIN_NAMESPACE \link http://www.linux-foundation.org/en/Accessibility/IAccessible2 IAccessible2 Specification \endlink */ + +/*! + \internal +*/ +QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType, + int *startOffset, int *endOffset, const QString& text) +{ + QTextBoundaryFinder::BoundaryType type; + switch (boundaryType) { + case QAccessible2::CharBoundary: + type = QTextBoundaryFinder::Grapheme; + break; + case QAccessible2::WordBoundary: + type = QTextBoundaryFinder::Word; + break; + case QAccessible2::SentenceBoundary: + type = QTextBoundaryFinder::Sentence; + break; + default: + // in any other case return the whole line + *startOffset = 0; + *endOffset = text.length(); + return text; + } + + QTextBoundaryFinder boundary(type, text); + boundary.setPosition(offset); + + if (!boundary.isAtBoundary()) { + boundary.toPreviousBoundary(); + } + boundary.toPreviousBoundary(); + *startOffset = boundary.position(); + boundary.toNextBoundary(); + *endOffset = boundary.position(); + + return text.mid(*startOffset, *endOffset - *startOffset); +} + +/*! + \internal +*/ +QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType, + int *startOffset, int *endOffset, const QString& text) +{ + QTextBoundaryFinder::BoundaryType type; + switch (boundaryType) { + case QAccessible2::CharBoundary: + type = QTextBoundaryFinder::Grapheme; + break; + case QAccessible2::WordBoundary: + type = QTextBoundaryFinder::Word; + break; + case QAccessible2::SentenceBoundary: + type = QTextBoundaryFinder::Sentence; + break; + default: + // in any other case return the whole line + *startOffset = 0; + *endOffset = text.length(); + return text; + } + + QTextBoundaryFinder boundary(type, text); + boundary.setPosition(offset); + + boundary.toNextBoundary(); + *startOffset = boundary.position(); + boundary.toNextBoundary(); + *endOffset = boundary.position(); + + return text.mid(*startOffset, *endOffset - *startOffset); +} + +/*! + \internal +*/ +QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType, + int *startOffset, int *endOffset, const QString& text) +{ + QTextBoundaryFinder::BoundaryType type; + switch (boundaryType) { + case QAccessible2::CharBoundary: + type = QTextBoundaryFinder::Grapheme; + break; + case QAccessible2::WordBoundary: + type = QTextBoundaryFinder::Word; + break; + case QAccessible2::SentenceBoundary: + type = QTextBoundaryFinder::Sentence; + break; + default: + // in any other case return the whole line + *startOffset = 0; + *endOffset = text.length(); + return text; + } + + QTextBoundaryFinder boundary(type, text); + boundary.setPosition(offset); + + if (!boundary.isAtBoundary()) { + boundary.toPreviousBoundary(); + } + *startOffset = boundary.position(); + boundary.toNextBoundary(); + *endOffset = boundary.position(); + + return text.mid(*startOffset, *endOffset - *startOffset); +} + QAccessibleSimpleEditableTextInterface::QAccessibleSimpleEditableTextInterface( QAccessibleInterface *accessibleInterface) : iface(accessibleInterface) diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index 6fbe849..d01c3af 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -466,7 +466,6 @@ void QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem *layoutItem) static bool g_instantInvalidatePropagation = false; /*! - \internal \since 4.8 \sa instantInvalidatePropagation() @@ -496,7 +495,6 @@ void QGraphicsLayout::setInstantInvalidatePropagation(bool enable) } /*! - \internal \since 4.8 \sa setInstantInvalidatePropagation() diff --git a/src/gui/kernel/qkeymapper_p.h b/src/gui/kernel/qkeymapper_p.h index 2607c2a..1d624f9 100644 --- a/src/gui/kernel/qkeymapper_p.h +++ b/src/gui/kernel/qkeymapper_p.h @@ -213,6 +213,8 @@ public: int mapS60ScanCodesToQt(TUint s60key); int mapQtToS60Key(int qtKey); int mapQtToS60ScanCodes(int qtKey); + int mapS60RemConIdToS60Key(int s60RemConId); + int mapS60RemConIdToS60ScanCodes(int s60RemConId); void updateInputLanguage(); #endif }; diff --git a/src/gui/kernel/qkeymapper_s60.cpp b/src/gui/kernel/qkeymapper_s60.cpp index 1113b77..2a7083e 100644 --- a/src/gui/kernel/qkeymapper_s60.cpp +++ b/src/gui/kernel/qkeymapper_s60.cpp @@ -87,97 +87,104 @@ QString QKeyMapperPrivate::translateKeyEvent(int keySym, Qt::KeyboardModifiers / } #include <e32keys.h> +#include <remconcoreapi.h> struct KeyMapping{ TKeyCode s60KeyCode; TStdScanCode s60ScanCode; + TRemConCoreApiOperationId s60RemConId; Qt::Key qtKey; }; using namespace Qt; +// key mapping table in the format of +// {S60 key code, S60 scan code, S60 RemCon operation Id, Qt key code} static const KeyMapping keyMapping[] = { - {EKeyBackspace, EStdKeyBackspace, Key_Backspace}, - {EKeyTab, EStdKeyTab, Key_Tab}, - {EKeyEnter, EStdKeyEnter, Key_Enter}, - {EKeyEscape, EStdKeyEscape, Key_Escape}, - {EKeySpace, EStdKeySpace, Key_Space}, - {EKeyDelete, EStdKeyDelete, Key_Delete}, - {EKeyPrintScreen, EStdKeyPrintScreen, Key_SysReq}, - {EKeyPause, EStdKeyPause, Key_Pause}, - {EKeyHome, EStdKeyHome, Key_Home}, - {EKeyEnd, EStdKeyEnd, Key_End}, - {EKeyPageUp, EStdKeyPageUp, Key_PageUp}, - {EKeyPageDown, EStdKeyPageDown, Key_PageDown}, - {EKeyInsert, EStdKeyInsert, Key_Insert}, - {EKeyLeftArrow, EStdKeyLeftArrow, Key_Left}, - {EKeyRightArrow, EStdKeyRightArrow, Key_Right}, - {EKeyUpArrow, EStdKeyUpArrow, Key_Up}, - {EKeyDownArrow, EStdKeyDownArrow, Key_Down}, - {EKeyLeftShift, EStdKeyLeftShift, Key_Shift}, - {EKeyRightShift, EStdKeyRightShift, Key_Shift}, - {EKeyLeftAlt, EStdKeyLeftAlt, Key_Alt}, - {EKeyRightAlt, EStdKeyRightAlt, Key_AltGr}, - {EKeyLeftCtrl, EStdKeyLeftCtrl, Key_Control}, - {EKeyRightCtrl, EStdKeyRightCtrl, Key_Control}, - {EKeyLeftFunc, EStdKeyLeftFunc, Key_Super_L}, - {EKeyRightFunc, EStdKeyRightFunc, Key_Super_R}, - {EKeyCapsLock, EStdKeyCapsLock, Key_CapsLock}, - {EKeyNumLock, EStdKeyNumLock, Key_NumLock}, - {EKeyScrollLock, EStdKeyScrollLock, Key_ScrollLock}, - {EKeyF1, EStdKeyF1, Key_F1}, - {EKeyF2, EStdKeyF2, Key_F2}, - {EKeyF3, EStdKeyF3, Key_F3}, - {EKeyF4, EStdKeyF4, Key_F4}, - {EKeyF5, EStdKeyF5, Key_F5}, - {EKeyF6, EStdKeyF6, Key_F6}, - {EKeyF7, EStdKeyF7, Key_F7}, - {EKeyF8, EStdKeyF8, Key_F8}, - {EKeyF9, EStdKeyF9, Key_F9}, - {EKeyF10, EStdKeyF10, Key_F10}, - {EKeyF11, EStdKeyF11, Key_F11}, - {EKeyF12, EStdKeyF12, Key_F12}, - {EKeyF13, EStdKeyF13, Key_F13}, - {EKeyF14, EStdKeyF14, Key_F14}, - {EKeyF15, EStdKeyF15, Key_F15}, - {EKeyF16, EStdKeyF16, Key_F16}, - {EKeyF17, EStdKeyF17, Key_F17}, - {EKeyF18, EStdKeyF18, Key_F18}, - {EKeyF19, EStdKeyF19, Key_F19}, - {EKeyF20, EStdKeyF20, Key_F20}, - {EKeyF21, EStdKeyF21, Key_F21}, - {EKeyF22, EStdKeyF22, Key_F22}, - {EKeyF23, EStdKeyF23, Key_F23}, - {EKeyF24, EStdKeyF24, Key_F24}, - {EKeyOff, EStdKeyOff, Key_PowerOff}, -// {EKeyMenu, EStdKeyMenu, Key_Menu}, // Menu is EKeyApplication0 - {EKeyHelp, EStdKeyHelp, Key_Help}, - {EKeyDial, EStdKeyDial, Key_Call}, - {EKeyIncVolume, EStdKeyIncVolume, Key_VolumeUp}, - {EKeyDecVolume, EStdKeyDecVolume, Key_VolumeDown}, - {EKeyDevice0, EStdKeyDevice0, Key_Context1}, // Found by manual testing. - {EKeyDevice1, EStdKeyDevice1, Key_Context2}, // Found by manual testing. - {EKeyDevice3, EStdKeyDevice3, Key_Select}, - {EKeyDevice7, EStdKeyDevice7, Key_Camera}, - {EKeyApplication0, EStdKeyApplication0, Key_Menu}, // Found by manual testing. - {EKeyApplication1, EStdKeyApplication1, Key_Launch1}, // Found by manual testing. - {EKeyApplication2, EStdKeyApplication2, Key_MediaPlay}, // Found by manual testing. - {EKeyApplication3, EStdKeyApplication3, Key_MediaStop}, // Found by manual testing. - {EKeyApplication4, EStdKeyApplication4, Key_MediaNext}, // Found by manual testing. - {EKeyApplication5, EStdKeyApplication5, Key_MediaPrevious}, // Found by manual testing. - {EKeyApplication6, EStdKeyApplication6, Key_Launch6}, - {EKeyApplication7, EStdKeyApplication7, Key_Launch7}, - {EKeyApplication8, EStdKeyApplication8, Key_Launch8}, - {EKeyApplication9, EStdKeyApplication9, Key_Launch9}, - {EKeyApplicationA, EStdKeyApplicationA, Key_LaunchA}, - {EKeyApplicationB, EStdKeyApplicationB, Key_LaunchB}, - {EKeyApplicationC, EStdKeyApplicationC, Key_LaunchC}, - {EKeyApplicationD, EStdKeyApplicationD, Key_LaunchD}, - {EKeyApplicationE, EStdKeyApplicationE, Key_LaunchE}, - {EKeyApplicationF, EStdKeyApplicationF, Key_LaunchF}, - {EKeyApplication19, EStdKeyApplication19, Key_CameraFocus}, - {EKeyYes, EStdKeyYes, Key_Yes}, - {EKeyNo, EStdKeyNo, Key_No}, - {TKeyCode(0), TStdScanCode(0), Qt::Key(0)} + {EKeyBackspace, EStdKeyBackspace, ENop, Key_Backspace}, + {EKeyTab, EStdKeyTab, ENop, Key_Tab}, + {EKeyEnter, EStdKeyEnter, ERemConCoreApiEnter, Key_Enter}, + {EKeyEscape, EStdKeyEscape, ENop, Key_Escape}, + {EKeySpace, EStdKeySpace, ENop, Key_Space}, + {EKeyDelete, EStdKeyDelete, ENop, Key_Delete}, + {EKeyPrintScreen, EStdKeyPrintScreen, ENop, Key_SysReq}, + {EKeyPause, EStdKeyPause, ENop, Key_Pause}, + {EKeyHome, EStdKeyHome, ENop, Key_Home}, + {EKeyEnd, EStdKeyEnd, ENop, Key_End}, + {EKeyPageUp, EStdKeyPageUp, ERemConCoreApiPageUp, Key_PageUp}, + {EKeyPageDown, EStdKeyPageDown, ERemConCoreApiPageDown, Key_PageDown}, + {EKeyInsert, EStdKeyInsert, ENop, Key_Insert}, + {EKeyLeftArrow, EStdKeyLeftArrow, ERemConCoreApiLeft, Key_Left}, + {EKeyRightArrow, EStdKeyRightArrow, ERemConCoreApiRight, Key_Right}, + {EKeyUpArrow, EStdKeyUpArrow, ERemConCoreApiUp, Key_Up}, + {EKeyDownArrow, EStdKeyDownArrow, ERemConCoreApiDown, Key_Down}, + {EKeyLeftShift, EStdKeyLeftShift, ENop, Key_Shift}, + {EKeyRightShift, EStdKeyRightShift, ENop, Key_Shift}, + {EKeyLeftAlt, EStdKeyLeftAlt, ENop, Key_Alt}, + {EKeyRightAlt, EStdKeyRightAlt, ENop, Key_AltGr}, + {EKeyLeftCtrl, EStdKeyLeftCtrl, ENop, Key_Control}, + {EKeyRightCtrl, EStdKeyRightCtrl, ENop, Key_Control}, + {EKeyLeftFunc, EStdKeyLeftFunc, ENop, Key_Super_L}, + {EKeyRightFunc, EStdKeyRightFunc, ENop, Key_Super_R}, + {EKeyCapsLock, EStdKeyCapsLock, ENop, Key_CapsLock}, + {EKeyNumLock, EStdKeyNumLock, ENop, Key_NumLock}, + {EKeyScrollLock, EStdKeyScrollLock, ENop, Key_ScrollLock}, + {EKeyF1, EStdKeyF1, ERemConCoreApiF1, Key_F1}, + {EKeyF2, EStdKeyF2, ERemConCoreApiF2, Key_F2}, + {EKeyF3, EStdKeyF3, ERemConCoreApiF3, Key_F3}, + {EKeyF4, EStdKeyF4, ERemConCoreApiF4, Key_F4}, + {EKeyF5, EStdKeyF5, ERemConCoreApiF5, Key_F5}, + {EKeyF6, EStdKeyF6, ENop, Key_F6}, + {EKeyF7, EStdKeyF7, ENop, Key_F7}, + {EKeyF8, EStdKeyF8, ENop, Key_F8}, + {EKeyF9, EStdKeyF9, ENop, Key_F9}, + {EKeyF10, EStdKeyF10, ENop, Key_F10}, + {EKeyF11, EStdKeyF11, ENop, Key_F11}, + {EKeyF12, EStdKeyF12, ENop, Key_F12}, + {EKeyF13, EStdKeyF13, ENop, Key_F13}, + {EKeyF14, EStdKeyF14, ENop, Key_F14}, + {EKeyF15, EStdKeyF15, ENop, Key_F15}, + {EKeyF16, EStdKeyF16, ENop, Key_F16}, + {EKeyF17, EStdKeyF17, ENop, Key_F17}, + {EKeyF18, EStdKeyF18, ENop, Key_F18}, + {EKeyF19, EStdKeyF19, ENop, Key_F19}, + {EKeyF20, EStdKeyF20, ENop, Key_F20}, + {EKeyF21, EStdKeyF21, ENop, Key_F21}, + {EKeyF22, EStdKeyF22, ENop, Key_F22}, + {EKeyF23, EStdKeyF23, ENop, Key_F23}, + {EKeyF24, EStdKeyF24, ENop, Key_F24}, + {EKeyOff, EStdKeyOff, ENop, Key_PowerOff}, +// {EKeyMenu, EStdKeyMenu, ENop, Key_Menu}, // Menu is EKeyApplication0 + {EKeyHelp, EStdKeyHelp, ERemConCoreApiHelp, Key_Help}, + {EKeyDial, EStdKeyDial, ENop, Key_Call}, + {EKeyIncVolume, EStdKeyIncVolume, ERemConCoreApiVolumeUp, Key_VolumeUp}, + {EKeyDecVolume, EStdKeyDecVolume, ERemConCoreApiVolumeDown, Key_VolumeDown}, + {EKeyDevice0, EStdKeyDevice0, ENop, Key_Context1}, // Found by manual testing. + {EKeyDevice1, EStdKeyDevice1, ENop, Key_Context2}, // Found by manual testing. + {EKeyDevice3, EStdKeyDevice3, ERemConCoreApiSelect, Key_Select}, + {EKeyDevice7, EStdKeyDevice7, ENop, Key_Camera}, + {EKeyApplication0, EStdKeyApplication0, ENop, Key_Menu}, // Found by manual testing. + {EKeyApplication1, EStdKeyApplication1, ENop, Key_Launch1}, // Found by manual testing. + {EKeyApplication2, EStdKeyApplication2, ERemConCoreApiPlay, Key_MediaPlay}, // Found by manual testing. + {EKeyApplication3, EStdKeyApplication3, ERemConCoreApiStop, Key_MediaStop}, // Found by manual testing. + {EKeyApplication4, EStdKeyApplication4, ERemConCoreApiForward, Key_MediaNext}, // Found by manual testing. + {EKeyApplication5, EStdKeyApplication5, ERemConCoreApiBackward, Key_MediaPrevious}, // Found by manual testing. + {EKeyApplication6, EStdKeyApplication6, ENop, Key_Launch6}, + {EKeyApplication7, EStdKeyApplication7, ENop, Key_Launch7}, + {EKeyApplication8, EStdKeyApplication8, ENop, Key_Launch8}, + {EKeyApplication9, EStdKeyApplication9, ENop, Key_Launch9}, + {EKeyApplicationA, EStdKeyApplicationA, ENop, Key_LaunchA}, + {EKeyApplicationB, EStdKeyApplicationB, ENop, Key_LaunchB}, + {EKeyApplicationC, EStdKeyApplicationC, ENop, Key_LaunchC}, + {EKeyApplicationD, EStdKeyApplicationD, ENop, Key_LaunchD}, + {EKeyApplicationE, EStdKeyApplicationE, ENop, Key_LaunchE}, + {EKeyApplicationF, EStdKeyApplicationF, ENop, Key_LaunchF}, + {EKeyApplication19, EStdKeyApplication19, ENop, Key_CameraFocus}, + {EKeyYes, EStdKeyYes, ENop, Key_Yes}, + {EKeyNo, EStdKeyNo, ENop, Key_No}, + {EKeyDevice20, EStdKeyDevice20, ERemConCoreApiPausePlayFunction, Key_MediaTogglePlayPause}, + {EKeyDevice21, EStdKeyDevice21, ERemConCoreApiRewind, Key_AudioRewind}, + {EKeyDevice22, EStdKeyDevice22, ERemConCoreApiFastForward, Key_AudioForward}, + {TKeyCode(0), TStdScanCode(0), ENop, Qt::Key(0)} }; int QKeyMapperPrivate::mapS60KeyToQt(TUint s60key) @@ -228,6 +235,30 @@ int QKeyMapperPrivate::mapQtToS60ScanCodes(int qtKey) return res; } +int QKeyMapperPrivate::mapS60RemConIdToS60Key(int s60RemConId) +{ + int res = KErrUnknown; + for (int i = 0; keyMapping[i].s60KeyCode != 0; i++) { + if (keyMapping[i].s60RemConId == s60RemConId) { + res = keyMapping[i].s60KeyCode; + break; + } + } + return res; +} + +int QKeyMapperPrivate::mapS60RemConIdToS60ScanCodes(int s60RemConId) +{ + int res = KErrUnknown; + for (int i = 0; keyMapping[i].s60KeyCode != 0; i++) { + if (keyMapping[i].s60RemConId == s60RemConId) { + res = keyMapping[i].s60ScanCode; + break; + } + } + return res; +} + void QKeyMapperPrivate::updateInputLanguage() { #ifdef Q_WS_S60 diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h index 399dd89..f1f7eb1 100644 --- a/src/gui/painting/qbezier_p.h +++ b/src/gui/painting/qbezier_p.h @@ -162,27 +162,27 @@ inline void QBezier::coefficients(qreal t, qreal &a, qreal &b, qreal &c, qreal & inline QPointF QBezier::pointAt(qreal t) const { -#if 1 - qreal a, b, c, d; - coefficients(t, a, b, c, d); - return QPointF(a*x1 + b*x2 + c*x3 + d*x4, a*y1 + b*y2 + c*y3 + d*y4); -#else // numerically more stable: + qreal x, y; + qreal m_t = 1. - t; - qreal a = x1*m_t + x2*t; - qreal b = x2*m_t + x3*t; - qreal c = x3*m_t + x4*t; - a = a*m_t + b*t; - b = b*m_t + c*t; - qreal x = a*m_t + b*t; - qreal a = y1*m_t + y2*t; - qreal b = y2*m_t + y3*t; - qreal c = y3*m_t + y4*t; - a = a*m_t + b*t; - b = b*m_t + c*t; - qreal y = a*m_t + b*t; + { + qreal a = x1*m_t + x2*t; + qreal b = x2*m_t + x3*t; + qreal c = x3*m_t + x4*t; + a = a*m_t + b*t; + b = b*m_t + c*t; + x = a*m_t + b*t; + } + { + qreal a = y1*m_t + y2*t; + qreal b = y2*m_t + y3*t; + qreal c = y3*m_t + y4*t; + a = a*m_t + b*t; + b = b*m_t + c*t; + y = a*m_t + b*t; + } return QPointF(x, y); -#endif } inline QPointF QBezier::normalVector(qreal t) const diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 994986b..147d2ec 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1611,6 +1611,8 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p && (fill.style() != Qt::NoBrush) && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush)) { + tessellator->tessellate((QPointF *)clippedPoints, clippedCount, + mode == QPaintEngine::WindingMode); if (tessellator->size > 0) { XRenderPictureAttributes attrs; attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9bd9733..1d10d75 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -6469,10 +6469,16 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y()); - const qreal underlineOffset = fe->underlinePosition().toReal(); + qreal underlineOffset = fe->underlinePosition().toReal(); + qreal y = pos.y(); + // compensate for different rounding rule in Core Graphics paint engine, + // ideally code like this should be moved to respective engines. + if (painter->paintEngine()->type() == QPaintEngine::CoreGraphics) { + y = qCeil(y); + } // deliberately ceil the offset to avoid the underline coming too close to // the text above it. - const qreal underlinePos = pos.y() + qCeil(underlineOffset); + const qreal underlinePos = y + qCeil(underlineOffset); if (underlineStyle == QTextCharFormat::SpellCheckUnderline) { underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle)); diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index fdba9c9..3973abd 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -198,7 +198,7 @@ bool QTextureGlyphCache::populate(QFontEngine *fontEngine, int numGlyphs, const Coord c = { 0, 0, // will be filled in later glyph_width, glyph_height, // texture coords - metrics.x.round().truncate(), + metrics.x.truncate(), -metrics.y.truncate() }; // baseline for horizontal scripts listItemCoordinates.insert(key, c); @@ -367,9 +367,7 @@ void QImageTextureGlyphCache::createTextureData(int width, int height) int QImageTextureGlyphCache::glyphMargin() const { -#if (defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) - return 1; -#elif defined(Q_WS_X11) +#if (defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) || defined(Q_WS_X11) return 0; #else return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; diff --git a/src/gui/s60framework/qs60keycapture.cpp b/src/gui/s60framework/qs60keycapture.cpp new file mode 100644 index 0000000..415c3e1 --- /dev/null +++ b/src/gui/s60framework/qs60keycapture.cpp @@ -0,0 +1,308 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Symbian application wrapper 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 <remconinterfaceselector.h> +#include <remconcoreapitarget.h> +#include <coemain.h> +#include "qkeymapper_p.h" +#include "qs60keycapture_p.h" + +QT_BEGIN_NAMESPACE + +/* + * Helper class for sending key handling responses to RemCon. +*/ +class CResponseHandler : public CActive +{ +public: + static CResponseHandler *NewL(CRemConCoreApiTarget &remConCoreApiTarget); + virtual ~CResponseHandler(); + void CompleteAnyKey(TRemConCoreApiOperationId operationId); + +private: + CResponseHandler(CRemConCoreApiTarget &remConCoreApiTarget); + + void RunL(); + void DoCancel(); + +private: + RArray<TRemConCoreApiOperationId> iResponseArray; + CRemConCoreApiTarget &iRemConCoreApiTarget; +}; + +CResponseHandler::CResponseHandler(CRemConCoreApiTarget &remConCoreApiTarget) + : CActive(CActive::EPriorityStandard), + iRemConCoreApiTarget(remConCoreApiTarget) +{ + CActiveScheduler::Add(this); +} + +CResponseHandler *CResponseHandler::NewL(CRemConCoreApiTarget &remConCoreApiTarget) +{ + CResponseHandler *self = + new (ELeave) CResponseHandler(remConCoreApiTarget); + return self; +} + +CResponseHandler::~CResponseHandler() +{ + Cancel(); + iResponseArray.Close(); +} + +void CResponseHandler::CompleteAnyKey(TRemConCoreApiOperationId operationId) +{ + if (!IsActive()) { + TInt error = KErrNone; + iRemConCoreApiTarget.SendResponse(iStatus, operationId, error); + SetActive(); + } else { + // already active. Append to array and complete later. + iResponseArray.Append(operationId); + } +} + +void CResponseHandler::DoCancel() +{ + iRemConCoreApiTarget.Cancel(); +} + +void CResponseHandler::RunL() +{ + // if any existing -> Send response + if (iResponseArray.Count()) { + CompleteAnyKey(iResponseArray[0]); + // Remove already completed key + iResponseArray.Remove(0); + iResponseArray.Compress(); + } +} + + +/* + * QS60KeyCapture provides media key handling using services from RemCon. + */ +QS60KeyCapture::QS60KeyCapture(CCoeEnv *env, QObject *parent): + QObject(parent), coeEnv(env), selector(0), target(0), handler(0) +{ + initRemCon(); + + TTimeIntervalMicroSeconds32 initialTime; + TTimeIntervalMicroSeconds32 time; + coeEnv->WsSession().GetKeyboardRepeatRate(initialTime, time); + initialRepeatTime = (initialTime.Int() / 1000); // msecs + repeatTime = (time.Int() / 1000); // msecs + + int clickTimeout = initialRepeatTime + repeatTime; + + volumeUpClickTimer.setSingleShot(true); + volumeDownClickTimer.setSingleShot(true); + repeatTimer.setSingleShot(true); + + volumeUpClickTimer.setInterval(clickTimeout); + volumeDownClickTimer.setInterval(clickTimeout); + repeatTimer.setInterval(initialRepeatTime); + + connect(&volumeUpClickTimer, SIGNAL(timeout()), this, SLOT(volumeUpClickTimerExpired())); + connect(&volumeDownClickTimer, SIGNAL(timeout()), this, SLOT(volumeDownClickTimerExpired())); + connect(&repeatTimer, SIGNAL(timeout()), this, SLOT(repeatTimerExpired())); +} + +/* + * Initializes RemCon connection for receiving key events + */ +void QS60KeyCapture::initRemCon() +{ + try { + QT_TRAP_THROWING( + selector = CRemConInterfaceSelector::NewL(); + target = CRemConCoreApiTarget::NewL(*selector, *this); + handler = CResponseHandler::NewL(*target); + selector->OpenTargetL()); + } catch (const std::exception &e) { + delete handler; + delete selector; + selector = 0; + target = 0; + handler = 0; + } +} + +QS60KeyCapture::~QS60KeyCapture() +{ + delete handler; + delete selector; +} + +void QS60KeyCapture::MrccatoCommand(TRemConCoreApiOperationId operationId, + TRemConCoreApiButtonAction buttonAction) +{ + if (!target) + return; + + switch (operationId) { + // Volume up/down keys auto repeat if user hold the key long enough + case ERemConCoreApiVolumeUp: + case ERemConCoreApiVolumeDown: + { + // Side key events are sent using following scheme: + // - ButtonClick is sent first + // - if nothing happens before repeat timer expires, no further events are generated + // - if user holds the button longer, ButtonPress is sent and + // when button is finally released ButtonRelease is sent. + + QTimer &timer = (operationId == ERemConCoreApiVolumeUp) ? volumeUpClickTimer : volumeDownClickTimer; + + switch (buttonAction) { + case ERemConCoreApiButtonPress: + if (timer.isActive()) { + timer.stop(); + // force repeat event + repeatKeyEvent = mapToKeyEvent(operationId); + repeatTimerExpired(); + } else { + sendKey(operationId, QEvent::KeyPress); + repeatTimer.start(initialRepeatTime); + } + break; + case ERemConCoreApiButtonRelease: + timer.stop(); + sendKey(operationId, QEvent::KeyRelease); + repeatTimer.stop(); + break; + case ERemConCoreApiButtonClick: + if (timer.isActive()) { + timer.stop(); + sendKey(operationId, QEvent::KeyRelease); + } + sendKey(operationId, QEvent::KeyPress); + timer.start(); + repeatTimer.stop(); + break; + default: + break; + } + } + break; + default: + switch (buttonAction) { + case ERemConCoreApiButtonPress: + sendKey(operationId, QEvent::KeyPress); + repeatTimer.start(initialRepeatTime); + break; + case ERemConCoreApiButtonRelease: + sendKey(operationId, QEvent::KeyRelease); + repeatTimer.stop(); + break; + case ERemConCoreApiButtonClick: + sendKey(operationId, QEvent::KeyPress); + sendKey(operationId, QEvent::KeyRelease); + repeatTimer.stop(); + break; + default: + break; + } + break; + } + + if (handler) + handler->CompleteAnyKey(operationId); +} + +/* + * Sends volume up KeyRelease event + */ +void QS60KeyCapture::volumeUpClickTimerExpired() +{ + sendKey(ERemConCoreApiVolumeUp, QEvent::KeyRelease); +} + +/* + * Sends volume down KeyRelease event + */ +void QS60KeyCapture::volumeDownClickTimerExpired() +{ + sendKey(ERemConCoreApiVolumeDown, QEvent::KeyRelease); +} + +/* + * Repeats last key event + */ +void QS60KeyCapture::repeatTimerExpired() +{ + // set auto repeat flag on + repeatKeyEvent.iRepeats = 1; + coeEnv->SimulateKeyEventL(repeatKeyEvent, EEventKey); + repeatTimer.start(repeatTime); +} + +/* + * Maps RemCon operation id to key event (includes key code and scan codes) + */ +TKeyEvent QS60KeyCapture::mapToKeyEvent(TRemConCoreApiOperationId operationId) +{ + TKeyEvent keyEvent; + keyEvent.iModifiers = 0; + keyEvent.iRepeats = 0; + keyEvent.iCode = qt_keymapper_private()->mapS60RemConIdToS60Key(operationId); + keyEvent.iScanCode = qt_keymapper_private()->mapS60RemConIdToS60ScanCodes(operationId); + return keyEvent; +} + +/* + * Delivers key events to the application. + * RemCon operations are converted to simulated key events + */ +void QS60KeyCapture::sendKey(TRemConCoreApiOperationId operationId, QEvent::Type type) +{ + TKeyEvent keyEvent = mapToKeyEvent(operationId); + + if (type == QEvent::KeyPress) { + coeEnv->SimulateKeyEventL(keyEvent, EEventKeyDown); + coeEnv->SimulateKeyEventL(keyEvent, EEventKey); + // save the key press event for repeats + repeatKeyEvent = keyEvent; + } else { + coeEnv->SimulateKeyEventL(keyEvent, EEventKeyUp); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/openvglite/qwindowsurface_vglite.h b/src/gui/s60framework/qs60keycapture_p.h index b6e22d8..a50fad7 100644 --- a/src/plugins/platforms/openvglite/qwindowsurface_vglite.h +++ b/src/gui/s60framework/qs60keycapture_p.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the plugins of the Qt Toolkit. +** This file is part of the Symbian application wrapper of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** GNU Lesser General Public License Usage @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QWINDOWSURFACE_VGLITE_H -#define QWINDOWSURFACE_VGLITE_H +#ifndef QS60KEYCAPTURE_P_H +#define QS60KEYCAPTURE_P_H // // W A R N I N G @@ -53,39 +53,64 @@ // We mean it. // -#include <QtGui/private/qwindowsurface_p.h> -#include <QtGui/private/qegl_p.h> +#include <QtCore/qglobal.h> -QT_BEGIN_NAMESPACE +#ifdef Q_OS_SYMBIAN + +#include <QObject> +#include <QEvent> +#include <QTimer> +#include <remconcoreapitargetobserver.h> +#include <w32std.h> -class QVGLiteGraphicsSystem; -class QVGPaintEngine; +class CRemConInterfaceSelector; +class CRemConCoreApiTarget; +class CResponseHandler; +class CCoeEnv; -class Q_OPENVG_EXPORT QVGLiteWindowSurface : public QWindowSurface, public QPaintDevice +QT_BEGIN_NAMESPACE + +class QS60KeyCapture: public QObject, + public MRemConCoreApiTargetObserver { + Q_OBJECT public: - QVGLiteWindowSurface(QVGLiteGraphicsSystem *gs, QWidget *window); - ~QVGLiteWindowSurface(); - - QPaintDevice *paintDevice(); - void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); - void setGeometry(const QRect &rect); - bool scroll(const QRegion &area, int dx, int dy); + QS60KeyCapture(CCoeEnv *env, QObject *parent = 0); + ~QS60KeyCapture(); - void beginPaint(const QRegion ®ion); - void endPaint(const QRegion ®ion); + void MrccatoCommand(TRemConCoreApiOperationId operationId, + TRemConCoreApiButtonAction buttonAct); - QPaintEngine *paintEngine() const; +private slots: + void volumeUpClickTimerExpired(); + void volumeDownClickTimerExpired(); + void repeatTimerExpired(); -protected: - int metric(PaintDeviceMetric metric) const; +private: + void sendKey(TRemConCoreApiOperationId operationId, QEvent::Type type); + TKeyEvent mapToKeyEvent(TRemConCoreApiOperationId operationId); + void initRemCon(); private: - QVGLiteGraphicsSystem *graphicsSystem; - bool isPaintingActive; - mutable QVGPaintEngine *engine; + QS60KeyCapture(); + Q_DISABLE_COPY(QS60KeyCapture) + + CCoeEnv *coeEnv; + + CRemConInterfaceSelector *selector; + CRemConCoreApiTarget *target; + CResponseHandler *handler; + + QTimer volumeUpClickTimer; + QTimer volumeDownClickTimer; + + TKeyEvent repeatKeyEvent; + int initialRepeatTime; // time before first repeat key event + int repeatTime; // time between subsequent repeat key events + QTimer repeatTimer; }; QT_END_NAMESPACE -#endif // QWINDOWSURFACE_VGLITE_H +#endif // Q_OS_SYMBIAN +#endif // QS60KEYCAPTURE_P_H diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp index ec97f7b..bd3017c 100644 --- a/src/gui/s60framework/qs60mainappui.cpp +++ b/src/gui/s60framework/qs60mainappui.cpp @@ -59,6 +59,7 @@ #include <private/qmenu_p.h> #include <private/qt_s60_p.h> #include <qdebug.h> +#include "qs60keycapture_p.h" //Animated wallpapers in Qt applications are not supported. const TInt KAknDisableAnimationBackground = 0x02000000; @@ -66,6 +67,20 @@ const TInt KAknSingleClickCompatible = 0x01000000; QT_BEGIN_NAMESPACE +static QS60KeyCapture *qt_S60KeyCapture = 0; + +static void installS60KeyCapture(CCoeEnv *env) +{ + if (QApplication::testAttribute(Qt::AA_CaptureMultimediaKeys)) + qt_S60KeyCapture = new QS60KeyCapture(env); +} + +static void removeS60KeyCapture() +{ + delete qt_S60KeyCapture; + qt_S60KeyCapture = 0; +} + /*! \class QS60MainAppUi \since 4.6 @@ -127,6 +142,7 @@ void QS60MainAppUi::ConstructL() } #endif BaseConstructL(flags); + installS60KeyCapture(iCoeEnv); } /*! @@ -142,6 +158,7 @@ QS60MainAppUi::QS60MainAppUi() */ QS60MainAppUi::~QS60MainAppUi() { + removeS60KeyCapture(); } /*! diff --git a/src/gui/s60framework/s60framework.pri b/src/gui/s60framework/s60framework.pri index 19525b7..e30d2c0 100644 --- a/src/gui/s60framework/s60framework.pri +++ b/src/gui/s60framework/s60framework.pri @@ -1,10 +1,13 @@ SOURCES += s60framework/qs60mainapplication.cpp \ - s60framework/qs60mainappui.cpp \ - s60framework/qs60maindocument.cpp - -HEADERS += s60framework/qs60mainapplication_p.h \ - s60framework/qs60mainapplication.h \ - s60framework/qs60mainappui.h \ - s60framework/qs60maindocument.h - -!isEmpty(QT_LIBINFIX): DEFINES += QT_LIBINFIX_UNQUOTED=$$QT_LIBINFIX
\ No newline at end of file + s60framework/qs60mainappui.cpp \ + s60framework/qs60maindocument.cpp \ + s60framework/qs60keycapture.cpp +HEADERS += qs60keycapture_p.h \ + s60framework/qs60mainapplication_p.h \ + s60framework/qs60mainapplication.h \ + s60framework/qs60mainappui.h \ + s60framework/qs60maindocument.h \ + s60framework/qs60keycapture_p.h +LIBS += -lremconcoreapi \ + -lremconinterfacebase +!isEmpty(QT_LIBINFIX):DEFINES += QT_LIBINFIX_UNQUOTED=$$QT_LIBINFIX diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 40c28f6..8436856 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -1195,15 +1195,15 @@ QRect QMacStylePrivate::comboboxEditBounds(const QRect &outerBounds, const HIThe QRect ret = outerBounds; switch (bdi.kind){ case kThemeComboBox: - ret.adjust(5, 8, -21, -4); + ret.adjust(5, 8, -22, -4); break; case kThemeComboBoxSmall: - ret.adjust(4, 5, -18, 0); - ret.setHeight(16); + ret.adjust(4, 6, -20, 0); + ret.setHeight(14); break; case kThemeComboBoxMini: - ret.adjust(4, 5, -16, 0); - ret.setHeight(13); + ret.adjust(4, 5, -18, -1); + ret.setHeight(12); break; case kThemePopupButton: ret.adjust(10, 3, -23, -3); @@ -3681,9 +3681,27 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled, tab->text, QPalette::WindowText); p->restore(); - } + QCommonStyle::drawControl(ce, &myTab, p, w); + } else if (qMacVersion() >= QSysInfo::MV_10_7 && (tab->state & State_Selected)) { + p->save(); + rotateTabPainter(p, myTab.shape, myTab.rect); - QCommonStyle::drawControl(ce, &myTab, p, w); + QPalette np = tab->palette; + np.setColor(QPalette::WindowText, QColor(0, 0, 0, 75)); + QRect nr = subElementRect(SE_TabBarTabText, opt, w); + nr.moveTop(-1); + int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextHideMnemonic; + proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled, + tab->text, QPalette::WindowText); + + np.setColor(QPalette::WindowText, QColor(255, 255, 255, 255)); + nr.moveTop(-2); + proxy()->drawItemText(p, nr, alignment, np, tab->state & State_Enabled, + tab->text, QPalette::WindowText); + p->restore(); + } else { + QCommonStyle::drawControl(ce, &myTab, p, w); + } } else { p->save(); CGContextSetShouldAntialias(cg, true); @@ -4707,7 +4725,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex HIThemeFrameDrawInfo fdi; fdi.version = qt_mac_hitheme_version; - fdi.state = tds; + fdi.state = ((sb->state & State_ReadOnly) || !(sb->state & State_Enabled)) ? kThemeStateInactive : kThemeStateActive; fdi.kind = kHIThemeFrameTextFieldSquare; fdi.isFocused = false; HIRect hirect = qt_hirectForQRect(lineeditRect); diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index de45754..e9f7a86 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -501,8 +501,10 @@ bool QS60StylePrivate::equalToThemePalette(qint64 cacheKey, QPalette::ColorRole { if (!m_themePalette) return false; - if (cacheKey == m_themePalette->brush(role).texture().cacheKey()) + if ((m_placeHolderTexture && (cacheKey == m_placeHolderTexture->cacheKey())) + || (cacheKey == m_themePalette->brush(role).texture().cacheKey())) return true; + return false; } diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 98186df..26d9f2c 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -218,16 +218,14 @@ struct QtFontStyle Key(const QString &styleString); Key() : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0) { } - Key(const Key &o) : style(o.style), - weight(o.weight), stretch(o.stretch) { } + Key(const Key &o) : style(o.style), weight(o.weight), stretch(o.stretch) { } uint style : 2; signed int weight : 8; signed int stretch : 12; bool operator==(const Key & other) { - return (style == other.style && - weight == other.weight && - (stretch == 0 || other.stretch == 0 || stretch == other.stretch)); + return (style == other.style && weight == other.weight && + (stretch == 0 || other.stretch == 0 || stretch == other.stretch)); } bool operator!=(const Key &other) { return !operator==(other); @@ -279,6 +277,7 @@ struct QtFontStyle bool smoothScalable : 1; signed int count : 30; QtFontSize *pixelSizes; + QString styleName; #ifdef Q_WS_X11 const char *weightName; @@ -353,13 +352,20 @@ struct QtFontFoundry int count; QtFontStyle **styles; - QtFontStyle *style(const QtFontStyle::Key &, bool = false); + QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false); }; -QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create) +QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create) { int pos = 0; if (count) { + // if styleName for searching first if possible + if (!styleName.isEmpty()) { + for (; pos < count; pos++) { + if (styles[pos]->styleName == styleName) + return styles[pos]; + } + } int low = 0; int high = count; pos = count / 2; @@ -386,6 +392,7 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create) } QtFontStyle *style = new QtFontStyle(key); + style->styleName = styleName; memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *)); styles[pos] = style; count++; @@ -814,7 +821,7 @@ void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundr } QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true); - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, QString(), true); style->smoothScalable = (pixelSize == 0); style->antialiased = antialiased; QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true); @@ -1123,15 +1130,17 @@ QT_BEGIN_INCLUDE_NAMESPACE #elif defined(Q_OS_SYMBIAN) # include "qfontdatabase_s60.cpp" #endif +QT_END_INCLUDE_NAMESPACE + #if !defined(Q_WS_X11) QString QFontDatabase::resolveFontFamilyAlias(const QString &family) { return family; } #endif -QT_END_INCLUDE_NAMESPACE -static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey) +static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey, + const QString &styleName = QString()) { int best = 0; int dist = 0xffff; @@ -1139,6 +1148,12 @@ static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &st for ( int i = 0; i < foundry->count; i++ ) { QtFontStyle *style = foundry->styles[i]; + if (!styleName.isEmpty() && styleName == style->styleName) { + dist = 0; + best = i; + break; + } + int d = qAbs( styleKey.weight - style->key.weight ); if ( styleKey.stretch != 0 && style->key.stretch != 0 ) { @@ -1532,7 +1547,8 @@ static QString styleStringHelper(int weight, QFont::Style style) */ QString QFontDatabase::styleString(const QFont &font) { - return styleStringHelper(font.weight(), font.style()); + return font.styleName().isEmpty() ? styleStringHelper(font.weight(), font.style()) + : font.styleName(); } /*! @@ -1542,7 +1558,8 @@ QString QFontDatabase::styleString(const QFont &font) */ QString QFontDatabase::styleString(const QFontInfo &fontInfo) { - return styleStringHelper(fontInfo.weight(), fontInfo.style()); + return fontInfo.styleName().isEmpty() ? styleStringHelper(fontInfo.weight(), fontInfo.style()) + : fontInfo.styleName(); } @@ -1788,13 +1805,17 @@ QStringList QFontDatabase::styles(const QString &family) const for (int k = 0; k < foundry->count; k++) { QtFontStyle::Key ke(foundry->styles[k]->key); ke.stretch = 0; - allStyles.style(ke, true); + allStyles.style(ke, foundry->styles[k]->styleName, true); } } } - for (int i = 0; i < allStyles.count; i++) - l.append(styleStringHelper(allStyles.styles[i]->key.weight, (QFont::Style)allStyles.styles[i]->key.style)); + for (int i = 0; i < allStyles.count; i++) { + l.append(allStyles.styles[i]->styleName.isEmpty() ? + styleStringHelper(allStyles.styles[i]->key.weight, + (QFont::Style)allStyles.styles[i]->key.style) : + allStyles.styles[i]->styleName); + } return l; } @@ -1852,7 +1873,9 @@ bool QFontDatabase::isBitmapScalable(const QString &family, QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { for (int k = 0; k < foundry->count; k++) - if ((style.isEmpty() || foundry->styles[k]->key == styleKey) + if ((style.isEmpty() || + foundry->styles[k]->styleName == style || + foundry->styles[k]->key == styleKey) && foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) { bitmapScalable = true; goto end; @@ -1891,7 +1914,9 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { for (int k = 0; k < foundry->count; k++) - if ((style.isEmpty() || foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) { + if ((style.isEmpty() || + foundry->styles[k]->styleName == style || + foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) { smoothScalable = true; goto end; } @@ -1924,12 +1949,12 @@ bool QFontDatabase::isScalable(const QString &family, \sa smoothSizes(), standardSizes() */ QList<int> QFontDatabase::pointSizes(const QString &family, - const QString &style) + const QString &styleName) { #if defined(Q_WS_WIN) // windows and macosx are always smoothly scalable Q_UNUSED(family); - Q_UNUSED(style); + Q_UNUSED(styleName); return standardSizes(); #else bool smoothScalable = false; @@ -1940,7 +1965,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family, QT_PREPEND_NAMESPACE(load)(familyName); - QtFontStyle::Key styleKey(style); + QtFontStyle::Key styleKey(styleName); QList<int> sizes; @@ -1957,7 +1982,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family, for (int j = 0; j < fam->count; j++) { QtFontFoundry *foundry = fam->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { - QtFontStyle *style = foundry->style(styleKey); + QtFontStyle *style = foundry->style(styleKey, styleName); if (!style) continue; if (style->smoothScalable) { @@ -2008,17 +2033,20 @@ QFont QFontDatabase::font(const QString &family, const QString &style, QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, true); + allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); } } QtFontStyle::Key styleKey(style); - QtFontStyle *s = bestStyle(&allStyles, styleKey); + QtFontStyle *s = bestStyle(&allStyles, styleKey, style); if (!s) // no styles found? return QApplication::font(); + QFont fnt(family, pointSize, s->key.weight); fnt.setStyle((QFont::Style)s->key.style); + if (!s->styleName.isEmpty()) + fnt.setStyleName(s->styleName); return fnt; } @@ -2032,11 +2060,11 @@ QFont QFontDatabase::font(const QString &family, const QString &style, \sa pointSizes(), standardSizes() */ QList<int> QFontDatabase::smoothSizes(const QString &family, - const QString &style) + const QString &styleName) { #ifdef Q_WS_WIN Q_UNUSED(family); - Q_UNUSED(style); + Q_UNUSED(styleName); return QFontDatabase::standardSizes(); #else bool smoothScalable = false; @@ -2047,7 +2075,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family, QT_PREPEND_NAMESPACE(load)(familyName); - QtFontStyle::Key styleKey(style); + QtFontStyle::Key styleKey(styleName); QList<int> sizes; @@ -2064,7 +2092,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family, for (int j = 0; j < fam->count; j++) { QtFontFoundry *foundry = fam->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { - QtFontStyle *style = foundry->style(styleKey); + QtFontStyle *style = foundry->style(styleKey, styleName); if (!style) continue; if (style->smoothScalable) { @@ -2131,12 +2159,12 @@ bool QFontDatabase::italic(const QString &family, const QString &style) const QtFontFoundry *foundry = f->foundries[j]; if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, true); + allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); } } QtFontStyle::Key styleKey(style); - QtFontStyle *s = allStyles.style(styleKey); + QtFontStyle *s = allStyles.style(styleKey, style); return s && s->key.style == QFont::StyleItalic; } @@ -2166,12 +2194,12 @@ bool QFontDatabase::bold(const QString &family, if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, true); + allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); } } QtFontStyle::Key styleKey(style); - QtFontStyle *s = allStyles.style(styleKey); + QtFontStyle *s = allStyles.style(styleKey, style); return s && s->key.weight >= QFont::Bold; } @@ -2202,12 +2230,12 @@ int QFontDatabase::weight(const QString &family, if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) { for (int k = 0; k < foundry->count; k++) - allStyles.style(foundry->styles[k]->key, true); + allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true); } } QtFontStyle::Key styleKey(style); - QtFontStyle *s = allStyles.style(styleKey); + QtFontStyle *s = allStyles.style(styleKey, style); return s ? s->key.weight : -1; } diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp index 60cf586..fc8247d 100644 --- a/src/gui/text/qfontdatabase_mac.cpp +++ b/src/gui/text/qfontdatabase_mac.cpp @@ -106,12 +106,14 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fonts, i); QCFString family_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute); + QCFString style_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute); QtFontFamily *family = db->family(family_name, true); for(int ws = 1; ws < QFontDatabase::WritingSystemsCount; ++ws) family->writingSystems[ws] = QtFontFamily::Supported; QtFontFoundry *foundry = family->foundry(foundry_name, true); QtFontStyle::Key styleKey; + QString styleName = style_name; if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) { if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) { Q_ASSERT(CFNumberIsFloatType(weight)); @@ -132,7 +134,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { } } - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, styleName, true); style->smoothScalable = true; if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) { //qDebug() << "WHEE"; @@ -205,7 +207,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) { QtFontFamily *family = db->family(familyName, true); QtFontFoundry *foundry = family->foundry(QString(), true); - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, QString(), true); style->pixelSize(0, true); style->smoothScalable = true; diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp index fd5c6b4..6b6f4f1 100644 --- a/src/gui/text/qfontdatabase_qpa.cpp +++ b/src/gui/text/qfontdatabase_qpa.cpp @@ -73,7 +73,7 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &fou } QtFontFoundry *foundry = f->foundry(foundryname, true); - QtFontStyle *fontStyle = foundry->style(styleKey, true); + QtFontStyle *fontStyle = foundry->style(styleKey, QString(), true); fontStyle->smoothScalable = scalable; fontStyle->antialiased = antialiased; QtFontSize *size = fontStyle->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true); diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 980b5de..2f4d055 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -508,7 +508,7 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex, QtFontFamily *family = privateDb()->family(familyName, true); family->fixedPitch = faceAttrib.IsMonoWidth(); QtFontFoundry *foundry = family->foundry(QString(), true); - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, QString(), true); style->smoothScalable = typefaceSupport.iIsScalable; style->pixelSize(0, true); diff --git a/src/gui/text/qfontdatabase_win.cpp b/src/gui/text/qfontdatabase_win.cpp index 20f945a..788eb30 100644 --- a/src/gui/text/qfontdatabase_win.cpp +++ b/src/gui/text/qfontdatabase_win.cpp @@ -284,7 +284,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName, family->english_name = getEnglishName(familyName); QtFontFoundry *foundry = family->foundry(foundryName, true); - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); @@ -292,14 +292,14 @@ void addFontToDatabase(QString familyName, const QString &scriptName, if (styleKey.weight <= QFont::DemiBold) { QtFontStyle::Key key(styleKey); key.weight = QFont::Bold; - QtFontStyle *style = foundry->style(key, true); + QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } if (styleKey.style != QFont::StyleItalic) { QtFontStyle::Key key(styleKey); key.style = QFont::StyleItalic; - QtFontStyle *style = foundry->style(key, true); + QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } @@ -307,7 +307,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName, QtFontStyle::Key key(styleKey); key.weight = QFont::Bold; key.style = QFont::StyleItalic; - QtFontStyle *style = foundry->style(key, true); + QtFontStyle *style = foundry->style(key, QString(), true); style->smoothScalable = scalable; style->pixelSize( size, TRUE); } diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index 958daa2..922a97f 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -680,7 +680,7 @@ static void loadXlfds(const char *reqFamily, int encoding_id) family->fontFileIndex = -1; family->symbol_checked = true; QtFontFoundry *foundry = family->foundry(QLatin1String(foundryName), true); - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, QString(), true); delete [] style->weightName; style->weightName = qstrdup(tokens[Weight]); @@ -1034,13 +1034,14 @@ static void loadFontConfig() FcChar8 *file_value; int index_value; FcChar8 *foundry_value; + FcChar8 *style_value; FcBool scalable; { FcObjectSet *os = FcObjectSetCreate(); FcPattern *pattern = FcPatternCreate(); const char *properties [] = { - FC_FAMILY, FC_WEIGHT, FC_SLANT, + FC_FAMILY, FC_STYLE, FC_WEIGHT, FC_SLANT, FC_SPACING, FC_FILE, FC_INDEX, FC_LANG, FC_CHARSET, FC_FOUNDRY, FC_SCALABLE, FC_PIXEL_SIZE, FC_WEIGHT, FC_WIDTH, @@ -1085,6 +1086,8 @@ static void loadFontConfig() scalable = FcTrue; if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch) foundry_value = 0; + if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch) + style_value = 0; QtFontFamily *family = db->family(familyName, true); FcLangSet *langset = 0; @@ -1142,6 +1145,7 @@ static void loadFontConfig() family->fontFileIndex = index_value; QtFontStyle::Key styleKey; + QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString(); styleKey.style = (slant_value == FC_SLANT_ITALIC) ? QFont::StyleItalic : ((slant_value == FC_SLANT_OBLIQUE) @@ -1156,7 +1160,7 @@ static void loadFontConfig() QtFontFoundry *foundry = family->foundry(foundry_value ? QString::fromUtf8((const char *)foundry_value) : QString(), true); - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, styleName, true); if (spacing_value < FC_MONO) family->fixedPitch = false; @@ -1208,7 +1212,7 @@ static void loadFontConfig() for (int i = 0; i < 4; ++i) { styleKey.style = (i%2) ? QFont::StyleNormal : QFont::StyleItalic; styleKey.weight = (i > 1) ? QFont::Bold : QFont::Normal; - QtFontStyle *style = foundry->style(styleKey, true); + QtFontStyle *style = foundry->style(styleKey, QString(), true); style->smoothScalable = true; QtFontSize *size = style->pixelSize(SMOOTH_SCALABLE, true); QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true); @@ -1356,7 +1360,7 @@ static void initializeDb() if (equiv) continue; // let's fake one... - equiv = foundry->style(key, true); + equiv = foundry->style(key, QString(), true); equiv->smoothScalable = true; QtFontSize *equiv_size = equiv->pixelSize(SMOOTH_SCALABLE, true); diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 64b8682..64d4a24 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -492,17 +492,6 @@ void QCoreTextFontEngine::init() avgCharWidth = QFixed::fromReal(width * fontDef.pixelSize / emSize); } else avgCharWidth = QFontEngine::averageCharWidth(); - - ctMaxCharWidth = ctMinLeftBearing = ctMinRightBearing = 0; - QByteArray hheaTable = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a')); - if (hheaTable.size() >= 16) { - quint16 width = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 10)); - ctMaxCharWidth = width * fontDef.pixelSize / emSize; - qint16 bearing = qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 12)); - ctMinLeftBearing = bearing * fontDef.pixelSize / emSize; - bearing = qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 14)); - ctMinRightBearing = bearing * fontDef.pixelSize / emSize; - } } bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, @@ -599,20 +588,17 @@ QFixed QCoreTextFontEngine::averageCharWidth() const qreal QCoreTextFontEngine::maxCharWidth() const { - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? qRound(ctMaxCharWidth) : ctMaxCharWidth; + return 0; } qreal QCoreTextFontEngine::minLeftBearing() const { - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? qRound(ctMinLeftBearing) : ctMinLeftBearing; + return 0; } qreal QCoreTextFontEngine::minRightBearing() const { - return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) - ? qRound(ctMinRightBearing) : ctMinLeftBearing; + return 0; } void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight) @@ -732,8 +718,9 @@ void QCoreTextFontEngine::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *position QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition, int margin, bool aa) { + Q_UNUSED(margin); const glyph_metrics_t br = boundingBox(glyph); - QImage im(qRound(br.width) + margin * 2, qRound(br.height) + margin * 2, QImage::Format_RGB32); + QImage im(qRound(br.width) + 2, qRound(br.height) + 2, QImage::Format_RGB32); im.fill(0); CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); @@ -764,8 +751,8 @@ QImage QCoreTextFontEngine::imageForGlyph(glyph_t glyph, QFixed subPixelPosition CGContextSetFont(ctx, cgFont); - qreal pos_x = -br.x.toReal() + subPixelPosition.toReal() + margin; - qreal pos_y = im.height() + br.y.toReal() - margin; + qreal pos_x = -br.x.truncate() + subPixelPosition.toReal(); + qreal pos_y = im.height() + br.y.toReal(); CGContextSetTextPosition(ctx, pos_x, pos_y); CGSize advance; diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index 3ca8a0a..efe8295 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -103,9 +103,6 @@ private: int synthesisFlags; CGAffineTransform transform; QFixed avgCharWidth; - qreal ctMaxCharWidth; - qreal ctMinLeftBearing; - qreal ctMinRightBearing; friend class QCoreTextFontEngineMulti; }; diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp index 890cad9..d693273 100644 --- a/src/gui/text/qfontenginedirectwrite.cpp +++ b/src/gui/text/qfontenginedirectwrite.cpp @@ -390,6 +390,60 @@ glyph_metrics_t QFontEngineDirectWrite::boundingBox(const QGlyphLayout &glyphs) return glyph_metrics_t(0, -m_ascent, w - lastRightBearing(glyphs), m_ascent + m_descent, w, 0); } +glyph_metrics_t QFontEngineDirectWrite::alphaMapBoundingBox(glyph_t glyph, QFixed subPixelPosition, + const QTransform &matrix, + GlyphFormat /*format*/) +{ + glyph_metrics_t bbox = QFontEngine::boundingBox(glyph, matrix); // To get transformed advance + + UINT16 glyphIndex = glyph; + FLOAT glyphAdvance = 0; + + DWRITE_GLYPH_OFFSET glyphOffset; + glyphOffset.advanceOffset = 0; + glyphOffset.ascenderOffset = 0; + + DWRITE_GLYPH_RUN glyphRun; + glyphRun.fontFace = m_directWriteFontFace; + glyphRun.fontEmSize = fontDef.pixelSize; + glyphRun.glyphCount = 1; + glyphRun.glyphIndices = &glyphIndex; + glyphRun.glyphAdvances = &glyphAdvance; + glyphRun.isSideways = false; + glyphRun.bidiLevel = 0; + glyphRun.glyphOffsets = &glyphOffset; + + DWRITE_MATRIX transform; + transform.dx = subPixelPosition.toReal(); + transform.dy = 0; + transform.m11 = matrix.m11(); + transform.m12 = matrix.m12(); + transform.m21 = matrix.m21(); + transform.m22 = matrix.m22(); + + IDWriteGlyphRunAnalysis *glyphAnalysis = NULL; + HRESULT hr = m_directWriteFactory->CreateGlyphRunAnalysis( + &glyphRun, + 1.0f, + &transform, + DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC, + DWRITE_MEASURING_MODE_NATURAL, + 0.0, 0.0, + &glyphAnalysis + ); + + if (SUCCEEDED(hr)) { + RECT rect; + glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect); + glyphAnalysis->Release(); + + return glyph_metrics_t(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, + bbox.xoff, bbox.yoff); + } else { + return glyph_metrics_t(); + } +} + glyph_metrics_t QFontEngineDirectWrite::boundingBox(glyph_t g) { if (m_directWriteFontFace == 0) @@ -459,9 +513,10 @@ qreal QFontEngineDirectWrite::maxCharWidth() const extern uint qt_pow_gamma[256]; -QImage QFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition) +QImage QFontEngineDirectWrite::alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition, + const QTransform &xform) { - QImage im = imageForGlyph(glyph, subPixelPosition, 0, QTransform()); + QImage im = imageForGlyph(glyph, subPixelPosition, 0, xform); QImage indexed(im.width(), im.height(), QImage::Format_Indexed8); QVector<QRgb> colors(256); @@ -492,12 +547,8 @@ QImage QFontEngineDirectWrite::imageForGlyph(glyph_t t, int margin, const QTransform &xform) { - glyph_metrics_t metrics = QFontEngine::boundingBox(t, xform); - int width = (metrics.width + margin * 2 + 4).ceil().toInt() ; - int height = (metrics.height + margin * 2 + 4).ceil().toInt(); - UINT16 glyphIndex = t; - FLOAT glyphAdvance = metrics.xoff.toReal(); + FLOAT glyphAdvance = 0; DWRITE_GLYPH_OFFSET glyphOffset; glyphOffset.advanceOffset = 0; @@ -513,12 +564,9 @@ QImage QFontEngineDirectWrite::imageForGlyph(glyph_t t, glyphRun.bidiLevel = 0; glyphRun.glyphOffsets = &glyphOffset; - QFixed x = margin - metrics.x.round() + subPixelPosition; - QFixed y = margin - metrics.y.floor(); - DWRITE_MATRIX transform; - transform.dx = x.toReal(); - transform.dy = y.toReal(); + transform.dx = subPixelPosition.toReal(); + transform.dy = 0; transform.m11 = xform.m11(); transform.m12 = xform.m12(); transform.m21 = xform.m21(); @@ -537,48 +585,54 @@ QImage QFontEngineDirectWrite::imageForGlyph(glyph_t t, if (SUCCEEDED(hr)) { RECT rect; - rect.left = 0; - rect.top = 0; - rect.right = width; - rect.bottom = height; - - int size = width * height * 3; - BYTE *alphaValues = new BYTE[size]; - qMemSet(alphaValues, size, 0); - - hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1, - &rect, - alphaValues, - size); - - if (SUCCEEDED(hr)) { - QImage img(width, height, QImage::Format_RGB32); - img.fill(0xffffffff); + glyphAnalysis->GetAlphaTextureBounds(DWRITE_TEXTURE_CLEARTYPE_3x1, &rect); - for (int y=0; y<height; ++y) { - uint *dest = reinterpret_cast<uint *>(img.scanLine(y)); - BYTE *src = alphaValues + width * 3 * y; + rect.left -= margin; + rect.top -= margin; + rect.right += margin; + rect.bottom += margin; - for (int x=0; x<width; ++x) { - dest[x] = *(src) << 16 - | *(src + 1) << 8 - | *(src + 2); + int width = rect.right - rect.left; + int height = rect.bottom - rect.top; - src += 3; + int size = width * height * 3; + if (size > 0) { + BYTE *alphaValues = new BYTE[size]; + qMemSet(alphaValues, size, 0); + + hr = glyphAnalysis->CreateAlphaTexture(DWRITE_TEXTURE_CLEARTYPE_3x1, + &rect, + alphaValues, + size); + + if (SUCCEEDED(hr)) { + QImage img(width, height, QImage::Format_RGB32); + img.fill(0xffffffff); + + for (int y=0; y<height; ++y) { + uint *dest = reinterpret_cast<uint *>(img.scanLine(y)); + BYTE *src = alphaValues + width * 3 * y; + + for (int x=0; x<width; ++x) { + dest[x] = *(src) << 16 + | *(src + 1) << 8 + | *(src + 2); + + src += 3; + } } - } - delete[] alphaValues; - glyphAnalysis->Release(); + delete[] alphaValues; + glyphAnalysis->Release(); - return img; - } else { - delete[] alphaValues; - glyphAnalysis->Release(); + return img; + } else { + delete[] alphaValues; + glyphAnalysis->Release(); - qErrnoWarning("QFontEngineDirectWrite::imageForGlyph: CreateAlphaTexture failed"); + qErrnoWarning("QFontEngineDirectWrite::imageForGlyph: CreateAlphaTexture failed"); + } } - } else { qErrnoWarning("QFontEngineDirectWrite::imageForGlyph: CreateGlyphRunAnalysis failed"); } diff --git a/src/gui/text/qfontenginedirectwrite_p.h b/src/gui/text/qfontenginedirectwrite_p.h index d0086fc..edf1e6a 100644 --- a/src/gui/text/qfontenginedirectwrite_p.h +++ b/src/gui/text/qfontenginedirectwrite_p.h @@ -86,6 +86,10 @@ public: glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); glyph_metrics_t boundingBox(glyph_t g); + glyph_metrics_t alphaMapBoundingBox(glyph_t glyph, + QFixed subPixelPosition, + const QTransform &matrix, + GlyphFormat format); QFixed ascent() const; QFixed descent() const; @@ -97,7 +101,7 @@ public: bool supportsSubPixelPositions() const; - QImage alphaMapForGlyph(glyph_t glyph, QFixed subPixelPosition); + QImage alphaMapForGlyph(glyph_t, QFixed subPixelPosition, const QTransform &t); QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 0abafb8..143dc1a 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2710,7 +2710,7 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block) html += QLatin1Char('>'); if (block.begin().atEnd()) - html += "<br />"; + html += QLatin1String("<br />"); QTextBlock::Iterator it = block.begin(); if (fragmentMarkers && !it.atEnd() && block == doc->begin()) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 8ddf3eb..31d7e8a 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2890,6 +2890,7 @@ int QTextEngine::positionInLigature(const QScriptItem *si, int end, } const HB_CharAttributes *attrs = attributes(); + logClusters = this->logClusters(si); clusterLength = getClusterLength(logClusters, attrs, 0, end, glyph_pos, &clusterStart); if (clusterLength) { @@ -3051,6 +3052,22 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo : justified(false), underlineStyle(QTextCharFormat::NoUnderline), charFormat(format), num_chars(0), chars(0), logClusters(0), f(0), fontEngine(0) { + f = font; + fontEngine = f->d->engineForScript(si.analysis.script); + Q_ASSERT(fontEngine); + + initWithScriptItem(si); +} + +QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars_, int numChars, QFontEngine *fe, const QTextCharFormat &format) + : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), charFormat(format), + num_chars(numChars), chars(chars_), logClusters(0), f(font), glyphs(g), fontEngine(fe) +{ +} + +// Fix up flags and underlineStyle with given info +void QTextItemInt::initWithScriptItem(const QScriptItem &si) +{ // explicitly initialize flags so that initFontAttributes can be called // multiple times on the same TextItem flags = 0; @@ -3058,13 +3075,10 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo flags |= QTextItem::RightToLeft; ascent = si.ascent; descent = si.descent; - f = font; - fontEngine = f->d->engineForScript(si.analysis.script); - Q_ASSERT(fontEngine); - if (format.hasProperty(QTextFormat::TextUnderlineStyle)) { - underlineStyle = format.underlineStyle(); - } else if (format.boolProperty(QTextFormat::FontUnderline) + if (charFormat.hasProperty(QTextFormat::TextUnderlineStyle)) { + underlineStyle = charFormat.underlineStyle(); + } else if (charFormat.boolProperty(QTextFormat::FontUnderline) || f->d->underline) { underlineStyle = QTextCharFormat::SingleUnderline; } @@ -3073,18 +3087,12 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo if (underlineStyle == QTextCharFormat::SingleUnderline) flags |= QTextItem::Underline; - if (f->d->overline || format.fontOverline()) + if (f->d->overline || charFormat.fontOverline()) flags |= QTextItem::Overline; - if (f->d->strikeOut || format.fontStrikeOut()) + if (f->d->strikeOut || charFormat.fontStrikeOut()) flags |= QTextItem::StrikeOut; } -QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars_, int numChars, QFontEngine *fe) - : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), - num_chars(numChars), chars(chars_), logClusters(0), f(font), glyphs(g), fontEngine(fe) -{ -} - QTextItemInt QTextItemInt::midItem(QFontEngine *fontEngine, int firstGlyphIndex, int numGlyphs) const { QTextItemInt ti = *this; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 055974a..b1bd0c3 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -312,11 +312,13 @@ public: logClusters(0), f(0), fontEngine(0) {} QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFormat &format = QTextCharFormat()); - QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars, int numChars, QFontEngine *fe); + QTextItemInt(const QGlyphLayout &g, QFont *font, const QChar *chars, int numChars, QFontEngine *fe, + const QTextCharFormat &format = QTextCharFormat()); /// copy the structure items, adjusting the glyphs arrays to the right subarrays. /// the width of the returned QTextItemInt is not adjusted, for speed reasons QTextItemInt midItem(QFontEngine *fontEngine, int firstGlyphIndex, int numGlyphs) const; + void initWithScriptItem(const QScriptItem &si); QFixed descent; QFixed ascent; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 7990667..3f0b9e8 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2389,13 +2389,13 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR unsigned short *logClusters = eng->logClusters(&si); QGlyphLayout glyphs = eng->shapedGlyphs(&si); - QTextItemInt gf(si, &f, format); - gf.glyphs = glyphs.mid(iterator.glyphsStart, iterator.glyphsEnd - iterator.glyphsStart); - gf.chars = eng->layoutData->string.unicode() + iterator.itemStart; + QTextItemInt gf(glyphs.mid(iterator.glyphsStart, iterator.glyphsEnd - iterator.glyphsStart), + &f, eng->layoutData->string.unicode() + iterator.itemStart, + iterator.itemEnd - iterator.itemStart, eng->fontEngine(si), format); gf.logClusters = logClusters + iterator.itemStart - si.position; - gf.num_chars = iterator.itemEnd - iterator.itemStart; gf.width = iterator.itemWidth; gf.justified = line.justified; + gf.initWithScriptItem(si); Q_ASSERT(gf.fontEngine); diff --git a/src/gui/widgets/qabstractspinbox.cpp b/src/gui/widgets/qabstractspinbox.cpp index 4372ae3..7a985a1 100644 --- a/src/gui/widgets/qabstractspinbox.cpp +++ b/src/gui/widgets/qabstractspinbox.cpp @@ -1655,6 +1655,8 @@ void QAbstractSpinBox::initStyleOption(QStyleOptionSpinBox *option) const : (QAbstractSpinBox::StepDownEnabled|QAbstractSpinBox::StepUpEnabled); option->frame = d->frame; + if (d->readOnly) + option->state |= QStyle::State_ReadOnly; } /*! diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index df7766e..d42c259 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -527,6 +527,7 @@ void QHostInfoRunnable::run() iterator.remove(); hostInfo.setLookupId(postponed->id); postponed->resultEmitter.emitResultsReady(hostInfo); + delete postponed; } } } diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp index 0aa5a5a..966af88 100644 --- a/src/network/socket/qsymbiansocketengine.cpp +++ b/src/network/socket/qsymbiansocketengine.cpp @@ -264,6 +264,7 @@ QSymbianSocketEnginePrivate::QSymbianSocketEnginePrivate() : QSymbianSocketEnginePrivate::~QSymbianSocketEnginePrivate() { + selectTimer.Close(); } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 52450b6..5d2221f 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1696,6 +1696,8 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp } int numGlyphs = vertexCoordinates->vertexCount() / 4; + if (numGlyphs == 0) + return; if (elementIndices.size() < numGlyphs*6) { Q_ASSERT(elementIndices.size() % 6 == 0); diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index ad56cbd..36e786f 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -68,6 +68,13 @@ extern QList<QWidget*> childWidgets(const QWidget *widget, bool includeTopLevel QString Q_GUI_EXPORT qt_accStripAmp(const QString &text); QString Q_GUI_EXPORT qt_accHotKey(const QString &text); +QString Q_GUI_EXPORT qTextBeforeOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType, + int *startOffset, int *endOffset, const QString& text); +QString Q_GUI_EXPORT qTextAtOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType, + int *startOffset, int *endOffset, const QString& text); +QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::BoundaryType boundaryType, + int *startOffset, int *endOffset, const QString& text); + /*! \class QAccessibleButton \brief The QAccessibleButton class implements the QAccessibleInterface for button type widgets. @@ -815,25 +822,34 @@ QString QAccessibleLineEdit::text(int startOffset, int endOffset) return lineEdit()->text().mid(startOffset, endOffset - startOffset); } -QString QAccessibleLineEdit::textBeforeOffset (int /*offset*/, BoundaryType /*boundaryType*/, - int * /*startOffset*/, int * /*endOffset*/) +QString QAccessibleLineEdit::textBeforeOffset(int offset, BoundaryType boundaryType, + int *startOffset, int *endOffset) { - // TODO - return QString(); + if (lineEdit()->echoMode() != QLineEdit::Normal) { + *startOffset = *endOffset = -1; + return QString(); + } + return qTextBeforeOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text()); } -QString QAccessibleLineEdit::textAfterOffset(int /*offset*/, BoundaryType /*boundaryType*/, - int * /*startOffset*/, int * /*endOffset*/) +QString QAccessibleLineEdit::textAfterOffset(int offset, BoundaryType boundaryType, + int *startOffset, int *endOffset) { - // TODO - return QString(); + if (lineEdit()->echoMode() != QLineEdit::Normal) { + *startOffset = *endOffset = -1; + return QString(); + } + return qTextAfterOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text()); } -QString QAccessibleLineEdit::textAtOffset(int /*offset*/, BoundaryType /*boundaryType*/, - int * /*startOffset*/, int * /*endOffset*/) +QString QAccessibleLineEdit::textAtOffset(int offset, BoundaryType boundaryType, + int *startOffset, int *endOffset) { - // TODO - return QString(); + if (lineEdit()->echoMode() != QLineEdit::Normal) { + *startOffset = *endOffset = -1; + return QString(); + } + return qTextAtOffsetFromString(offset, boundaryType, startOffset, endOffset, lineEdit()->text()); } void QAccessibleLineEdit::removeSelection(int selectionIndex) diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index 04edbb7..fc2791a 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -104,15 +104,7 @@ void SymbianEngine::initialize() return; } - TRAP(error, { - iConnectionMonitor.ConnectL(); - CleanupClosePushL(iConnectionMonitor); -#ifdef SNAP_FUNCTIONALITY_AVAILABLE - User::LeaveIfError(iConnectionMonitor.SetUintAttribute(EBearerIdAll, 0, KBearerGroupThreshold, 1)); -#endif - iConnectionMonitor.NotifyEventL(*this); - CleanupStack::Pop(); - }); + TRAP(error, StartConnectionMonitorNotifyL()); if (error != KErrNone) { iInitOk = false; return; @@ -148,6 +140,17 @@ void SymbianEngine::initialize() startCommsDatabaseNotifications(); } +void SymbianEngine::StartConnectionMonitorNotifyL() +{ + iConnectionMonitor.ConnectL(); + CleanupClosePushL(iConnectionMonitor); +#ifdef SNAP_FUNCTIONALITY_AVAILABLE + User::LeaveIfError(iConnectionMonitor.SetUintAttribute(EBearerIdAll, 0, KBearerGroupThreshold, 1)); +#endif + iConnectionMonitor.NotifyEventL(*this); + CleanupStack::Pop(); +} + SymbianEngine::~SymbianEngine() { Cancel(); @@ -255,7 +258,7 @@ void SymbianEngine::updateConfigurationsL() #ifdef SNAP_FUNCTIONALITY_AVAILABLE // S60 version is >= Series60 3rd Edition Feature Pack 2 TInt error = KErrNone; - + // Loop through all IAPs RArray<TUint32> connectionMethods; // IAPs CleanupClosePushL(connectionMethods); @@ -289,7 +292,7 @@ void SymbianEngine::updateConfigurationsL() CleanupStack::PopAndDestroy(&connectionMethod); } CleanupStack::PopAndDestroy(&connectionMethods); - + // Loop through all SNAPs RArray<TUint32> destinations; CleanupClosePushL(destinations); @@ -459,7 +462,7 @@ void SymbianEngine::updateConfigurationsL() break; } } - } + } } foreach (const QString &oldIface, knownSnapConfigs) { @@ -489,13 +492,13 @@ SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( SymbianNetworkConfigurationPrivate *cpPriv = new SymbianNetworkConfigurationPrivate; TUint32 iapId = connectionMethod.GetIntAttributeL(CMManager::ECmIapId); QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(iapId)); - + HBufC *pName = connectionMethod.GetStringAttributeL(CMManager::ECmName); CleanupStack::PushL(pName); QT_TRYCATCH_LEAVING(cpPriv->name = QString::fromUtf16(pName->Ptr(),pName->Length())); CleanupStack::PopAndDestroy(pName); pName = NULL; - + TUint32 bearerId = connectionMethod.GetIntAttributeL(CMManager::ECmCommsDBBearerType); switch (bearerId) { case KCommDbBearerCSD: @@ -520,7 +523,7 @@ SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( cpPriv->bearerType = QNetworkConfiguration::BearerUnknown; break; } - + TInt error = KErrNone; TUint32 bearerType = connectionMethod.GetIntAttributeL(CMManager::ECmBearerType); switch (bearerType) { @@ -544,13 +547,13 @@ SymbianNetworkConfigurationPrivate *SymbianEngine::configFromConnectionMethodL( CleanupStack::PopAndDestroy(pName); pName = NULL; } - + cpPriv->state = QNetworkConfiguration::Defined; TBool isConnected = connectionMethod.GetBoolAttributeL(CMManager::ECmConnected); if (isConnected) { cpPriv->state = QNetworkConfiguration::Active; } - + cpPriv->isValid = true; cpPriv->id = ident; cpPriv->numericId = iapId; @@ -566,7 +569,7 @@ bool SymbianEngine::readNetworkConfigurationValuesFromCommsDb( { TRAPD(error, readNetworkConfigurationValuesFromCommsDbL(aApId,apNetworkConfiguration)); if (error != KErrNone) { - return false; + return false; } return true; } @@ -574,22 +577,22 @@ bool SymbianEngine::readNetworkConfigurationValuesFromCommsDb( void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL( TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration) { - CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB); - CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC(); + CApDataHandler* pDataHandler = CApDataHandler::NewLC(*ipCommsDB); + CApAccessPointItem* pAPItem = CApAccessPointItem::NewLC(); TBuf<KCommsDbSvrMaxColumnNameLength> name; - + CApUtils* pApUtils = CApUtils::NewLC(*ipCommsDB); TUint32 apId = pApUtils->WapIdFromIapIdL(aApId); - + pDataHandler->AccessPointDataL(apId,*pAPItem); pAPItem->ReadTextL(EApIapName, name); if (name.Compare(_L("Easy WLAN")) == 0) { // "Easy WLAN" won't be accepted to the Configurations list User::Leave(KErrNotFound); } - + QString ident = QT_BEARERMGMT_CONFIGURATION_IAP_PREFIX+QString::number(qHash(aApId)); - + QT_TRYCATCH_LEAVING(apNetworkConfiguration->name = QString::fromUtf16(name.Ptr(),name.Length())); apNetworkConfiguration->isValid = true; apNetworkConfiguration->id = ident; @@ -600,7 +603,7 @@ void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL( apNetworkConfiguration->purpose = QNetworkConfiguration::UnknownPurpose; apNetworkConfiguration->roamingSupported = false; switch (pAPItem->BearerTypeL()) { - case EApBearerTypeCSD: + case EApBearerTypeCSD: apNetworkConfiguration->bearerType = QNetworkConfiguration::Bearer2G; break; case EApBearerTypeGPRS: @@ -625,7 +628,7 @@ void SymbianEngine::readNetworkConfigurationValuesFromCommsDbL( apNetworkConfiguration->bearerType = QNetworkConfiguration::BearerUnknown; break; } - + CleanupStack::PopAndDestroy(pApUtils); CleanupStack::PopAndDestroy(pAPItem); CleanupStack::PopAndDestroy(pDataHandler); @@ -664,7 +667,7 @@ QNetworkConfigurationPrivatePointer SymbianEngine::defaultConfigurationL() ptr = accessPointConfigurations.value(iface); } #endif - + if (ptr) { QMutexLocker configLocker(&ptr->mutex); if (ptr->isValid) @@ -684,7 +687,7 @@ void SymbianEngine::updateActiveAccessPoints() TUint connectionCount; iConnectionMonitor.GetConnectionCount(connectionCount, status); User::WaitForRequest(status); - + // Go through all connections and set state of related IAPs to Active. // Status needs to be checked carefully, because ConnMon lists also e.g. // WLAN connections that are being currently tried --> we don't want to @@ -763,7 +766,7 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn iUpdateGoingOn = false; if (scanSuccessful) { QList<QString> unavailableConfigs = accessPointConfigurations.keys(); - + // Set state of returned IAPs to Discovered // if state is not already Active for(TUint i=0; i<iapInfo.iCount; i++) { @@ -780,7 +783,7 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn } } } - + // Make sure that state of rest of the IAPs won't be Active foreach (const QString &iface, unavailableConfigs) { QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface); @@ -792,7 +795,7 @@ void SymbianEngine::accessPointScanningReady(TBool scanSuccessful, TConnMonIapIn } updateStatesToSnaps(); - + if (!iFirstUpdate) { startCommsDatabaseNotifications(); mutex.unlock(); @@ -844,7 +847,7 @@ void SymbianEngine::updateStatesToSnaps() } else { changeConfigurationStateTo(ptr, QNetworkConfiguration::Defined); } - } + } } #ifdef SNAP_FUNCTIONALITY_AVAILABLE @@ -1062,7 +1065,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) if (connectionStatus == KConfigDaemonStartingRegistration) { TUint connectionId = realEvent->ConnectionId(); TUint subConnectionCount = 0; - TUint apId; + TUint apId; TRequestStatus status; iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); User::WaitForRequest(status); @@ -1088,7 +1091,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) // Connection has been successfully opened TUint connectionId = realEvent->ConnectionId(); TUint subConnectionCount = 0; - TUint apId; + TUint apId; TRequestStatus status; iConnectionMonitor.GetUintAttribute(connectionId, subConnectionCount, KIAPId, apId, status); User::WaitForRequest(status); @@ -1144,7 +1147,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) connectionId, QNetworkSession::Disconnected); ); } - + bool online = false; foreach (const QString &iface, accessPointConfigurations.keys()) { QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(iface); @@ -1160,7 +1163,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) } } } - break; + break; case EConnMonIapAvailabilityChange: { @@ -1174,7 +1177,7 @@ void SymbianEngine::EventL(const CConnMonEventBase& aEvent) QNetworkConfigurationPrivatePointer ptr = accessPointConfigurations.value(ident); if (ptr) { - // Configuration is either Discovered or Active + // Configuration is either Discovered or Active QT_TRYCATCH_LEAVING(changeConfigurationStateAtMinTo(ptr, QNetworkConfiguration::Discovered)); unDiscoveredConfigs.removeOne(ident); } @@ -1360,7 +1363,7 @@ AccessPointsAvailabilityScanner::AccessPointsAvailabilityScanner(SymbianEngine& RConnectionMonitor& connectionMonitor) : CActive(CActive::EPriorityHigh), iOwner(owner), iConnectionMonitor(connectionMonitor) { - CActiveScheduler::Add(this); + CActiveScheduler::Add(this); } AccessPointsAvailabilityScanner::~AccessPointsAvailabilityScanner() diff --git a/src/plugins/bearer/symbian/symbianengine.h b/src/plugins/bearer/symbian/symbianengine.h index 3b3a78a..a205c97 100644 --- a/src/plugins/bearer/symbian/symbianengine.h +++ b/src/plugins/bearer/symbian/symbianengine.h @@ -145,10 +145,10 @@ public: Q_SIGNALS: void onlineStateChanged(bool isOnline); - + void configurationStateChanged(quint32 accessPointId, quint32 connMonId, QNetworkSession::State newState); - + public Q_SLOTS: void updateConfigurations(); void delayedConfigurationUpdate(); @@ -169,8 +169,8 @@ private: TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration); void readNetworkConfigurationValuesFromCommsDbL( TUint32 aApId, SymbianNetworkConfigurationPrivate *apNetworkConfiguration); -#endif - +#endif + void updateConfigurationsL(); void updateActiveAccessPoints(); void updateAvailableAccessPoints(); @@ -184,11 +184,13 @@ private: void startMonitoringIAPData(TUint32 aIapId); QNetworkConfigurationPrivatePointer dataByConnectionId(TUint aConnectionId); + void StartConnectionMonitorNotifyL(); + protected: // From CActive void RunL(); void DoCancel(); - + private: // MConnectionMonitorObserver void EventL(const CConnMonEventBase& aEvent); @@ -198,7 +200,7 @@ private: #endif private: // Data - bool iFirstUpdate; + bool iFirstUpdate; CCommsDatabase* ipCommsDB; RConnectionMonitor iConnectionMonitor; @@ -225,11 +227,11 @@ class AccessPointsAvailabilityScanner : public CActive { public: AccessPointsAvailabilityScanner(SymbianEngine& owner, - RConnectionMonitor& connectionMonitor); + RConnectionMonitor& connectionMonitor); ~AccessPointsAvailabilityScanner(); void StartScanning(); - + protected: // From CActive void RunL(); void DoCancel(); diff --git a/src/plugins/platforms/openvglite/openvglite.pro b/src/plugins/platforms/openvglite/openvglite.pro deleted file mode 100644 index 9d7860a..0000000 --- a/src/plugins/platforms/openvglite/openvglite.pro +++ /dev/null @@ -1,12 +0,0 @@ -TARGET = qvglitegraphicssystem -include(../../qpluginbase.pri) - -QT += openvg - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/graphicssystems - -SOURCES = main.cpp qgraphicssystem_vglite.cpp qwindowsurface_vglite.cpp -HEADERS = qgraphicssystem_vglite.h qwindowsurface_vglite.h - -target.path += $$[QT_INSTALL_PLUGINS]/graphicssystems -INSTALLS += target diff --git a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp b/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp deleted file mode 100644 index 203896f..0000000 --- a/src/plugins/platforms/openvglite/qgraphicssystem_vglite.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** 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 "qgraphicssystem_vglite.h" -#include "qwindowsurface_vglite.h" -#include <QtOpenVG/private/qpixmapdata_vg_p.h> -#include <QtGui/private/qegl_p.h> -#include <QtCore/qdebug.h> -#ifdef OPENVG_USBHP_INIT -extern "C" { -#include <linuxusbhp.h> -}; -#endif - -QT_BEGIN_NAMESPACE - -QVGLiteGraphicsSystem::QVGLiteGraphicsSystem() - : w(0), h(0), d(0), dw(0), dh(0), physWidth(0), physHeight(0), - surface(0), context(0), rootWindow(0), - screenFormat(QImage::Format_RGB16), preservedSwap(false) -{ -#ifdef OPENVG_USBHP_INIT - initLibrary(); -#endif - - // The graphics system is also the screen definition. - mScreens.append(this); - - QString displaySpec = QString::fromLatin1(qgetenv("QWS_DISPLAY")); - QStringList displayArgs = displaySpec.split(QLatin1Char(':')); - - // Initialize EGL and create the global EGL context. - context = qt_vg_create_context(0); - if (!context) { - qFatal("QVGLiteGraphicsSystem: could not initialize EGL"); - return; - } - - // Get the root window handle to use. Default to zero. - QRegExp winidRx(QLatin1String("winid=?(\\d+)")); - int winidIdx = displayArgs.indexOf(winidRx); - int handle = 0; - if (winidIdx >= 0) { - winidRx.exactMatch(displayArgs.at(winidIdx)); - handle = winidRx.cap(1).toInt(); - } - - // Create a full-screen window based on the native handle. - // If the context is premultiplied, the window should be too. - QEglProperties props; -#ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT - EGLint surfaceType = 0; - if (context->configAttrib(EGL_SURFACE_TYPE, &surfaceType) && - (surfaceType & EGL_VG_ALPHA_FORMAT_PRE_BIT) != 0) - props.setValue(EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE); -#endif - rootWindow = eglCreateWindowSurface - (context->display(), context->config(), - (EGLNativeWindowType)handle, props.properties()); - if (rootWindow == EGL_NO_SURFACE) { - delete context; - context = 0; - qFatal("QVGLiteGraphicsSystem: could not create full-screen window"); - return; - } - - // Try to turn on preserved swap behaviour on the root window. - // This will allow us to optimize compositing to focus on just - // the screen region that has changed. Otherwise we must - // re-composite the entire screen every frame. -#if !defined(QVG_NO_PRESERVED_SWAP) - eglGetError(); // Clear error state first. - eglSurfaceAttrib(context->display(), rootWindow, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); - preservedSwap = (eglGetError() == EGL_SUCCESS); -#else - preservedSwap = false; -#endif - - // Fetch the root window properties. - eglQuerySurface(context->display(), rootWindow, EGL_WIDTH, &w); - eglQuerySurface(context->display(), rootWindow, EGL_HEIGHT, &h); - screenFormat = qt_vg_config_to_image_format(context); - switch (screenFormat) { - case QImage::Format_ARGB32_Premultiplied: - case QImage::Format_ARGB32: - case QImage::Format_RGB32: - default: - d = 32; - break; - case QImage::Format_RGB16: - case QImage::Format_ARGB4444_Premultiplied: - d = 16; - break; - } - dw = w; - dh = h; - qDebug("screen size: %dx%dx%d", w, h, d); - - // Handle display physical size spec. From qscreenlinuxfb_qws.cpp. - QRegExp mmWidthRx(QLatin1String("mmWidth=?(\\d+)")); - int dimIdxW = displayArgs.indexOf(mmWidthRx); - QRegExp mmHeightRx(QLatin1String("mmHeight=?(\\d+)")); - int dimIdxH = displayArgs.indexOf(mmHeightRx); - if (dimIdxW >= 0) { - mmWidthRx.exactMatch(displayArgs.at(dimIdxW)); - physWidth = mmWidthRx.cap(1).toInt(); - if (dimIdxH < 0) - physHeight = dh*physWidth/dw; - } - if (dimIdxH >= 0) { - mmHeightRx.exactMatch(displayArgs.at(dimIdxH)); - physHeight = mmHeightRx.cap(1).toInt(); - if (dimIdxW < 0) - physWidth = dw*physHeight/dh; - } - if (dimIdxW < 0 && dimIdxH < 0) { - const int dpi = 72; - physWidth = qRound(dw * 25.4 / dpi); - physHeight = qRound(dh * 25.4 / dpi); - } -} - -QVGLiteGraphicsSystem::~QVGLiteGraphicsSystem() -{ -} - -QPixmapData *QVGLiteGraphicsSystem::createPixmapData(QPixmapData::PixelType type) const -{ -#if !defined(QVGLite_NO_SINGLE_CONTEXT) && !defined(QVGLite_NO_PIXMAP_DATA) - // Pixmaps can use QVGLitePixmapData; bitmaps must use raster. - if (type == QPixmapData::PixmapType) - return new QVGPixmapData(type); - else - return new QRasterPixmapData(type); -#else - return new QRasterPixmapData(type); -#endif -} - -QWindowSurface *QVGLiteGraphicsSystem::createWindowSurface(QWidget *widget) const -{ - if (widget->windowType() == Qt::Desktop) - return 0; // Don't create an explicit window surface for the destkop. - if (surface) { - qWarning() << "QVGLiteGraphicsSystem: only one window surface " - "is supported at a time"; - return 0; - } - surface = new QVGLiteWindowSurface - (const_cast<QVGLiteGraphicsSystem *>(this), widget); - return surface; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/openvglite/qwindowsurface_vglite.cpp b/src/plugins/platforms/openvglite/qwindowsurface_vglite.cpp deleted file mode 100644 index dad23c1..0000000 --- a/src/plugins/platforms/openvglite/qwindowsurface_vglite.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** 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 "qwindowsurface_vglite.h" -#include "qgraphicssystem_vglite.h" -#include <QtOpenVG/qvg.h> -#include <QtOpenVG/private/qvg_p.h> -#include <QtOpenVG/private/qpaintengine_vg_p.h> - -QT_BEGIN_NAMESPACE - -QVGLiteWindowSurface::QVGLiteWindowSurface - (QVGLiteGraphicsSystem *gs, QWidget *window) - : QWindowSurface(window), graphicsSystem(gs), - isPaintingActive(false), engine(0) -{ -} - -QVGLiteWindowSurface::~QVGLiteWindowSurface() -{ - graphicsSystem->surface = 0; - if (engine) - qt_vg_destroy_paint_engine(engine); -} - -QPaintDevice *QVGLiteWindowSurface::paintDevice() -{ - qt_vg_make_current(graphicsSystem->context, graphicsSystem->rootWindow); - isPaintingActive = true; - // TODO: clear the parts of the back buffer that are not - // covered by the window surface to black. - return this; -} - -void QVGLiteWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) -{ - Q_UNUSED(widget); - Q_UNUSED(region); - Q_UNUSED(offset); - QEglContext *context = graphicsSystem->context; - if (context) { - if (!isPaintingActive) - qt_vg_make_current(context, graphicsSystem->rootWindow); - context->swapBuffers(); - qt_vg_done_current(context); - context->setSurface(EGL_NO_SURFACE); - isPaintingActive = false; - } -} - -void QVGLiteWindowSurface::setGeometry(const QRect &rect) -{ - QWindowSurface::setGeometry(rect); -} - -bool QVGLiteWindowSurface::scroll(const QRegion &area, int dx, int dy) -{ - return QWindowSurface::scroll(area, dx, dy); -} - -void QVGLiteWindowSurface::beginPaint(const QRegion ®ion) -{ - Q_UNUSED(region); -} - -void QVGLiteWindowSurface::endPaint(const QRegion ®ion) -{ - Q_UNUSED(region); -} - -QPaintEngine *QVGLiteWindowSurface::paintEngine() const -{ - if (!engine) - engine = qt_vg_create_paint_engine(); - return engine; -} - -// We need to get access to QWidget::metric() from QVGLiteWindowSurface::metric, -// but it is not a friend of QWidget. To get around this, we create a -// fake QX11PaintEngine class, which is a friend. -class QX11PaintEngine -{ -public: - static int metric(const QWidget *widget, QPaintDevice::PaintDeviceMetric met) - { - return widget->metric(met); - } -}; - -int QVGLiteWindowSurface::metric(PaintDeviceMetric met) const -{ - return QX11PaintEngine::metric(window(), met); -} diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index aedb87e..d764187 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -3058,8 +3058,61 @@ void tst_QAccessibility::lineEditTest() delete iface; delete le; delete le2; - delete toplevel; QTestAccessibility::clearEvents(); + + // IA2 + QString cite = "I always pass on good advice. It is the only thing to do with it. It is never of any use to oneself. --Oscar Wilde"; + QLineEdit *le3 = new QLineEdit(cite, toplevel); + iface = QAccessible::queryAccessibleInterface(le3); + QAccessibleTextInterface* textIface = iface->textInterface(); + le3->deselect(); + le3->setCursorPosition(3); + QCOMPARE(textIface->cursorPosition(), 3); + QCOMPARE(textIface->selectionCount(), 0); + int start, end; + + QCOMPARE(textIface->text(0, 8), QString::fromLatin1("I always")); + QCOMPARE(textIface->textAtOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("I")); + QCOMPARE(start, 0); + QCOMPARE(end, 1); + QCOMPARE(textIface->textBeforeOffset(0, QAccessible2::CharBoundary,&start,&end), QString()); + QCOMPARE(textIface->textAfterOffset(0, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1(" ")); + QCOMPARE(start, 1); + QCOMPARE(end, 2); + + QCOMPARE(textIface->textAtOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("a")); + QCOMPARE(start, 5); + QCOMPARE(end, 6); + QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("w")); + QCOMPARE(textIface->textAfterOffset(5, QAccessible2::CharBoundary,&start,&end), QString::fromLatin1("y")); + + QCOMPARE(textIface->textAtOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always")); + QCOMPARE(start, 2); + QCOMPARE(end, 8); + + QCOMPARE(textIface->textAtOffset(2, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always")); + QCOMPARE(textIface->textAtOffset(7, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("always")); + QCOMPARE(textIface->textAtOffset(8, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" ")); + QCOMPARE(textIface->textAtOffset(25, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("advice")); + QCOMPARE(textIface->textAtOffset(92, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1("oneself")); + + QCOMPARE(textIface->textBeforeOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" ")); + QCOMPARE(textIface->textAfterOffset(5, QAccessible2::WordBoundary,&start,&end), QString::fromLatin1(" ")); + QCOMPARE(textIface->textAtOffset(5, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. ")); + QCOMPARE(start, 0); + QCOMPARE(end, 30); + + QCOMPARE(textIface->textBeforeOffset(40, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("I always pass on good advice. ")); + QCOMPARE(textIface->textAfterOffset(5, QAccessible2::SentenceBoundary,&start,&end), QString::fromLatin1("It is the only thing to do with it. ")); + + QCOMPARE(textIface->textAtOffset(5, QAccessible2::ParagraphBoundary,&start,&end), cite); + QCOMPARE(start, 0); + QCOMPARE(end, cite.length()); + QCOMPARE(textIface->textAtOffset(5, QAccessible2::LineBoundary,&start,&end), cite); + QCOMPARE(textIface->textAtOffset(5, QAccessible2::NoBoundary,&start,&end), cite); + + delete iface; + delete toplevel; } void tst_QAccessibility::workspaceTest() diff --git a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp index e06e3a8..6490bfe 100644 --- a/tests/auto/qdbusconnection/tst_qdbusconnection.cpp +++ b/tests/auto/qdbusconnection/tst_qdbusconnection.cpp @@ -113,6 +113,10 @@ private slots: void serviceRegistrationRaceCondition(); + void registerVirtualObject(); + void callVirtualObject(); + void callVirtualObjectLocal(); + public: QString serviceName() const { return "com.trolltech.Qt.Autotests.QDBusConnection"; } bool callMethod(const QDBusConnection &conn, const QString &path); @@ -823,7 +827,6 @@ bool tst_QDBusConnection::callMethod(const QDBusConnection &conn, const QString { QDBusMessage msg = QDBusMessage::createMethodCall(conn.baseService(), path, "", "method"); QDBusMessage reply = conn.call(msg, QDBus::Block/*WithGui*/); - if (reply.type() != QDBusMessage::ReplyMessage) return false; if (MyObject::path == path) { @@ -1098,6 +1101,203 @@ void tst_QDBusConnection::serviceRegistrationRaceCondition() QCOMPARE(recv.count, 1); } +class VirtualObject: public QDBusVirtualObject +{ + Q_OBJECT +public: + VirtualObject() :success(true) {} + + QString introspect(const QString &path) const + { + return QString(); + } + + bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) { + ++callCount; + lastMessage = message; + + if (success) { + QDBusMessage reply = message.createReply(replyArguments); + connection.send(reply); + } + emit messageReceived(message); + return success; + } +signals: + void messageReceived(const QDBusMessage &message) const; + +public: + mutable QDBusMessage lastMessage; + QVariantList replyArguments; + mutable int callCount; + bool success; +}; + + +void tst_QDBusConnection::registerVirtualObject() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QString path = "/tree/node"; + QString childPath = "/tree/node/child"; + QString childChildPath = "/tree/node/child/another"; + + { + // Register VirtualObject that handles child paths. Unregister by going out of scope. + VirtualObject obj; + QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj)); + QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&obj)); + } + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0)); + + { + // Register VirtualObject that handles child paths. Unregister by calling unregister. + VirtualObject obj; + QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj)); + QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(&obj)); + con.unregisterObject(path); + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0)); + } + + { + // Single node has no sub path handling. + VirtualObject obj; + QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SingleNode)); + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0)); + } + + { + // Register VirtualObject that handles child paths. Try to register an object on a child path of that. + VirtualObject obj; + QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(&obj)); + + QObject objectAtSubPath; + QVERIFY(!con.registerObject(path, &objectAtSubPath)); + QVERIFY(!con.registerObject(childPath, &objectAtSubPath)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&obj)); + } + + { + // Register object, make sure no SubPath handling object can be registered on a parent path. + QObject objectAtSubPath; + QVERIFY(con.registerObject(childPath, &objectAtSubPath)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(&objectAtSubPath)); + + VirtualObject obj; + QVERIFY(!con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0)); + } + QCOMPARE(con.objectRegisteredAt(path), static_cast<QObject *>(0)); + QCOMPARE(con.objectRegisteredAt(childPath), static_cast<QObject *>(0)); + QCOMPARE(con.objectRegisteredAt(childChildPath), static_cast<QObject *>(0)); +} + +void tst_QDBusConnection::callVirtualObject() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QDBusConnection con2 = QDBusConnection::connectToBus(QDBusConnection::SessionBus, "con2"); + + QString path = "/tree/node"; + QString childPath = "/tree/node/child"; + + // register one object at root: + VirtualObject obj; + QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + obj.callCount = 0; + obj.replyArguments << 42 << 47u; + + QObject::connect(&obj, SIGNAL(messageReceived(QDBusMessage)), &QTestEventLoop::instance(), SLOT(exitLoop())); + + QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, QString(), "hello"); + QDBusPendingCall reply = con2.asyncCall(message); + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(obj.callCount, 1); + QCOMPARE(obj.lastMessage.service(), con2.baseService()); + QCOMPARE(obj.lastMessage.interface(), QString()); + QCOMPARE(obj.lastMessage.path(), path); + reply.waitForFinished(); + QVERIFY(reply.isValid()); + QCOMPARE(reply.reply().arguments(), obj.replyArguments); + + // call sub path + QDBusMessage childMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "helloChild"); + obj.replyArguments.clear(); + obj.replyArguments << 99; + QDBusPendingCall childReply = con2.asyncCall(childMessage); + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QCOMPARE(obj.callCount, 2); + QCOMPARE(obj.lastMessage.service(), con2.baseService()); + QCOMPARE(obj.lastMessage.interface(), QString()); + QCOMPARE(obj.lastMessage.path(), childPath); + + childReply.waitForFinished(); + QVERIFY(childReply.isValid()); + QCOMPARE(childReply.reply().arguments(), obj.replyArguments); + + // let the call fail by having the virtual object return false + obj.success = false; + QDBusMessage errorMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "someFunc"); + QDBusPendingCall errorReply = con2.asyncCall(errorMessage); + + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + QTest::qWait(100); + QVERIFY(errorReply.isError()); + qDebug() << errorReply.reply().arguments(); + QCOMPARE(errorReply.reply().errorName(), QString("org.freedesktop.DBus.Error.UnknownObject")); + + QDBusConnection::disconnectFromBus("con2"); +} + +void tst_QDBusConnection::callVirtualObjectLocal() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + + QString path = "/tree/node"; + QString childPath = "/tree/node/child"; + + // register one object at root: + VirtualObject obj; + QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + obj.callCount = 0; + obj.replyArguments << 42 << 47u; + + QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, QString(), "hello"); + QDBusMessage reply = con.call(message, QDBus::Block, 5000); + QCOMPARE(obj.callCount, 1); + QCOMPARE(obj.lastMessage.service(), con.baseService()); + QCOMPARE(obj.lastMessage.interface(), QString()); + QCOMPARE(obj.lastMessage.path(), path); + QCOMPARE(obj.replyArguments, reply.arguments()); + + obj.replyArguments << QString("alien abduction"); + QDBusMessage subPathMessage = QDBusMessage::createMethodCall(con.baseService(), childPath, QString(), "hello"); + QDBusMessage subPathReply = con.call(subPathMessage , QDBus::Block, 5000); + QCOMPARE(obj.callCount, 2); + QCOMPARE(obj.lastMessage.service(), con.baseService()); + QCOMPARE(obj.lastMessage.interface(), QString()); + QCOMPARE(obj.lastMessage.path(), childPath); + QCOMPARE(obj.replyArguments, subPathReply.arguments()); +} + QString MyObject::path; QTEST_MAIN(tst_QDBusConnection) diff --git a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp index 96ab311..9156818 100644 --- a/tests/auto/qdbusinterface/tst_qdbusinterface.cpp +++ b/tests/auto/qdbusinterface/tst_qdbusinterface.cpp @@ -200,6 +200,7 @@ private slots: void invalidAfterServiceOwnerChanged(); void introspect(); void introspectUnknownTypes(); + void introspectVirtualObject(); void callMethod(); void invokeMethod(); void invokeMethodWithReturn(); @@ -361,7 +362,6 @@ void tst_QDBusInterface::invalidAfterServiceOwnerChanged() void tst_QDBusInterface::introspect() { - QDBusConnection con = QDBusConnection::sessionBus(); QDBusInterface iface(QDBusConnection::sessionBus().baseService(), QLatin1String("/"), TEST_INTERFACE_NAME); @@ -394,6 +394,75 @@ void tst_QDBusInterface::introspectUnknownTypes() QVERIFY(mo->indexOfProperty("prop1") != -1); int pidx = mo->indexOfProperty("prop1"); QCOMPARE(mo->property(pidx).typeName(), "QDBusRawType<0x7e>*"); + + + + QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), "/unknownTypes", "org.freedesktop.DBus.Introspectable", "Introspect"); + QDBusMessage reply = con.call(message, QDBus::Block, 5000); + qDebug() << "REPL: " << reply.arguments(); + +} + + +class VirtualObject: public QDBusVirtualObject +{ + Q_OBJECT +public: + VirtualObject() :success(true) {} + + QString introspect(const QString &path) const { + if (path == "/some/path/superNode") + return "zitroneneis"; + if (path == "/some/path/superNode/foo") + return " <interface name=\"com.trolltech.QtDBus.VirtualObject\">\n" + " <method name=\"klingeling\" />\n" + " </interface>\n" ; + return QString(); + } + + bool handleMessage(const QDBusMessage &message, const QDBusConnection &connection) { + ++callCount; + lastMessage = message; + + if (success) { + QDBusMessage reply = message.createReply(replyArguments); + connection.send(reply); + } + emit messageReceived(message); + return success; + } +signals: + void messageReceived(const QDBusMessage &message) const; + +public: + mutable QDBusMessage lastMessage; + QVariantList replyArguments; + mutable int callCount; + bool success; +}; + +void tst_QDBusInterface::introspectVirtualObject() +{ + QDBusConnection con = QDBusConnection::sessionBus(); + QVERIFY(con.isConnected()); + VirtualObject obj; + + obj.success = false; + + QString path = "/some/path/superNode"; + QVERIFY(con.registerVirtualObject(path, &obj, QDBusConnection::SubPath)); + + QDBusMessage message = QDBusMessage::createMethodCall(con.baseService(), path, "org.freedesktop.DBus.Introspectable", "Introspect"); + QDBusMessage reply = con.call(message, QDBus::Block, 5000); + QVERIFY(reply.arguments().at(0).toString().contains( + QRegExp("<node>.*zitroneneis.*<interface name=") )); + + QDBusMessage message2 = QDBusMessage::createMethodCall(con.baseService(), path + "/foo", "org.freedesktop.DBus.Introspectable", "Introspect"); + QDBusMessage reply2 = con.call(message2, QDBus::Block, 5000); + QVERIFY(reply2.arguments().at(0).toString().contains( + QRegExp("<node>.*<interface name=\"com.trolltech.QtDBus.VirtualObject\">" + ".*<method name=\"klingeling\" />\n" + ".*</interface>.*<interface name=") )); } void tst_QDBusInterface::callMethod() diff --git a/tests/auto/qpainterpath/tst_qpainterpath.cpp b/tests/auto/qpainterpath/tst_qpainterpath.cpp index 3941a11..33315ad 100644 --- a/tests/auto/qpainterpath/tst_qpainterpath.cpp +++ b/tests/auto/qpainterpath/tst_qpainterpath.cpp @@ -114,6 +114,8 @@ private slots: void connectPathMoveTo(); void translate(); + + void lineWithinBounds(); }; // Testing get/set functions @@ -1306,6 +1308,25 @@ void tst_QPainterPath::translate() QCOMPARE(complexPath.translated(-offset), untranslatedComplexPath); } + +void tst_QPainterPath::lineWithinBounds() +{ + const int iteration_count = 3; + volatile const qreal yVal = 0.5; + QPointF a(0.0, yVal); + QPointF b(1000.0, yVal); + QPointF c(2000.0, yVal); + QPointF d(3000.0, yVal); + QPainterPath path; + path.moveTo(QPointF(0, yVal)); + path.cubicTo(QPointF(1000.0, yVal), QPointF(2000.0, yVal), QPointF(3000.0, yVal)); + for(int i=0; i<=iteration_count; i++) { + qreal actual = path.pointAtPercent(qreal(i) / iteration_count).y(); + QVERIFY(actual == yVal); // don't use QCOMPARE, don't want fuzzy comparison + } +} + + QTEST_APPLESS_MAIN(tst_QPainterPath) #include "tst_qpainterpath.moc" diff --git a/tests/auto/qs60mainapplication/qs60mainapplication.pro b/tests/auto/qs60mainapplication/qs60mainapplication.pro index bbd6c30..de3f59d 100644 --- a/tests/auto/qs60mainapplication/qs60mainapplication.pro +++ b/tests/auto/qs60mainapplication/qs60mainapplication.pro @@ -2,3 +2,4 @@ load(qttest_p4) SOURCES += tst_qs60mainapplication.cpp symbian:LIBS += -lapparc -leikcore -lcone -lavkon +symbian:LIBS += -lremconcoreapi -lremconinterfacebase
\ No newline at end of file diff --git a/tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp b/tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp index 069fd14..967ce4e 100644 --- a/tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp +++ b/tests/auto/qs60mainapplication/tst_qs60mainapplication.cpp @@ -59,6 +59,8 @@ public slots: void cleanup(); private slots: void customQS60MainApplication(); + void testMultimediaKeys_data(); + void testMultimediaKeys(); }; void tst_QS60MainApplication::initTestCase() @@ -115,6 +117,201 @@ CApaApplication *factory() { return new (ELeave) CustomMainApplication; } + +#include <remconcoreapicontrollerobserver.h> +#include <remconcoreapicontroller.h> +#include <remconinterfaceselector.h> +#include <QTimer> +#include <QSignalSpy> + +class KeyGenerator : public QObject, + public MRemConCoreApiControllerObserver +{ + Q_OBJECT +public: + KeyGenerator(QObject *parent = 0); + ~KeyGenerator(); + void MrccacoResponse(TRemConCoreApiOperationId operationId, TInt error); + + void simulateKey(int qtKey); + +private: + void init(); + void cleanup(); + + CRemConInterfaceSelector *interfaceSelector; + CRemConCoreApiController *coreController; +}; + +KeyGenerator::KeyGenerator(QObject *parent) : QObject(parent) +{ + init(); +} + +KeyGenerator::~KeyGenerator() +{ + cleanup(); +} + +void KeyGenerator::MrccacoResponse(TRemConCoreApiOperationId operationId, TInt error) +{ + Q_UNUSED(operationId); + Q_UNUSED(error); +} + +/* + * Generates keyPress and keyRelease events for given key + */ +void KeyGenerator::simulateKey(int qtKey) +{ + if (!coreController) + return; + + TRemConCoreApiButtonAction action = ERemConCoreApiButtonClick; + TUint numRemotes = 0; + TRequestStatus status; + bool wait = true; + + switch (qtKey) { + // media keys + case Qt::Key_VolumeUp: + coreController->VolumeUp(status, numRemotes, action); + break; + case Qt::Key_VolumeDown: + coreController->VolumeDown(status, numRemotes, action); + break; + case Qt::Key_MediaStop: + coreController->Stop(status, numRemotes, action); + break; + case Qt::Key_MediaTogglePlayPause: + coreController->PausePlayFunction(status, numRemotes, action); + break; + case Qt::Key_MediaNext: + coreController->Forward(status, numRemotes, action); + break; + case Qt::Key_MediaPrevious: + coreController->Backward(status, numRemotes, action); + break; + case Qt::Key_AudioForward: + coreController->FastForward(status, numRemotes, action); + break; + case Qt::Key_AudioRewind: + coreController->Rewind(status, numRemotes, action); + break; + // accessory keys + case Qt::Key_Select: + coreController->Select(status, numRemotes, action); + break; + case Qt::Key_Enter: + coreController->Enter(status, numRemotes, action); + break; + case Qt::Key_PageUp: + coreController->PageUp(status, numRemotes, action); + break; + case Qt::Key_PageDown: + coreController->PageDown(status, numRemotes, action); + break; + case Qt::Key_Left: + coreController->Left(status, numRemotes, action); + break; + case Qt::Key_Right: + coreController->Right(status, numRemotes, action); + break; + case Qt::Key_Up: + coreController->Up(status, numRemotes, action); + break; + case Qt::Key_Down: + coreController->Down(status, numRemotes, action); + break; + case Qt::Key_Help: + coreController->Help(status, numRemotes, action); + break; + case Qt::Key_F1: + coreController->F1(status, numRemotes, action); + break; + case Qt::Key_F2: + coreController->F2(status, numRemotes, action); + break; + case Qt::Key_F3: + coreController->F3(status, numRemotes, action); + break; + case Qt::Key_F4: + coreController->F4(status, numRemotes, action); + break; + case Qt::Key_F5: + coreController->F5(status, numRemotes, action); + break; + default: + wait = false; + break; + } + + if (wait) + User::WaitForRequest(status); +} + +void KeyGenerator::init() +{ + try { + QT_TRAP_THROWING(interfaceSelector = CRemConInterfaceSelector::NewL()); + QT_TRAP_THROWING(coreController = CRemConCoreApiController::NewL(*interfaceSelector, *this)); + QT_TRAP_THROWING(interfaceSelector->OpenControllerL()); + } catch (const std::exception &e) { + cleanup(); + } +} + +void KeyGenerator::cleanup() +{ + delete interfaceSelector; + interfaceSelector = 0; + coreController = 0; +} + +const int keyEventTimeout = 2000; // 2secs + +class TestWidget : public QWidget +{ + Q_OBJECT +public: + TestWidget(QWidget *parent = 0); + ~TestWidget(); + +signals: + void keyPress(int key); + void keyRelease(int key); + +protected: + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *event); + +private: + QTimer exitTimer; +}; + +TestWidget::TestWidget(QWidget *parent) : QWidget(parent) +{ + // quit if no events are received + exitTimer.setSingleShot(true); + exitTimer.start(keyEventTimeout); + connect(&exitTimer, SIGNAL(timeout()), qApp, SLOT(quit())); +} + +TestWidget::~TestWidget() +{ +} + +void TestWidget::keyPressEvent(QKeyEvent *event) +{ + emit keyPress(event->key()); +} + +void TestWidget::keyReleaseEvent(QKeyEvent *event) +{ + emit keyRelease(event->key()); + qApp->quit(); // test is done so quit immediately +} + #endif // Q_WS_S60 void tst_QS60MainApplication::customQS60MainApplication() @@ -129,5 +326,67 @@ void tst_QS60MainApplication::customQS60MainApplication() #endif } +void tst_QS60MainApplication::testMultimediaKeys_data() +{ + QTest::addColumn<int>("key"); + + QTest::newRow("Key_VolumeUp") << (int)Qt::Key_VolumeUp; + QTest::newRow("Key_VolumeDown") << (int)Qt::Key_VolumeDown; + QTest::newRow("Key_MediaStop") << (int)Qt::Key_MediaStop; + QTest::newRow("Key_MediaTogglePlayPause") << (int)Qt::Key_MediaTogglePlayPause; + QTest::newRow("Key_MediaNext") << (int)Qt::Key_MediaNext; + QTest::newRow("Key_MediaPrevious") << (int)Qt::Key_MediaPrevious; + QTest::newRow("Key_AudioForward") << (int)Qt::Key_AudioForward; + QTest::newRow("Key_AudioRewind") << (int)Qt::Key_AudioRewind; + + QTest::newRow("Key_Select") << (int)Qt::Key_Select; + QTest::newRow("Key_Enter") << (int)Qt::Key_Enter; + QTest::newRow("Key_PageUp") << (int)Qt::Key_PageUp; + QTest::newRow("Key_PageDown") << (int)Qt::Key_PageDown; + QTest::newRow("Key_Left") << (int)Qt::Key_Left; + QTest::newRow("Key_Right") << (int)Qt::Key_Right; + QTest::newRow("Key_Up") << (int)Qt::Key_Up; + QTest::newRow("Key_Down") << (int)Qt::Key_Down; + QTest::newRow("Key_Help") << (int)Qt::Key_Help; + QTest::newRow("Key_F1") << (int)Qt::Key_F1; + QTest::newRow("Key_F2") << (int)Qt::Key_F2; + QTest::newRow("Key_F3") << (int)Qt::Key_F3; + QTest::newRow("Key_F4") << (int)Qt::Key_F4; + QTest::newRow("Key_F5") << (int)Qt::Key_F5; +} + +void tst_QS60MainApplication::testMultimediaKeys() +{ +#ifndef Q_WS_S60 + QSKIP("This is an S60-only test", SkipAll); +#elif __WINS__ + QSKIP("S60 emulator not supported", SkipAll); +#else + QApplication::setAttribute(Qt::AA_CaptureMultimediaKeys); + int argc = 1; + char *argv = "tst_qs60mainapplication"; + QApplication app(argc, &argv); + + QFETCH(int, key); + KeyGenerator keyGen; + keyGen.simulateKey(key); + + TestWidget widget; + QSignalSpy keyPressSpy(&widget, SIGNAL(keyPress(int))); + QSignalSpy keyReleaseSpy(&widget, SIGNAL(keyRelease(int))); + + widget.show(); + app.exec(); + + QCOMPARE(keyPressSpy.count(), 1); + QList<QVariant> arguments = keyPressSpy.takeFirst(); + QVERIFY(arguments.at(0).toInt() == key); + + QCOMPARE(keyReleaseSpy.count(), 1); + arguments = keyReleaseSpy.takeFirst(); + QVERIFY(arguments.at(0).toInt() == key); +#endif +} + QTEST_APPLESS_MAIN(tst_QS60MainApplication) #include "tst_qs60mainapplication.moc" diff --git a/tools/qvfb/qvfb.pro b/tools/qvfb/qvfb.pro index c101d00..29ce202 100644 --- a/tools/qvfb/qvfb.pro +++ b/tools/qvfb/qvfb.pro @@ -8,9 +8,6 @@ DESTDIR = ../../bin target.path=$$[QT_INSTALL_BINS] INSTALLS += target -DEPENDPATH = ../../include -INCLUDEPATH += ../../src/gui/embedded - FORMS = config.ui HEADERS = qvfb.h \ qvfbview.h \ @@ -19,10 +16,7 @@ HEADERS = qvfb.h \ gammaview.h \ qvfbprotocol.h \ qvfbshmem.h \ - qvfbmmap.h \ - ../../src/gui/embedded/qvfbhdr.h \ - ../../src/gui/embedded/qlock_p.h \ - ../../src/gui/embedded/qwssignalhandler_p.h + qvfbmmap.h SOURCES = qvfb.cpp \ qvfbview.cpp \ @@ -31,9 +25,7 @@ SOURCES = qvfb.cpp \ qanimationwriter.cpp \ qvfbprotocol.cpp \ qvfbshmem.cpp \ - qvfbmmap.cpp \ - ../../src/gui/embedded/qlock.cpp \ - ../../src/gui/embedded/qwssignalhandler.cpp + qvfbmmap.cpp include(../shared/deviceskin/deviceskin.pri) diff --git a/tools/qvfb/qvfbmmap.cpp b/tools/qvfb/qvfbmmap.cpp index 7e80e37..01c1d9c 100644 --- a/tools/qvfb/qvfbmmap.cpp +++ b/tools/qvfb/qvfbmmap.cpp @@ -48,9 +48,7 @@ #include <unistd.h> #include <sys/ipc.h> #include <sys/types.h> -#include <sys/shm.h> #include <sys/stat.h> -#include <sys/sem.h> #include <sys/mman.h> #include <fcntl.h> #include <errno.h> diff --git a/tools/qvfb/qvfbshmem.cpp b/tools/qvfb/qvfbshmem.cpp index a03b25d..c17a680 100644 --- a/tools/qvfb/qvfbshmem.cpp +++ b/tools/qvfb/qvfbshmem.cpp @@ -39,10 +39,9 @@ ** ****************************************************************************/ -#include "qlock_p.h" - #include "qvfbshmem.h" -#include "qvfbhdr.h" +#include <qvfbhdr.h> +#include <private/qlock_p.h> #include <QFile> #include <QTimer> @@ -53,8 +52,6 @@ #include <sys/types.h> #include <sys/shm.h> #include <sys/stat.h> -#include <sys/sem.h> -#include <sys/mman.h> #include <fcntl.h> #include <errno.h> #include <math.h> @@ -69,27 +66,40 @@ QT_BEGIN_NAMESPACE // live. static QString qws_dataDir(int qws_display_id) { - QByteArray dataDir = QT_VFB_DATADIR(qws_display_id).toLocal8Bit(); - if (mkdir(dataDir, 0700)) { + static QString result; + if (!result.isEmpty()) + return result; + result = QT_VFB_DATADIR(qws_display_id); + QByteArray dataDir = result.toLocal8Bit(); + +#if defined(Q_OS_INTEGRITY) + /* ensure filesystem is ready before starting requests */ + WaitForFileSystemInitialization(); +#endif + + if (QT_MKDIR(dataDir, 0700)) { if (errno != EEXIST) { qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData()); } } - struct stat buf; - if (lstat(dataDir, &buf)) + QT_STATBUF buf; + if (QT_LSTAT(dataDir, &buf)) qFatal("stat failed for Qt for Embedded Linux data directory: %s", dataDir.constData()); if (!S_ISDIR(buf.st_mode)) qFatal("%s is not a directory", dataDir.constData()); + +#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS) && !defined(Q_OS_QNX) if (buf.st_uid != getuid()) qFatal("Qt for Embedded Linux data directory is not owned by user %uh", getuid()); if ((buf.st_mode & 0677) != 0600) qFatal("Qt for Embedded Linux data directory has incorrect permissions: %s", dataDir.constData()); - dataDir += "/"; +#endif - return QString(dataDir); + result.append(QLatin1Char('/')); + return result; } @@ -130,20 +140,10 @@ QShMemViewProtocol::QShMemViewProtocol(int displayid, const QSize &s, qws_dataDir(displayid); - QString oldPipe = "/tmp/qtembedded-" + username + "/" + QString("QtEmbedded-%1").arg(displayid); - int oldPipeSemkey = ftok(oldPipe.toLatin1().constData(), 'd'); - if (oldPipeSemkey != -1) { - int oldPipeLockId = semget(oldPipeSemkey, 0, 0); - if (oldPipeLockId >= 0){ - sembuf sops; - sops.sem_num = 0; - sops.sem_op = 1; - sops.sem_flg = SEM_UNDO; - int rv; - do { - rv = semop(lockId,&sops,1); - } while (rv == -1 && errno == EINTR); - + { + QString oldPipe = "/tmp/qtembedded-" + username + "/" + QString("QtEmbedded-%1").arg(displayid); + QLock oldPipeLock(oldPipe, 'd', false); + if (oldPipeLock.isValid()) { perror("QShMemViewProtocol::QShMemViewProtocol"); qFatal("Cannot create lock file as an old version of QVFb has " "opened %s. Close other QVFb and try again", diff --git a/tools/qvfb/qvfbview.cpp b/tools/qvfb/qvfbview.cpp index 3f13ecc..91c5380 100644 --- a/tools/qvfb/qvfbview.cpp +++ b/tools/qvfb/qvfbview.cpp @@ -61,12 +61,7 @@ #include <stdlib.h> #include <unistd.h> -#include <sys/ipc.h> #include <sys/types.h> -#include <sys/shm.h> -#include <sys/stat.h> -#include <sys/sem.h> -#include <fcntl.h> #include <errno.h> #include <math.h> |