From 5396e4de1146220e9fb57e42fa30083148af7798 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Mon, 20 Jul 2009 18:44:34 +0200 Subject: fix qmake syntax Reviewed-by: TrustMe --- mkspecs/features/moc.prf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/moc.prf b/mkspecs/features/moc.prf index 33a58ad..62d9092 100644 --- a/mkspecs/features/moc.prf +++ b/mkspecs/features/moc.prf @@ -65,7 +65,7 @@ moc_header.output = $$MOC_DIR/$${QMAKE_H_MOD_MOC}${QMAKE_FILE_BASE}$${first(QMAK moc_header.input = HEADERS moc_header.variable_out = SOURCES moc_header.name = MOC ${QMAKE_FILE_IN} -if(!contains(TEMPLATE, "vc.*") & !contains(TEMPLATE_PREFIX, "vc")) { +if(!contains(TEMPLATE, "vc.*"):!contains(TEMPLATE_PREFIX, "vc")) { !isEmpty(INCLUDETEMP):moc_header.depends += $$INCLUDETEMP } silent:moc_header.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_header.commands @@ -79,7 +79,7 @@ moc_source.commands = ${QMAKE_FUNC_mocCmd} moc_source.output = $$MOC_DIR/$${QMAKE_CPP_MOD_MOC}${QMAKE_FILE_BASE}$${QMAKE_EXT_CPP_MOC} moc_source.input = SOURCES OBJECTIVE_SOURCES moc_source.name = MOC ${QMAKE_FILE_IN} -if(!contains(TEMPLATE, "vc.*") & !contains(TEMPLATE_PREFIX, "vc")) { +if(!contains(TEMPLATE, "vc.*"):!contains(TEMPLATE_PREFIX, "vc")) { !isEmpty(INCLUDETEMP):moc_source.depends += $$INCLUDETEMP } silent:moc_source.commands = @echo moc ${QMAKE_FILE_IN} && $$moc_source.commands -- cgit v0.12 From d3053c64e6e61656f8ea1fa809648228d0393957 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Mon, 20 Jul 2009 09:53:21 -0700 Subject: s/slots/Q_SLOTS/ Fix QDirectFBMousePrivate and QDirectFBKeyboardPrivate Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp | 2 +- src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp index ed59db8..b5376b1 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbkeyboard.cpp @@ -78,7 +78,7 @@ private: DFBEvent event; int bytesRead; -private slots: +private Q_SLOTS: void readKeyboardData(); }; diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp index 694ba51..142993d 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbmouse.cpp @@ -71,7 +71,7 @@ private: DFBEvent event; uint bytesRead; -private slots: +private Q_SLOTS: void readMouseData(); }; -- cgit v0.12 From 08834e4f7af8c1a4fe34ccfbbb8d2c973e91eb48 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Tue, 21 Jul 2009 09:03:20 +1000 Subject: Fixed compile on certain Solaris versions. Every source file must end with a newline, otherwise: "Error: There is extra text on this line." --- src/sql/drivers/mysql/qsql_mysql.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index dd4127c..8f377bd 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1473,4 +1473,4 @@ QString QMYSQLDriver::escapeIdentifier(const QString &identifier, IdentifierType QT_END_NAMESPACE -#include "qsql_mysql.moc" \ No newline at end of file +#include "qsql_mysql.moc" -- cgit v0.12 From 5538d52eec9454404d3e02d9d23cc562b91a68e0 Mon Sep 17 00:00:00 2001 From: Benjamin C Meyer Date: Tue, 21 Jul 2009 13:46:20 +1000 Subject: Match the behavior of the Windows configure and allow the user to type 'y' rather then 'yes' Merge-request: 945 Reviewed-by: Rohan McGovern --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index f7e8005..13bdf7f 100755 --- a/configure +++ b/configure @@ -3769,7 +3769,7 @@ elif [ "$Edition" = "OpenSource" ]; then read acceptance fi echo - if [ "$acceptance" = "yes" ]; then + if [ "$acceptance" = "yes" ] || [ "$acceptance" = "y" ]; then break elif [ "$acceptance" = "no" ]; then echo "You are not licensed to use this software." -- cgit v0.12 From c6d243df383514f2bf30e178eba087a312191b0f Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jul 2009 10:03:17 +0200 Subject: Doc: mark QImage/QPixmap alphaChannel and setAlphaChannel as obsolete. They are expensive - which is why QImage::setALphaChannel had been obsoleted in Qt 4.5. Reviewed-by: Gunnar --- src/gui/image/qimage.cpp | 9 +++--- src/gui/image/qpixmap.cpp | 70 +++++++++++++++++++++++------------------------ 2 files changed, 38 insertions(+), 41 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index ad55dcd..7d7dde1 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -612,9 +612,6 @@ bool QImageData::checkForAlphaPixels() const \table \header \o Function \o Description \row - \o setAlphaChannel() - \o Sets the alpha channel of the image. - \row \o setDotsPerMeterX() \o Defines the aspect ratio by setting the number of pixels that fit horizontally in a physical meter. @@ -5587,7 +5584,7 @@ bool QImage::isDetached() const Note that the image will be converted to the Format_ARGB32_Premultiplied format if the function succeeds. - Use one of the composition mods in QPainter::CompositionMode instead. + Use one of the composition modes in QPainter::CompositionMode instead. \warning This function is expensive. @@ -5665,6 +5662,8 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) /*! + \obsolete + Returns the alpha channel of the image as a new grayscale QImage in which each pixel's red, green, and blue values are given the alpha value of the original image. The color depth of the returned image is 8-bit. @@ -5744,7 +5743,7 @@ QImage QImage::alphaChannel() const Returns true if the image has a format that respects the alpha channel, otherwise returns false. - \sa alphaChannel(), {QImage#Image Information}{Image Information} + \sa {QImage#Image Information}{Image Information} */ bool QImage::hasAlphaChannel() const { diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 72fdec0..3e5c9b7 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1572,24 +1572,24 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) designed and optimized for showing images on screen. QBitmap is only a convenience class that inherits QPixmap, ensuring a depth of 1. The isQBitmap() function returns true if a QPixmap object is - really a bitmap, otherwise returns false. Finally, the QPicture class is a - paint device that records and replays QPainter commands. + really a bitmap, otherwise returns false. Finally, the QPicture class + is a paint device that records and replays QPainter commands. A QPixmap can easily be displayed on the screen using QLabel or one of QAbstractButton's subclasses (such as QPushButton and QToolButton). QLabel has a pixmap property, whereas - QAbstractButton has an icon property. And because QPixmap is a - QPaintDevice subclass, QPainter can be used to draw directly onto - pixmaps. + QAbstractButton has an icon property. In addition to the ordinary constructors, a QPixmap can be constructed using the static grabWidget() and grabWindow() functions which creates a QPixmap and paints the given widget, or - window, in it. + window, into it. + + QPixmap objects can be passed around by value since the QPixmap + class uses implicit data sharing. For more information, see the \l + {Implicit Data Sharing} documentation. QPixmap objects can also be + streamed. - Note that the pixel data in a pixmap is internal and is managed by - the underlying window system. Pixels can only be accessed through - QPainter functions or by converting the QPixmap to a QImage. Depending on the system, QPixmap is stored using a RGB32 or a premultiplied alpha format. If the image has an alpha channel, and if the system allows, the preferred format is premultiplied alpha. @@ -1600,6 +1600,13 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) QPixmap are stored on the client side and don't use any GDI resources). + Note that the pixel data in a pixmap is internal and is managed by + the underlying window system. Because QPixmap is a QPaintDevice + subclass, QPainter can be used to draw directly onto pixmaps. + Pixels can only be accessed through QPainter functions or by + converting the QPixmap to a QImage. However, the fill() function + is available for initializing the entire pixmap with a given color. + There are functions to convert between QImage and QPixmap. Typically, the QImage class is used to load an image file, optionally manipulating the image data, before the QImage @@ -1614,11 +1621,6 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) there are several functions that enables transformation of the pixmap. - QPixmap objects can be passed around by value since the QPixmap - class uses implicit data sharing. For more information, see the \l - {Implicit Data Sharing} documentation. QPixmap objects can also be - streamed. - \tableofcontents \section1 Reading and Writing Image Files @@ -1675,12 +1677,15 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) The hasAlphaChannel() returns true if the pixmap has a format that respects the alpha channel, otherwise returns false, while the hasAlpha() function returns true if the pixmap has an alpha - channel \e or a mask (otherwise false). + channel \e or a mask (otherwise false). The mask() function returns + the mask as a QBitmap object, which can be set using setMask(). - The alphaChannel() function returns the alpha channel as a new - QPixmap object, while the mask() function returns the mask as a - QBitmap object. The alpha channel and mask can be set using the - setAlphaChannel() and setMask() functions, respectively. + The createHeuristicMask() function creates and returns a 1-bpp + heuristic mask (i.e. a QBitmap) for this pixmap. It works by + selecting a color from one of the corners and then chipping away + pixels of that color, starting at all the edges. The + createMaskFromColor() function creates and returns a mask (i.e. a + QBitmap) for the pixmap based on a given color. \row \o Low-level information @@ -1718,14 +1723,7 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) \section1 Pixmap Transformations QPixmap supports a number of functions for creating a new pixmap - that is a transformed version of the original: The - createHeuristicMask() function creates and returns a 1-bpp - heuristic mask (i.e. a QBitmap) for this pixmap. It works by - selecting a color from one of the corners and then chipping away - pixels of that color, starting at all the edges. The - createMaskFromColor() function creates and returns a mask (i.e. a - QBitmap) for the pixmap based on a given color. - + that is a transformed version of the original: The scaled(), scaledToWidth() and scaledToHeight() functions return scaled copies of the pixmap, while the copy() function @@ -1740,11 +1738,6 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) function returns the actual matrix used for transforming the pixmap. - There are also functions for changing attributes of a pixmap. - in-place: The fill() function fills the entire image with the - given color, the setMask() function sets a mask bitmap, and the - setAlphaChannel() function sets the pixmap's alpha channel. - \sa QBitmap, QImage, QImageReader, QImageWriter */ @@ -1763,7 +1756,7 @@ QPixmap QPixmap::transformed(const QMatrix &matrix, Qt::TransformationMode mode) Returns true if this pixmap has an alpha channel, \e or has a mask, otherwise returns false. - \sa hasAlphaChannel(), alphaChannel(), mask() + \sa hasAlphaChannel(), mask() */ bool QPixmap::hasAlpha() const { @@ -1774,7 +1767,7 @@ bool QPixmap::hasAlpha() const Returns true if the pixmap has a format that respects the alpha channel, otherwise returns false. - \sa alphaChannel(), hasAlpha() + \sa hasAlpha() */ bool QPixmap::hasAlphaChannel() const { @@ -1791,6 +1784,7 @@ int QPixmap::metric(PaintDeviceMetric metric) const /*! \fn void QPixmap::setAlphaChannel(const QPixmap &alphaChannel) + \obsolete Sets the alpha channel of this pixmap to the given \a alphaChannel by converting the \a alphaChannel into 32 bit and using the @@ -1828,6 +1822,8 @@ void QPixmap::setAlphaChannel(const QPixmap &alphaChannel) } /*! + \obsolete + Returns the alpha channel of the pixmap as a new grayscale QPixmap in which each pixel's red, green, and blue values are given the alpha value of the original pixmap. The color depth of the returned pixmap is the system depth @@ -1846,7 +1842,9 @@ void QPixmap::setAlphaChannel(const QPixmap &alphaChannel) \image alphachannelimage.png The pixmap and channelImage QPixmaps \warning This is an expensive operation. The alpha channel of the - pixmap is extracted dynamically from the pixeldata. + pixmap is extracted dynamically from the pixeldata. Most usecases of this + function are covered by QPainter and compositionModes which will normally + execute faster. \sa setAlphaChannel(), {QPixmap#Pixmap Information}{Pixmap Information} @@ -1867,7 +1865,7 @@ QPaintEngine *QPixmap::paintEngine() const /*! \fn QBitmap QPixmap::mask() const - Extracts a bitmap mask from the pixmap's alphachannel. + Extracts a bitmap mask from the pixmap's alpha channel. \warning This is potentially an expensive operation. The mask of the pixmap is extracted dynamically from the pixeldata. -- cgit v0.12 From 0571d9617633a993f3a40e388ac426d78a376ce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 21 Jul 2009 10:02:27 +0200 Subject: LayeredPane should not be reported as an IP address edit control to MSAA The reason was that ROLE_SYSTEM_IPADDRESS = 0x3F has been added to MSAA at one point in time. (Can be found in recent versions of OleAcc.idl). Since the MSAA bridge used a direct mapping between QAccessible::Role and MSAA roles this lead to that LayeredPane was interpreted to be an IP address edit control, affecting QStackedWidget (and some relatives). This caused some screen readers to be confused when the same accessible interface had children such as push buttons. I also discussed this change with Harald. Task-number: 257958 --- src/gui/accessible/qaccessible.h | 1 + src/gui/accessible/qaccessible_win.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index 19080de..8dc8159 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -210,6 +210,7 @@ public: PageTabList = 0x0000003C, Clock = 0x0000003D, Splitter = 0x0000003E, + // Additional Qt roles where enum value does not map directly to MSAA: LayeredPane = 0x0000003F, UserRole = 0x0000ffff }; diff --git a/src/gui/accessible/qaccessible_win.cpp b/src/gui/accessible/qaccessible_win.cpp index bfacb94..85f1a8d 100644 --- a/src/gui/accessible/qaccessible_win.cpp +++ b/src/gui/accessible/qaccessible_win.cpp @@ -1051,6 +1051,8 @@ HRESULT STDMETHODCALLTYPE QWindowsAccessible::get_accRole(VARIANT varID, VARIANT Role role = accessible->role(varID.lVal); if (role != NoRole) { + if (role == LayeredPane) + role = QAccessible::Pane; (*pvarRole).vt = VT_I4; (*pvarRole).lVal = role; } else { -- cgit v0.12 From 1341fe5198bbf58c1a25a5680fbffec3b9b75eb6 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Mon, 20 Jul 2009 17:25:06 +0200 Subject: Fixes memory leak of global data. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: related to 253013 Reviewed-by: João Abecasis --- src/corelib/tools/qlocale.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 296d5a0..85e49c7 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -5299,7 +5299,11 @@ struct p5s_deleter { ~p5s_deleter() { - Bfree(p5s); + while (p5s) { + Bigint *next = p5s->next; + Bfree(p5s); + p5s = next; + } } }; -- cgit v0.12 From 1ccdf7cb7d5da92676d401105e9b03bfa747a926 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Jul 2009 11:30:49 +0200 Subject: Compile fix with namespaced Qt --- src/xmlpatterns/api/qxmlschema.cpp | 4 ++++ src/xmlpatterns/api/qxmlschema_p.cpp | 4 ++++ src/xmlpatterns/api/qxmlschemavalidator.cpp | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/xmlpatterns/api/qxmlschema.cpp b/src/xmlpatterns/api/qxmlschema.cpp index af4c715..e64b388 100644 --- a/src/xmlpatterns/api/qxmlschema.cpp +++ b/src/xmlpatterns/api/qxmlschema.cpp @@ -45,6 +45,8 @@ #include #include +QT_BEGIN_NAMESPACE + /*! \class QXmlSchema @@ -293,3 +295,5 @@ QNetworkAccessManager *QXmlSchema::networkAccessManager() const { return d->networkAccessManager(); } + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlschema_p.cpp b/src/xmlpatterns/api/qxmlschema_p.cpp index 0bcb565..2dad359 100644 --- a/src/xmlpatterns/api/qxmlschema_p.cpp +++ b/src/xmlpatterns/api/qxmlschema_p.cpp @@ -47,6 +47,8 @@ #include #include +QT_BEGIN_NAMESPACE + QXmlSchemaPrivate::QXmlSchemaPrivate(const QXmlNamePool &namePool) : m_namePool(namePool) , m_userMessageHandler(0) @@ -197,3 +199,5 @@ QNetworkAccessManager *QXmlSchemaPrivate::networkAccessManager() const return m_networkAccessManager.data()->value; } + +QT_END_NAMESPACE diff --git a/src/xmlpatterns/api/qxmlschemavalidator.cpp b/src/xmlpatterns/api/qxmlschemavalidator.cpp index 9234d83..a864d40 100644 --- a/src/xmlpatterns/api/qxmlschemavalidator.cpp +++ b/src/xmlpatterns/api/qxmlschemavalidator.cpp @@ -51,6 +51,8 @@ #include #include +QT_BEGIN_NAMESPACE + /*! \class QXmlSchemaValidator @@ -338,3 +340,5 @@ QNetworkAccessManager *QXmlSchemaValidator::networkAccessManager() const return d->m_networkAccessManager.data()->value; } + +QT_END_NAMESPACE -- cgit v0.12 From 42e469bc5edcc6dee2401a104bd30de6b4be54fe Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 15 Jul 2009 14:56:57 +0200 Subject: QNAM: Proper loading of meta data when having AlwaysCache mode Properly load the raw headers and properly handle the redirection when having a network cache in AlwaysCache mode (equals the offline mode in web browser). Task-number: 256240 Reviewed-by: Thiago Macieira --- src/network/access/qnetworkaccesscachebackend.cpp | 14 ++++++++++++++ src/network/access/qnetworkreplyimpl.cpp | 10 ++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/network/access/qnetworkaccesscachebackend.cpp b/src/network/access/qnetworkaccesscachebackend.cpp index f46a50a..8571ba3 100644 --- a/src/network/access/qnetworkaccesscachebackend.cpp +++ b/src/network/access/qnetworkaccesscachebackend.cpp @@ -86,6 +86,20 @@ bool QNetworkAccessCacheBackend::sendCacheContents() setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute)); setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true); + // set the raw headers + QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders(); + QNetworkCacheMetaData::RawHeaderList::ConstIterator it = rawHeaders.constBegin(), + end = rawHeaders.constEnd(); + for ( ; it != end; ++it) + setRawHeader(it->first, it->second); + + // handle a possible redirect + QVariant redirectionTarget = attributes.value(QNetworkRequest::RedirectionTargetAttribute); + if (redirectionTarget.isValid()) { + setAttribute(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); + redirectionRequested(redirectionTarget.toUrl()); + } + // signal we're open metaDataChanged(); diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 98944fd..4ec3a75 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -376,7 +376,17 @@ void QNetworkReplyImplPrivate::feed(const QByteArray &data) QNetworkCacheMetaData metaData; metaData.setUrl(url); metaData = backend->fetchCacheMetaData(metaData); + + // save the redirect request also in the cache + QVariant redirectionTarget = q->attribute(QNetworkRequest::RedirectionTargetAttribute); + if (redirectionTarget.isValid()) { + QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes(); + attributes.insert(QNetworkRequest::RedirectionTargetAttribute, redirectionTarget); + metaData.setAttributes(attributes); + } + cacheSaveDevice = networkCache->prepare(metaData); + if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) { if (cacheSaveDevice && !cacheSaveDevice->isOpen()) qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- " -- cgit v0.12 From d159db5214b6bd489d4a1e16d6b8077eb242e6da Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Jul 2009 12:30:58 +0200 Subject: Fix compiler warning about initialization order reviewed-by: Kim Motoyoshi Kalland --- src/svg/qsvgstyle.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index 4c8247b..b693429 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -81,12 +81,12 @@ void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &) } QSvgFillStyle::QSvgFillStyle(const QBrush &brush) - : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true) + : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillRule(Qt::WindingFill), m_fillOpacitySet(false), m_fillOpacity(1.0), m_gradientResolved (true) { } QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style) - : m_style(style), m_fillRuleSet(false), m_fillOpacitySet(false), m_fillRule(Qt::WindingFill), m_fillOpacity(1.0), m_gradientResolved (true) + : m_style(style), m_fillRuleSet(false), m_fillRule(Qt::WindingFill), m_fillOpacitySet(false), m_fillOpacity(1.0), m_gradientResolved (true) { } -- cgit v0.12 From 573235120825c6d95c73adf374fde6ed4f38cafa Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 21 Jul 2009 12:24:42 +0200 Subject: sunpro doesn't like templated friend classes, either --- tools/linguist/shared/profileevaluator.cpp | 2 +- tools/linguist/shared/profileevaluator.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 9a27eb0..5a9095a 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -256,7 +256,7 @@ public: ProFile *m_prevProFile; // See m_prevLineNo }; -#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3) +#if (!defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) && !defined(__SUNPRO_CC) Q_DECLARE_TYPEINFO(ProFileEvaluator::Private::State, Q_PRIMITIVE_TYPE); Q_DECLARE_TYPEINFO(ProFileEvaluator::Private::ProLoop, Q_MOVABLE_TYPE); #endif diff --git a/tools/linguist/shared/profileevaluator.h b/tools/linguist/shared/profileevaluator.h index 88b7590..f3498c1 100644 --- a/tools/linguist/shared/profileevaluator.h +++ b/tools/linguist/shared/profileevaluator.h @@ -96,7 +96,7 @@ private: class Private; Private *d; - // This doesn't help gcc 3.3 ... + // This doesn't help gcc 3.3 and sunpro ... template friend class QTypeInfo; }; -- cgit v0.12 From 2ee9e0ea326540ebb29ed5a60eb32ac686c45730 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 21 Jul 2009 11:09:23 +0200 Subject: Doc fixes to QEasingCurve. * Remove some references to QAnimation. QAnimation does not exist. * Clarify the documentation for QEasingCurve::Linear. (avoid "tweening" and "no easing") * In the diagrams, change "ease" to "value". * Change the diagram generation code to use antialiased drawing (just as we do in the easingcurve example) Reviewed-by: leo --- doc/src/diagrams/programs/easingcurve/main.cpp | 29 +++++++++++++++---------- doc/src/images/qeasingcurve-cosinecurve.png | Bin 2544 -> 3419 bytes doc/src/images/qeasingcurve-inback.png | Bin 2225 -> 2808 bytes doc/src/images/qeasingcurve-inbounce.png | Bin 2378 -> 3154 bytes doc/src/images/qeasingcurve-incirc.png | Bin 2138 -> 2605 bytes doc/src/images/qeasingcurve-incubic.png | Bin 2230 -> 2722 bytes doc/src/images/qeasingcurve-incurve.png | Bin 2325 -> 2692 bytes doc/src/images/qeasingcurve-inelastic.png | Bin 2314 -> 3304 bytes doc/src/images/qeasingcurve-inexpo.png | Bin 2183 -> 2675 bytes doc/src/images/qeasingcurve-inoutback.png | Bin 2460 -> 3241 bytes doc/src/images/qeasingcurve-inoutbounce.png | Bin 2522 -> 3386 bytes doc/src/images/qeasingcurve-inoutcirc.png | Bin 2352 -> 2843 bytes doc/src/images/qeasingcurve-inoutcubic.png | Bin 2410 -> 2931 bytes doc/src/images/qeasingcurve-inoutelastic.png | Bin 2485 -> 3461 bytes doc/src/images/qeasingcurve-inoutexpo.png | Bin 2383 -> 3004 bytes doc/src/images/qeasingcurve-inoutquad.png | Bin 2392 -> 2893 bytes doc/src/images/qeasingcurve-inoutquart.png | Bin 2331 -> 2925 bytes doc/src/images/qeasingcurve-inoutquint.png | Bin 2244 -> 2823 bytes doc/src/images/qeasingcurve-inoutsine.png | Bin 2405 -> 2891 bytes doc/src/images/qeasingcurve-inquad.png | Bin 2283 -> 2733 bytes doc/src/images/qeasingcurve-inquart.png | Bin 2261 -> 2727 bytes doc/src/images/qeasingcurve-inquint.png | Bin 2178 -> 2630 bytes doc/src/images/qeasingcurve-insine.png | Bin 2167 -> 2567 bytes doc/src/images/qeasingcurve-linear.png | Bin 2165 -> 2318 bytes doc/src/images/qeasingcurve-outback.png | Bin 2371 -> 2852 bytes doc/src/images/qeasingcurve-outbounce.png | Bin 2481 -> 3360 bytes doc/src/images/qeasingcurve-outcirc.png | Bin 2269 -> 2796 bytes doc/src/images/qeasingcurve-outcubic.png | Bin 2336 -> 2792 bytes doc/src/images/qeasingcurve-outcurve.png | Bin 2389 -> 2724 bytes doc/src/images/qeasingcurve-outelastic.png | Bin 2402 -> 3423 bytes doc/src/images/qeasingcurve-outexpo.png | Bin 2299 -> 2803 bytes doc/src/images/qeasingcurve-outinback.png | Bin 2400 -> 3026 bytes doc/src/images/qeasingcurve-outinbounce.png | Bin 2568 -> 3629 bytes doc/src/images/qeasingcurve-outincirc.png | Bin 2339 -> 2822 bytes doc/src/images/qeasingcurve-outincubic.png | Bin 2393 -> 2872 bytes doc/src/images/qeasingcurve-outinelastic.png | Bin 2517 -> 3941 bytes doc/src/images/qeasingcurve-outinexpo.png | Bin 2377 -> 2923 bytes doc/src/images/qeasingcurve-outinquad.png | Bin 2380 -> 2858 bytes doc/src/images/qeasingcurve-outinquart.png | Bin 2319 -> 2830 bytes doc/src/images/qeasingcurve-outinquint.png | Bin 2248 -> 2724 bytes doc/src/images/qeasingcurve-outinsine.png | Bin 2388 -> 2817 bytes doc/src/images/qeasingcurve-outquad.png | Bin 2324 -> 2760 bytes doc/src/images/qeasingcurve-outquart.png | Bin 2304 -> 2764 bytes doc/src/images/qeasingcurve-outquint.png | Bin 2242 -> 2687 bytes doc/src/images/qeasingcurve-outsine.png | Bin 2364 -> 2773 bytes doc/src/images/qeasingcurve-sinecurve.png | Bin 2470 -> 3329 bytes src/corelib/tools/qeasingcurve.cpp | 15 +++++++------ 47 files changed, 25 insertions(+), 19 deletions(-) diff --git a/doc/src/diagrams/programs/easingcurve/main.cpp b/doc/src/diagrams/programs/easingcurve/main.cpp index 8a2d53b..f249dbc 100644 --- a/doc/src/diagrams/programs/easingcurve/main.cpp +++ b/doc/src/diagrams/programs/easingcurve/main.cpp @@ -85,32 +85,37 @@ void createCurveIcons() qreal curveScale = iconSize.height()/2; - painter.drawLine(yAxis - 2, xAxis - curveScale, yAxis + 2, xAxis - curveScale); // hor + painter.drawLine(yAxis - 2, xAxis - curveScale, yAxis + 2, xAxis - curveScale); // hor painter.drawLine(yAxis + curveScale, xAxis + 2, yAxis + curveScale, xAxis - 2); // ver painter.drawText(yAxis + curveScale - 8, xAxis - curveScale - 4, QLatin1String("(1,1)")); - + painter.drawText(yAxis + 42, xAxis + 10, QLatin1String("progress")); - painter.drawText(15, xAxis - curveScale - 10, QLatin1String("ease")); - - painter.setPen(QPen(Qt::red, 1, Qt::DotLine)); + painter.drawText(15, xAxis - curveScale - 10, QLatin1String("value")); + + painter.setPen(QPen(Qt::red, 1, Qt::DotLine)); painter.drawLine(yAxis, xAxis - curveScale, yAxis + curveScale, xAxis - curveScale); // hor painter.drawLine(yAxis + curveScale, xAxis, yAxis + curveScale, xAxis - curveScale); // ver - - QPoint currentPos(yAxis, xAxis); - + + QPoint start(yAxis, xAxis - curveScale * curve.valueForProgress(0)); + painter.setPen(Qt::black); QFont font = oldFont; font.setPixelSize(oldFont.pixelSize() + 15); painter.setFont(font); painter.drawText(0, iconSize.height() - 20, iconSize.width(), 20, Qt::AlignHCenter, name); - - for (qreal t = 0; t < 1.0; t+=1.0/curveScale) { + + QPainterPath curvePath; + curvePath.moveTo(start); + for (qreal t = 0; t <= 1.0; t+=1.0/curveScale) { QPoint to; to.setX(yAxis + curveScale * t); to.setY(xAxis - curveScale * curve.valueForProgress(t)); - painter.drawLine(currentPos, to); - currentPos = to; + curvePath.lineTo(to); } + painter.setRenderHint(QPainter::Antialiasing, true); + painter.strokePath(curvePath, QColor(32, 32, 32)); + painter.setRenderHint(QPainter::Antialiasing, false); + QString fileName(QString::fromAscii("qeasingcurve-%1.png").arg(name.toLower())); printf("%s\n", qPrintable(fileName)); pix.save(QString::fromAscii("%1/%2").arg(output).arg(fileName), "PNG"); diff --git a/doc/src/images/qeasingcurve-cosinecurve.png b/doc/src/images/qeasingcurve-cosinecurve.png index b27e763..8cee978 100644 Binary files a/doc/src/images/qeasingcurve-cosinecurve.png and b/doc/src/images/qeasingcurve-cosinecurve.png differ diff --git a/doc/src/images/qeasingcurve-inback.png b/doc/src/images/qeasingcurve-inback.png index 8506c0f..0064cb3 100644 Binary files a/doc/src/images/qeasingcurve-inback.png and b/doc/src/images/qeasingcurve-inback.png differ diff --git a/doc/src/images/qeasingcurve-inbounce.png b/doc/src/images/qeasingcurve-inbounce.png index 275b38c..eaa64f8 100644 Binary files a/doc/src/images/qeasingcurve-inbounce.png and b/doc/src/images/qeasingcurve-inbounce.png differ diff --git a/doc/src/images/qeasingcurve-incirc.png b/doc/src/images/qeasingcurve-incirc.png index b985e9c..7bd0f09 100644 Binary files a/doc/src/images/qeasingcurve-incirc.png and b/doc/src/images/qeasingcurve-incirc.png differ diff --git a/doc/src/images/qeasingcurve-incubic.png b/doc/src/images/qeasingcurve-incubic.png index e417ee1..1ac9eaf 100644 Binary files a/doc/src/images/qeasingcurve-incubic.png and b/doc/src/images/qeasingcurve-incubic.png differ diff --git a/doc/src/images/qeasingcurve-incurve.png b/doc/src/images/qeasingcurve-incurve.png index d9a9340..578259e 100644 Binary files a/doc/src/images/qeasingcurve-incurve.png and b/doc/src/images/qeasingcurve-incurve.png differ diff --git a/doc/src/images/qeasingcurve-inelastic.png b/doc/src/images/qeasingcurve-inelastic.png index b242fd3..f976b5a 100644 Binary files a/doc/src/images/qeasingcurve-inelastic.png and b/doc/src/images/qeasingcurve-inelastic.png differ diff --git a/doc/src/images/qeasingcurve-inexpo.png b/doc/src/images/qeasingcurve-inexpo.png index f06316c..1af3652 100644 Binary files a/doc/src/images/qeasingcurve-inexpo.png and b/doc/src/images/qeasingcurve-inexpo.png differ diff --git a/doc/src/images/qeasingcurve-inoutback.png b/doc/src/images/qeasingcurve-inoutback.png index 9fd1446..480bc05 100644 Binary files a/doc/src/images/qeasingcurve-inoutback.png and b/doc/src/images/qeasingcurve-inoutback.png differ diff --git a/doc/src/images/qeasingcurve-inoutbounce.png b/doc/src/images/qeasingcurve-inoutbounce.png index fb65f31..de62309 100644 Binary files a/doc/src/images/qeasingcurve-inoutbounce.png and b/doc/src/images/qeasingcurve-inoutbounce.png differ diff --git a/doc/src/images/qeasingcurve-inoutcirc.png b/doc/src/images/qeasingcurve-inoutcirc.png index 123cc54..b4be8ac 100644 Binary files a/doc/src/images/qeasingcurve-inoutcirc.png and b/doc/src/images/qeasingcurve-inoutcirc.png differ diff --git a/doc/src/images/qeasingcurve-inoutcubic.png b/doc/src/images/qeasingcurve-inoutcubic.png index b07695c..49dfbef 100644 Binary files a/doc/src/images/qeasingcurve-inoutcubic.png and b/doc/src/images/qeasingcurve-inoutcubic.png differ diff --git a/doc/src/images/qeasingcurve-inoutelastic.png b/doc/src/images/qeasingcurve-inoutelastic.png index 65851e1..5b0e54a 100644 Binary files a/doc/src/images/qeasingcurve-inoutelastic.png and b/doc/src/images/qeasingcurve-inoutelastic.png differ diff --git a/doc/src/images/qeasingcurve-inoutexpo.png b/doc/src/images/qeasingcurve-inoutexpo.png index 7cbfb13..776984a 100644 Binary files a/doc/src/images/qeasingcurve-inoutexpo.png and b/doc/src/images/qeasingcurve-inoutexpo.png differ diff --git a/doc/src/images/qeasingcurve-inoutquad.png b/doc/src/images/qeasingcurve-inoutquad.png index c5eed06..2643330 100644 Binary files a/doc/src/images/qeasingcurve-inoutquad.png and b/doc/src/images/qeasingcurve-inoutquad.png differ diff --git a/doc/src/images/qeasingcurve-inoutquart.png b/doc/src/images/qeasingcurve-inoutquart.png index 3b66c0d..31fc0c8 100644 Binary files a/doc/src/images/qeasingcurve-inoutquart.png and b/doc/src/images/qeasingcurve-inoutquart.png differ diff --git a/doc/src/images/qeasingcurve-inoutquint.png b/doc/src/images/qeasingcurve-inoutquint.png index c74efe9..4d7a745 100644 Binary files a/doc/src/images/qeasingcurve-inoutquint.png and b/doc/src/images/qeasingcurve-inoutquint.png differ diff --git a/doc/src/images/qeasingcurve-inoutsine.png b/doc/src/images/qeasingcurve-inoutsine.png index 5964f31..012ff75 100644 Binary files a/doc/src/images/qeasingcurve-inoutsine.png and b/doc/src/images/qeasingcurve-inoutsine.png differ diff --git a/doc/src/images/qeasingcurve-inquad.png b/doc/src/images/qeasingcurve-inquad.png index 3373310..e697c20 100644 Binary files a/doc/src/images/qeasingcurve-inquad.png and b/doc/src/images/qeasingcurve-inquad.png differ diff --git a/doc/src/images/qeasingcurve-inquart.png b/doc/src/images/qeasingcurve-inquart.png index 28086d8..6d65175 100644 Binary files a/doc/src/images/qeasingcurve-inquart.png and b/doc/src/images/qeasingcurve-inquart.png differ diff --git a/doc/src/images/qeasingcurve-inquint.png b/doc/src/images/qeasingcurve-inquint.png index 330aa85..faaaea7 100644 Binary files a/doc/src/images/qeasingcurve-inquint.png and b/doc/src/images/qeasingcurve-inquint.png differ diff --git a/doc/src/images/qeasingcurve-insine.png b/doc/src/images/qeasingcurve-insine.png index 63d9238..0944903 100644 Binary files a/doc/src/images/qeasingcurve-insine.png and b/doc/src/images/qeasingcurve-insine.png differ diff --git a/doc/src/images/qeasingcurve-linear.png b/doc/src/images/qeasingcurve-linear.png index 2a05885..fb3aaf3 100644 Binary files a/doc/src/images/qeasingcurve-linear.png and b/doc/src/images/qeasingcurve-linear.png differ diff --git a/doc/src/images/qeasingcurve-outback.png b/doc/src/images/qeasingcurve-outback.png index 7cb34c6..83b3fa2 100644 Binary files a/doc/src/images/qeasingcurve-outback.png and b/doc/src/images/qeasingcurve-outback.png differ diff --git a/doc/src/images/qeasingcurve-outbounce.png b/doc/src/images/qeasingcurve-outbounce.png index 932fc16..27ac979 100644 Binary files a/doc/src/images/qeasingcurve-outbounce.png and b/doc/src/images/qeasingcurve-outbounce.png differ diff --git a/doc/src/images/qeasingcurve-outcirc.png b/doc/src/images/qeasingcurve-outcirc.png index a1a6cb6..0019370 100644 Binary files a/doc/src/images/qeasingcurve-outcirc.png and b/doc/src/images/qeasingcurve-outcirc.png differ diff --git a/doc/src/images/qeasingcurve-outcubic.png b/doc/src/images/qeasingcurve-outcubic.png index aa1d604..45477c0 100644 Binary files a/doc/src/images/qeasingcurve-outcubic.png and b/doc/src/images/qeasingcurve-outcubic.png differ diff --git a/doc/src/images/qeasingcurve-outcurve.png b/doc/src/images/qeasingcurve-outcurve.png index a949ae4..295b471 100644 Binary files a/doc/src/images/qeasingcurve-outcurve.png and b/doc/src/images/qeasingcurve-outcurve.png differ diff --git a/doc/src/images/qeasingcurve-outelastic.png b/doc/src/images/qeasingcurve-outelastic.png index 2a9ba39..1d407ed 100644 Binary files a/doc/src/images/qeasingcurve-outelastic.png and b/doc/src/images/qeasingcurve-outelastic.png differ diff --git a/doc/src/images/qeasingcurve-outexpo.png b/doc/src/images/qeasingcurve-outexpo.png index e771c2e..5685155 100644 Binary files a/doc/src/images/qeasingcurve-outexpo.png and b/doc/src/images/qeasingcurve-outexpo.png differ diff --git a/doc/src/images/qeasingcurve-outinback.png b/doc/src/images/qeasingcurve-outinback.png index 7523727..4700ab0 100644 Binary files a/doc/src/images/qeasingcurve-outinback.png and b/doc/src/images/qeasingcurve-outinback.png differ diff --git a/doc/src/images/qeasingcurve-outinbounce.png b/doc/src/images/qeasingcurve-outinbounce.png index ab73d02..12cc1a8 100644 Binary files a/doc/src/images/qeasingcurve-outinbounce.png and b/doc/src/images/qeasingcurve-outinbounce.png differ diff --git a/doc/src/images/qeasingcurve-outincirc.png b/doc/src/images/qeasingcurve-outincirc.png index ec4b8d3..c8a5c86 100644 Binary files a/doc/src/images/qeasingcurve-outincirc.png and b/doc/src/images/qeasingcurve-outincirc.png differ diff --git a/doc/src/images/qeasingcurve-outincubic.png b/doc/src/images/qeasingcurve-outincubic.png index 8b8ae68..42af870 100644 Binary files a/doc/src/images/qeasingcurve-outincubic.png and b/doc/src/images/qeasingcurve-outincubic.png differ diff --git a/doc/src/images/qeasingcurve-outinelastic.png b/doc/src/images/qeasingcurve-outinelastic.png index 89dde2c..308be57 100644 Binary files a/doc/src/images/qeasingcurve-outinelastic.png and b/doc/src/images/qeasingcurve-outinelastic.png differ diff --git a/doc/src/images/qeasingcurve-outinexpo.png b/doc/src/images/qeasingcurve-outinexpo.png index 5909901..0692baa 100644 Binary files a/doc/src/images/qeasingcurve-outinexpo.png and b/doc/src/images/qeasingcurve-outinexpo.png differ diff --git a/doc/src/images/qeasingcurve-outinquad.png b/doc/src/images/qeasingcurve-outinquad.png index 7ddefee..9e3cd83 100644 Binary files a/doc/src/images/qeasingcurve-outinquad.png and b/doc/src/images/qeasingcurve-outinquad.png differ diff --git a/doc/src/images/qeasingcurve-outinquart.png b/doc/src/images/qeasingcurve-outinquart.png index 00ef597..9a3c16f 100644 Binary files a/doc/src/images/qeasingcurve-outinquart.png and b/doc/src/images/qeasingcurve-outinquart.png differ diff --git a/doc/src/images/qeasingcurve-outinquint.png b/doc/src/images/qeasingcurve-outinquint.png index 361bfaa4..add9feb 100644 Binary files a/doc/src/images/qeasingcurve-outinquint.png and b/doc/src/images/qeasingcurve-outinquint.png differ diff --git a/doc/src/images/qeasingcurve-outinsine.png b/doc/src/images/qeasingcurve-outinsine.png index 1737041..4bc2aaf 100644 Binary files a/doc/src/images/qeasingcurve-outinsine.png and b/doc/src/images/qeasingcurve-outinsine.png differ diff --git a/doc/src/images/qeasingcurve-outquad.png b/doc/src/images/qeasingcurve-outquad.png index 6f27cbd..c505ff9 100644 Binary files a/doc/src/images/qeasingcurve-outquad.png and b/doc/src/images/qeasingcurve-outquad.png differ diff --git a/doc/src/images/qeasingcurve-outquart.png b/doc/src/images/qeasingcurve-outquart.png index d45a0b8..6eac058 100644 Binary files a/doc/src/images/qeasingcurve-outquart.png and b/doc/src/images/qeasingcurve-outquart.png differ diff --git a/doc/src/images/qeasingcurve-outquint.png b/doc/src/images/qeasingcurve-outquint.png index 6e7df0e..77a9ad4 100644 Binary files a/doc/src/images/qeasingcurve-outquint.png and b/doc/src/images/qeasingcurve-outquint.png differ diff --git a/doc/src/images/qeasingcurve-outsine.png b/doc/src/images/qeasingcurve-outsine.png index 7546a0d..d135b2f 100644 Binary files a/doc/src/images/qeasingcurve-outsine.png and b/doc/src/images/qeasingcurve-outsine.png differ diff --git a/doc/src/images/qeasingcurve-sinecurve.png b/doc/src/images/qeasingcurve-sinecurve.png index ca67d44..6134a01 100644 Binary files a/doc/src/images/qeasingcurve-sinecurve.png and b/doc/src/images/qeasingcurve-sinecurve.png differ diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 18a252a..34ad599 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -60,8 +60,8 @@ Easing curves describe a function that controls how the speed of the interpolation between 0 and 1 should be. Easing curves allow transitions from one value to another to appear more natural than a simple constant speed would allow. - The QEasingCurve class is usually used in conjunction with the QAnimation class, - but can be used on its own. + The QEasingCurve class is usually used in conjunction with the QVariantAnimation and + QPropertyAnimation classes but can be used on its own. To calculate the speed of the interpolation, the easing curve provides the function valueForProgress(), where the \a progress argument specifies the progress of the @@ -80,10 +80,10 @@ \endcode will print the effective progress of the interpolation between 0 and 1. - When using a QAnimation, the easing curve will be used to control the + When using a QPropertyAnimation, the associated easing curve will be used to control the progress of the interpolation between startValue and endValue: \code - QAnimation animation; + QPropertyAnimation animation; animation.setStartValue(0); animation.setEndValue(1000); animation.setDuration(1000); @@ -98,8 +98,7 @@ \value Linear \inlineimage qeasingcurve-linear.png \br - Easing equation function for a simple linear tweening, - with no easing. + Easing equation function for a linear (t) easing curve. \value InQuad \inlineimage qeasingcurve-inquad.png \br Easing equation function for a quadratic (t^2) easing @@ -280,7 +279,9 @@ \omitvalue OutCurve \omitvalue SineCurve \omitvalue CosineCurve - \value Custom This is returned if the user have specified a custom curve type with setCustomType(). Note that you cannot call setType() with this value, but type() can return it. + \value Custom This is returned if the user specified a custom curve type with + setCustomType(). Note that you cannot call setType() with this value, + but type() can return it. \omitvalue NCurveTypes */ -- cgit v0.12 From 99ddd27d400c92949d730ebf4f31eb2fea857650 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan-Arve=20S=C3=A6ther?= Date: Tue, 21 Jul 2009 12:43:58 +0200 Subject: Try to express ourselves better in the explanation for the curve types. Don't use easing too much. Also add an explanation of what "ease in" and "ease out" is. --- src/corelib/tools/qeasingcurve.cpp | 165 +++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 81 deletions(-) diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 34ad599..0828c61 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -61,7 +61,9 @@ between 0 and 1 should be. Easing curves allow transitions from one value to another to appear more natural than a simple constant speed would allow. The QEasingCurve class is usually used in conjunction with the QVariantAnimation and - QPropertyAnimation classes but can be used on its own. + QPropertyAnimation classes but can be used on its own. It is usually used to accelerate + the interpolation from zero velocity (ease in) or decelerate to zero velocity (ease out). + Ease in and ease out can also be combined in the same easing curve. To calculate the speed of the interpolation, the easing curve provides the function valueForProgress(), where the \a progress argument specifies the progress of the @@ -98,182 +100,183 @@ \value Linear \inlineimage qeasingcurve-linear.png \br - Easing equation function for a linear (t) easing curve. + Easing curve for a linear (t) function: + velocity is constant. \value InQuad \inlineimage qeasingcurve-inquad.png \br - Easing equation function for a quadratic (t^2) easing - in: accelerating from zero velocity. + Easing curve for a quadratic (t^2) function: + accelerating from zero velocity. \value OutQuad \inlineimage qeasingcurve-outquad.png \br - Easing equation function for a quadratic (t^2) easing - out: decelerating to zero velocity. + Easing curve for a quadratic (t^2) function: + decelerating to zero velocity. \value InOutQuad \inlineimage qeasingcurve-inoutquad.png \br - Easing equation function for a quadratic (t^2) easing - in/out: acceleration until halfway, then deceleration. + Easing curve for a quadratic (t^2) function: + acceleration until halfway, then deceleration. \value OutInQuad \inlineimage qeasingcurve-outinquad.png \br - Easing equation function for a quadratic (t^2) easing - out/in: deceleration until halfway, then acceleration. + Easing curve for a quadratic (t^2) function: + deceleration until halfway, then acceleration. \value InCubic \inlineimage qeasingcurve-incubic.png \br - Easing equation function for a cubic (t^3) easing - in: accelerating from zero velocity. + Easing curve for a cubic (t^3) function: + accelerating from zero velocity. \value OutCubic \inlineimage qeasingcurve-outcubic.png \br - Easing equation function for a cubic (t^3) easing - out: decelerating from zero velocity. + Easing curve for a cubic (t^3) function: + decelerating from zero velocity. \value InOutCubic \inlineimage qeasingcurve-inoutcubic.png \br - Easing equation function for a cubic (t^3) easing - in/out: acceleration until halfway, then deceleration. + Easing curve for a cubic (t^3) function: + acceleration until halfway, then deceleration. \value OutInCubic \inlineimage qeasingcurve-outincubic.png \br - Easing equation function for a cubic (t^3) easing - out/in: deceleration until halfway, then acceleration. + Easing curve for a cubic (t^3) function: + deceleration until halfway, then acceleration. \value InQuart \inlineimage qeasingcurve-inquart.png \br - Easing equation function for a quartic (t^4) easing - in: accelerating from zero velocity. + Easing curve for a quartic (t^4) function: + accelerating from zero velocity. \value OutQuart \inlineimage qeasingcurve-outquart.png \br - Easing equation function for a quartic (t^4) easing - out: decelerating from zero velocity. + Easing curve for a cubic (t^4) function: + decelerating from zero velocity. \value InOutQuart \inlineimage qeasingcurve-inoutquart.png \br - Easing equation function for a quartic (t^4) easing - in/out: acceleration until halfway, then deceleration. + Easing curve for a cubic (t^4) function: + acceleration until halfway, then deceleration. \value OutInQuart \inlineimage qeasingcurve-outinquart.png \br - Easing equation function for a quartic (t^4) easing - out/in: deceleration until halfway, then acceleration. + Easing curve for a cubic (t^4) function: + deceleration until halfway, then acceleration. \value InQuint \inlineimage qeasingcurve-inquint.png \br - Easing equation function for a quintic (t^5) easing + Easing curve for a quintic (t^5) easing in: accelerating from zero velocity. \value OutQuint \inlineimage qeasingcurve-outquint.png \br - Easing equation function for a quintic (t^5) easing - out: decelerating from zero velocity. + Easing curve for a cubic (t^5) function: + decelerating from zero velocity. \value InOutQuint \inlineimage qeasingcurve-inoutquint.png \br - Easing equation function for a quintic (t^5) easing - in/out: acceleration until halfway, then deceleration. + Easing curve for a cubic (t^5) function: + acceleration until halfway, then deceleration. \value OutInQuint \inlineimage qeasingcurve-outinquint.png \br - Easing equation function for a quintic (t^5) easing - out/in: deceleration until halfway, then acceleration. + Easing curve for a cubic (t^5) function: + deceleration until halfway, then acceleration. \value InSine \inlineimage qeasingcurve-insine.png \br - Easing equation function for a sinusoidal (sin(t)) easing - in: accelerating from zero velocity. + Easing curve for a sinusoidal (sin(t)) function: + accelerating from zero velocity. \value OutSine \inlineimage qeasingcurve-outsine.png \br - Easing equation function for a sinusoidal (sin(t)) easing - out: decelerating from zero velocity. + Easing curve for a sinusoidal (sin(t)) function: + decelerating from zero velocity. \value InOutSine \inlineimage qeasingcurve-inoutsine.png \br - Easing equation function for a sinusoidal (sin(t)) easing - in/out: acceleration until halfway, then deceleration. + Easing curve for a sinusoidal (sin(t)) function: + acceleration until halfway, then deceleration. \value OutInSine \inlineimage qeasingcurve-outinsine.png \br - Easing equation function for a sinusoidal (sin(t)) easing - out/in: deceleration until halfway, then acceleration. + Easing curve for a sinusoidal (sin(t)) function: + deceleration until halfway, then acceleration. \value InExpo \inlineimage qeasingcurve-inexpo.png \br - Easing equation function for an exponential (2^t) easing - in: accelerating from zero velocity. + Easing curve for an exponential (2^t) function: + accelerating from zero velocity. \value OutExpo \inlineimage qeasingcurve-outexpo.png \br - Easing equation function for an exponential (2^t) easing - out: decelerating from zero velocity. + Easing curve for an exponential (2^t) function: + decelerating from zero velocity. \value InOutExpo \inlineimage qeasingcurve-inoutexpo.png \br - Easing equation function for an exponential (2^t) easing - in/out: acceleration until halfway, then deceleration. + Easing curve for an exponential (2^t) function: + acceleration until halfway, then deceleration. \value OutInExpo \inlineimage qeasingcurve-outinexpo.png \br - Easing equation function for an exponential (2^t) easing - out/in: deceleration until halfway, then acceleration. + Easing curve for an exponential (2^t) function: + deceleration until halfway, then acceleration. \value InCirc \inlineimage qeasingcurve-incirc.png \br - Easing equation function for a circular (sqrt(1-t^2)) easing - in: accelerating from zero velocity. + Easing curve for a circular (sqrt(1-t^2)) function: + accelerating from zero velocity. \value OutCirc \inlineimage qeasingcurve-outcirc.png \br - Easing equation function for a circular (sqrt(1-t^2)) easing - out: decelerating from zero velocity. + Easing curve for a circular (sqrt(1-t^2)) function: + decelerating from zero velocity. \value InOutCirc \inlineimage qeasingcurve-inoutcirc.png \br - Easing equation function for a circular (sqrt(1-t^2)) easing - in/out: acceleration until halfway, then deceleration. + Easing curve for a circular (sqrt(1-t^2)) function: + acceleration until halfway, then deceleration. \value OutInCirc \inlineimage qeasingcurve-outincirc.png \br - Easing equation function for a circular (sqrt(1-t^2)) easing - out/in: deceleration until halfway, then acceleration. + Easing curve for a circular (sqrt(1-t^2)) function: + deceleration until halfway, then acceleration. \value InElastic \inlineimage qeasingcurve-inelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing in: + Easing curve for an elastic + (exponentially decaying sine wave) function: accelerating from zero velocity. The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \value OutElastic \inlineimage qeasingcurve-outelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing out: + Easing curve for an elastic + (exponentially decaying sine wave) function: decelerating from zero velocity. The peak amplitude can be set with the \e amplitude parameter, and the period of decay by the \e period parameter. \value InOutElastic \inlineimage qeasingcurve-inoutelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing in/out: + Easing curve for an elastic + (exponentially decaying sine wave) function: acceleration until halfway, then deceleration. \value OutInElastic \inlineimage qeasingcurve-outinelastic.png \br - Easing equation function for an elastic - (exponentially decaying sine wave) easing out/in: + Easing curve for an elastic + (exponentially decaying sine wave) function: deceleration until halfway, then acceleration. \value InBack \inlineimage qeasingcurve-inback.png \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing in: + Easing curve for a back (overshooting + cubic function: (s+1)*t^3 - s*t^2) easing in: accelerating from zero velocity. \value OutBack \inlineimage qeasingcurve-outback.png \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing out: - decelerating from zero velocity. + Easing curve for a back (overshooting + cubic function: (s+1)*t^3 - s*t^2) easing out: + decelerating to zero velocity. \value InOutBack \inlineimage qeasingcurve-inoutback.png \br - Easing equation function for a back (overshooting - cubic easing: (s+1)*t^3 - s*t^2) easing in/out: + Easing curve for a back (overshooting + cubic function: (s+1)*t^3 - s*t^2) easing in/out: acceleration until halfway, then deceleration. \value OutInBack \inlineimage qeasingcurve-outinback.png \br - Easing equation function for a back (overshooting + Easing curve for a back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out/in: deceleration until halfway, then acceleration. \value InBounce \inlineimage qeasingcurve-inbounce.png \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing in: accelerating + Easing curve for a bounce (exponentially + decaying parabolic bounce) function: accelerating from zero velocity. \value OutBounce \inlineimage qeasingcurve-outbounce.png \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing out: decelerating + Easing curve for a bounce (exponentially + decaying parabolic bounce) function: decelerating from zero velocity. \value InOutBounce \inlineimage qeasingcurve-inoutbounce.png \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing in/out: + Easing curve for a bounce (exponentially + decaying parabolic bounce) function easing in/out: acceleration until halfway, then deceleration. \value OutInBounce \inlineimage qeasingcurve-outinbounce.png \br - Easing equation function for a bounce (exponentially - decaying parabolic bounce) easing out/in: + Easing curve for a bounce (exponentially + decaying parabolic bounce) function easing out/in: deceleration until halfway, then acceleration. \omitvalue InCurve \omitvalue OutCurve -- cgit v0.12 From c5eff466432988b338d9d0f340e9d31955109eea Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 21 Jul 2009 12:51:14 +0200 Subject: Compile with QT_NO_PROCESS or QT_NO_SETTINGS Feature define logic was wrong Reviewed-by: Robert Griebl --- src/testlib/qtestcase.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 70c8c8d..5de37dc 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -937,7 +937,7 @@ static void qParseArgs(int argc, char *argv[]) " -iterations n : Sets the number of accumulation iterations.\n" " -median n : Sets the number of median iterations.\n" " -vb : Print out verbose benchmarking information.\n" -#if !defined(QT_NO_PROCESS) || !defined(QT_NO_SETTINGS) +#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS) " -chart : Create chart based on the benchmark result.\n" #endif "\n" @@ -1053,7 +1053,7 @@ static void qParseArgs(int argc, char *argv[]) } else if (strcmp(argv[i], "-vb") == 0) { QBenchmarkGlobalData::current->verboseOutput = true; -#if !defined(QT_NO_PROCESS) || !defined(QT_NO_SETTINGS) +#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS) } else if (strcmp(argv[i], "-chart") == 0) { QBenchmarkGlobalData::current->createChart = true; QTestLog::setLogMode(QTestLog::XML); @@ -1627,7 +1627,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) #endif -#if !defined(QT_NO_PROCESS) || !defined(QT_NO_SETTINGS) +#if !defined(QT_NO_PROCESS) && !defined(QT_NO_SETTINGS) if (QBenchmarkGlobalData::current->createChart) { QString chartLocation = QLibraryInfo::location(QLibraryInfo::BinariesPath); #ifdef Q_OS_WIN -- cgit v0.12 From ffd978a76d91aaef92a36c465325256633f2fa97 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Tue, 21 Jul 2009 12:27:42 +0200 Subject: Remove unused gesture related defines and structures We don't use all of them. I also changed the typedefs for the touch related functions to follow the same naming convention. --- src/gui/kernel/qapplication_p.h | 141 ++++++++++++------------------------ src/gui/kernel/qapplication_win.cpp | 16 ++-- 2 files changed, 56 insertions(+), 101 deletions(-) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 3692160..595f220 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -192,99 +192,54 @@ extern "C" { #endif #if defined(Q_WS_WIN) -typedef BOOL (WINAPI *qt_RegisterTouchWindowPtr)(HWND, ULONG); -typedef BOOL (WINAPI *qt_GetTouchInputInfoPtr)(HANDLE, UINT, PVOID, int); -typedef BOOL (WINAPI *qt_CloseTouchInputHandlePtr)(HANDLE); - -typedef BOOL (WINAPI *PtrGetGestureInfo)(HANDLE hGestureInfo, PVOID pGestureInfo); -typedef BOOL (WINAPI *PtrGetGestureExtraArgs)(HANDLE hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); -typedef BOOL (WINAPI *PtrCloseGestureInfoHandle)(HANDLE hGestureInfo); -typedef BOOL (WINAPI *PtrSetGestureConfig)(HWND hwnd, DWORD dwReserved, UINT cIDs, - PVOID pGestureConfig, - UINT cbSize); -typedef BOOL (WINAPI *PtrGetGestureConfig)(HWND hwnd, DWORD dwReserved, - DWORD dwFlags, PUINT pcIDs, - PVOID pGestureConfig, - UINT cbSize); - -typedef BOOL (WINAPI *PtrBeginPanningFeedback)(HWND hwnd); -typedef BOOL (WINAPI *PtrUpdatePanningFeedback)(HWND hwnd, LONG, LONG, BOOL); -typedef BOOL (WINAPI *PtrEndPanningFeedback)(HWND hwnd, BOOL); +typedef BOOL (WINAPI *PtrRegisterTouchWindow)(HWND, ULONG); +typedef BOOL (WINAPI *PtrGetTouchInputInfo)(HANDLE, UINT, PVOID, int); +typedef BOOL (WINAPI *PtrCloseTouchInputHandle)(HANDLE); + +typedef BOOL (WINAPI *PtrGetGestureInfo)(HANDLE, PVOID); +typedef BOOL (WINAPI *PtrGetGestureExtraArgs)(HANDLE, UINT, PBYTE); +typedef BOOL (WINAPI *PtrCloseGestureInfoHandle)(HANDLE); +typedef BOOL (WINAPI *PtrSetGestureConfig)(HWND, DWORD, UINT, PVOID, UINT); +typedef BOOL (WINAPI *PtrGetGestureConfig)(HWND, DWORD, DWORD, PUINT, PVOID, UINT); + +typedef BOOL (WINAPI *PtrBeginPanningFeedback)(HWND); +typedef BOOL (WINAPI *PtrUpdatePanningFeedback)(HWND, LONG, LONG, BOOL); +typedef BOOL (WINAPI *PtrEndPanningFeedback)(HWND, BOOL); #ifndef WM_GESTURE +# define WM_GESTURE 0x0119 + +# define GID_BEGIN 1 +# define GID_END 2 +# define GID_ZOOM 3 +# define GID_PAN 4 +# define GID_ROTATE 5 +# define GID_TWOFINGERTAP 6 +# define GID_ROLLOVER 7 -#define WM_GESTURE 0x0119 -#define WM_GESTURE_NOTIFY 0x011A - -DECLARE_HANDLE(HGESTUREINFO); - -#define GF_BEGIN 0x00000001 -#define GF_INERTIA 0x00000002 -#define GF_END 0x00000004 - -/* - * Gesture IDs - */ -#define GID_BEGIN 1 -#define GID_END 2 -#define GID_ZOOM 3 -#define GID_PAN 4 -#define GID_ROTATE 5 -#define GID_TWOFINGERTAP 6 -#define GID_ROLLOVER 7 - -typedef struct tagGESTUREINFO { - UINT cbSize; // size, in bytes, of this structure (including variable length Args field) - DWORD dwFlags; // see GF_* flags - DWORD dwID; // gesture ID, see GID_* defines - HWND hwndTarget; // handle to window targeted by this gesture - POINTS ptsLocation; // current location of this gesture - DWORD dwInstanceID; // internally used - DWORD dwSequenceID; // internally used - ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES - UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture -} GESTUREINFO, *PGESTUREINFO; -typedef GESTUREINFO const * PCGESTUREINFO; - -typedef struct tagGESTURENOTIFYSTRUCT { - UINT cbSize; // size, in bytes, of this structure - DWORD dwFlags; // unused - HWND hwndTarget; // handle to window targeted by the gesture - POINTS ptsLocation; // starting location - DWORD dwInstanceID; // internally used -} GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; - -/* - * Gesture argument helpers - * - Angle should be a double in the range of -2pi to +2pi - * - Argument should be an unsigned 16-bit value - */ -#define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)) -#define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265) - -typedef struct tagGESTURECONFIG { - DWORD dwID; // gesture ID - DWORD dwWant; // settings related to gesture ID that are to be turned on - DWORD dwBlock; // settings related to gesture ID that are to be turned off -} GESTURECONFIG, *PGESTURECONFIG; - -#define GC_ALLGESTURES 0x00000001 -#define GC_ZOOM 0x00000001 -#define GC_PAN 0x00000001 -#define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 -#define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 -#define GC_PAN_WITH_GUTTER 0x00000008 -#define GC_PAN_WITH_INERTIA 0x00000010 -#define GC_ROTATE 0x00000001 -#define GC_TWOFINGERTAP 0x00000001 -#define GC_ROLLOVER 0x00000001 -#define GESTURECONFIGMAXCOUNT 256 // Maximum number of gestures that can be included - // in a single call to SetGestureConfig / GetGestureConfig - - - -#define GCF_INCLUDE_ANCESTORS 0x00000001 // If specified, GetGestureConfig returns consolidated configuration - // for the specified window and it's parent window chain +typedef struct tagGESTUREINFO +{ + UINT cbSize; + DWORD dwFlags; + DWORD dwID; + HWND hwndTarget; + POINTS ptsLocation; + DWORD dwInstanceID; + DWORD dwSequenceID; + ULONGLONG ullArguments; + UINT cbExtraArgs; +} GESTUREINFO; + +# define GC_PAN 0x00000001 +# define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 +# define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 + +typedef struct tagGESTURECONFIG +{ + DWORD dwID; + DWORD dwWant; + DWORD dwBlock; +} GESTURECONFIG; #endif // WM_GESTURE @@ -559,9 +514,9 @@ public: const QList &touchPoints); #if defined(Q_WS_WIN) - static qt_RegisterTouchWindowPtr RegisterTouchWindow; - static qt_GetTouchInputInfoPtr GetTouchInputInfo; - static qt_CloseTouchInputHandlePtr CloseTouchInputHandle; + static PtrRegisterTouchWindow RegisterTouchWindow; + static PtrGetTouchInputInfo GetTouchInputInfo; + static PtrCloseTouchInputHandle CloseTouchInputHandle; QHash touchInputIDToTouchPointID; QList appAllTouchPoints; diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index cbcac9a..d5c820c 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -3727,7 +3727,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) gi.dwSequenceID = 0; QApplicationPrivate *qAppPriv = getQApplicationPrivateInternal(); - BOOL bResult = qAppPriv->GetGestureInfo((HGESTUREINFO)msg.lParam, &gi); + BOOL bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos); @@ -3765,7 +3765,7 @@ bool QETWidget::translateGestureEvent(const MSG &msg) if (dwErr > 0) qWarning() << "translateGestureEvent: error = " << dwErr; } - qAppPriv->CloseGestureInfoHandle((HGESTUREINFO)msg.lParam); + qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam); return true; } @@ -3951,17 +3951,17 @@ void QSessionManager::cancel() #endif //QT_NO_SESSIONMANAGER -qt_RegisterTouchWindowPtr QApplicationPrivate::RegisterTouchWindow = 0; -qt_GetTouchInputInfoPtr QApplicationPrivate::GetTouchInputInfo = 0; -qt_CloseTouchInputHandlePtr QApplicationPrivate::CloseTouchInputHandle = 0; +PtrRegisterTouchWindow QApplicationPrivate::RegisterTouchWindow = 0; +PtrGetTouchInputInfo QApplicationPrivate::GetTouchInputInfo = 0; +PtrCloseTouchInputHandle QApplicationPrivate::CloseTouchInputHandle = 0; void QApplicationPrivate::initializeMultitouch_sys() { QLibrary library(QLatin1String("user32")); // MinGW (g++ 3.4.5) accepts only C casts. - RegisterTouchWindow = (qt_RegisterTouchWindowPtr)(library.resolve("RegisterTouchWindow")); - GetTouchInputInfo = (qt_GetTouchInputInfoPtr)(library.resolve("GetTouchInputInfo")); - CloseTouchInputHandle = (qt_CloseTouchInputHandlePtr)(library.resolve("CloseTouchInputHandle")); + RegisterTouchWindow = (PtrRegisterTouchWindow)(library.resolve("RegisterTouchWindow")); + GetTouchInputInfo = (PtrGetTouchInputInfo)(library.resolve("GetTouchInputInfo")); + CloseTouchInputHandle = (PtrCloseTouchInputHandle)(library.resolve("CloseTouchInputHandle")); touchInputIDToTouchPointID.clear(); } -- cgit v0.12 From 4b4e4ecf808b036e906c3bf22ce97b56808bb20e Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 21 Jul 2009 12:58:07 +0200 Subject: Remove Stickman editor The editor was a just a detail to make the animations and shouldn't be included in the example. --- .../animation/stickman/editor/animationdialog.cpp | 192 --------------------- .../animation/stickman/editor/animationdialog.h | 84 --------- examples/animation/stickman/editor/editor.pri | 2 - examples/animation/stickman/editor/mainwindow.cpp | 76 -------- examples/animation/stickman/editor/mainwindow.h | 58 ------- examples/animation/stickman/graphicsview.cpp | 23 --- examples/animation/stickman/stickman.pro | 2 - 7 files changed, 437 deletions(-) delete mode 100644 examples/animation/stickman/editor/animationdialog.cpp delete mode 100644 examples/animation/stickman/editor/animationdialog.h delete mode 100644 examples/animation/stickman/editor/editor.pri delete mode 100644 examples/animation/stickman/editor/mainwindow.cpp delete mode 100644 examples/animation/stickman/editor/mainwindow.h diff --git a/examples/animation/stickman/editor/animationdialog.cpp b/examples/animation/stickman/editor/animationdialog.cpp deleted file mode 100644 index 853046d..0000000 --- a/examples/animation/stickman/editor/animationdialog.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "animationdialog.h" -#include "stickman.h" -#include "animation.h" -#include "node.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -AnimationDialog::AnimationDialog(StickMan *stickman, QWidget *parent) - : QDialog(parent), m_animation(0), m_stickman(stickman) -{ - initUi(); -} - -AnimationDialog::~AnimationDialog() -{ - delete m_animation; -} - -void AnimationDialog::initUi() -{ - setWindowTitle("Animation"); - setEnabled(false); - - // Second page - m_currentFrame = new QSpinBox(); - m_totalFrames = new QSpinBox(); - m_name = new QLineEdit(); - - connect(m_currentFrame, SIGNAL(valueChanged(int)), this, SLOT(currentFrameChanged(int))); - connect(m_totalFrames, SIGNAL(valueChanged(int)), this, SLOT(totalFramesChanged(int))); - connect(m_name, SIGNAL(textChanged(QString)), this, SLOT(setCurrentAnimationName(QString))); - - QGridLayout *gridLayout = new QGridLayout(this); - gridLayout->addWidget(new QLabel("Name:"), 0, 0, 1, 2); - gridLayout->addWidget(m_name, 0, 2, 1, 2); - gridLayout->addWidget(new QLabel("Frame:"), 1, 0); - gridLayout->addWidget(m_currentFrame, 1, 1); - gridLayout->addWidget(new QLabel("of total # of frames: "), 1, 2); - gridLayout->addWidget(m_totalFrames, 1, 3); -} - -void AnimationDialog::initFromAnimation() -{ - m_currentFrame->setRange(0, m_animation->totalFrames()-1); - m_currentFrame->setValue(m_animation->currentFrame()); - - m_totalFrames->setRange(1, 1000); - m_totalFrames->setValue(m_animation->totalFrames()); - - m_name->setText(m_animation->name()); -} - -void AnimationDialog::saveAnimation() -{ - saveCurrentFrame(); - - QString fileName = QFileDialog::getSaveFileName(this, "Save animation"); - - QFile file(fileName); - if (file.open(QIODevice::WriteOnly)) - m_animation->save(&file); -} - -void AnimationDialog::loadAnimation() -{ - if (maybeSave() != QMessageBox::Cancel) { - QString fileName = QFileDialog::getOpenFileName(this, "Open animation"); - - QFile file(fileName); - if (file.open(QIODevice::ReadOnly)) { - if (m_animation == 0) - newAnimation(); - - m_animation->load(&file); - stickManFromCurrentFrame(); - initFromAnimation(); - } - } -} - -QMessageBox::StandardButton AnimationDialog::maybeSave() -{ - if (m_animation == 0) - return QMessageBox::No; - - QMessageBox::StandardButton button = QMessageBox::question(this, "Save?", "Do you want to save your changes?", - QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel); - if (button == QMessageBox::Save) - saveAnimation(); - - return button; -} - -void AnimationDialog::newAnimation() -{ - if (maybeSave() != QMessageBox::Cancel) { - setEnabled(true); - delete m_animation; - m_animation = new Animation(); - initFromAnimation(); - } -} - -// Gets the data from the stickman and stores it in current frame -void AnimationDialog::saveCurrentFrame() -{ - int count = m_stickman->nodeCount(); - m_animation->setNodeCount(count); - for (int i=0; inode(i); - m_animation->setNodePos(i, node->pos()); - } -} - -// Gets the data from the current frame and sets the stickman -void AnimationDialog::stickManFromCurrentFrame() -{ - int count = m_animation->nodeCount(); - for (int i=0;inode(i); - node->setPos(m_animation->nodePos(i)); - } -} - -void AnimationDialog::currentFrameChanged(int currentFrame) -{ - saveCurrentFrame(); - qDebug("currentFrame: %d", currentFrame); - m_animation->setCurrentFrame(currentFrame); - stickManFromCurrentFrame(); - initFromAnimation(); -} - -void AnimationDialog::totalFramesChanged(int totalFrames) -{ - m_animation->setTotalFrames(totalFrames); - stickManFromCurrentFrame(); - initFromAnimation(); -} - -void AnimationDialog::setCurrentAnimationName(const QString &name) -{ - m_animation->setName(name); -} diff --git a/examples/animation/stickman/editor/animationdialog.h b/examples/animation/stickman/editor/animationdialog.h deleted file mode 100644 index 293f0d4..0000000 --- a/examples/animation/stickman/editor/animationdialog.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef ANIMATIONDIALOG_H -#define ANIMATIONDIALOG_H - -#include -#include - -QT_BEGIN_NAMESPACE -class QSpinBox; -class QLineEdit; -QT_END_NAMESPACE -class StickMan; -class Animation; -class AnimationDialog: public QDialog -{ - Q_OBJECT -public: - AnimationDialog(StickMan *stickMan, QWidget *parent = 0); - ~AnimationDialog(); - -public slots: - void currentFrameChanged(int currentFrame); - void totalFramesChanged(int totalFrames); - void setCurrentAnimationName(const QString &name); - - void newAnimation(); - void saveAnimation(); - void loadAnimation(); - -private: - void saveCurrentFrame(); - void stickManFromCurrentFrame(); - void initFromAnimation(); - void initUi(); - QMessageBox::StandardButton maybeSave(); - - QSpinBox *m_currentFrame; - QSpinBox *m_totalFrames; - QLineEdit *m_name; - Animation *m_animation; - StickMan *m_stickman; -}; - -#endif diff --git a/examples/animation/stickman/editor/editor.pri b/examples/animation/stickman/editor/editor.pri deleted file mode 100644 index 7ad9edb..0000000 --- a/examples/animation/stickman/editor/editor.pri +++ /dev/null @@ -1,2 +0,0 @@ -SOURCES += $$PWD/animationdialog.cpp $$PWD/mainwindow.cpp -HEADERS += $$PWD/animationdialog.h $$PWD/mainwindow.h diff --git a/examples/animation/stickman/editor/mainwindow.cpp b/examples/animation/stickman/editor/mainwindow.cpp deleted file mode 100644 index e1d08cc..0000000 --- a/examples/animation/stickman/editor/mainwindow.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "mainwindow.h" -#include "animationdialog.h" -#include "stickman.h" - -#include -#include - -MainWindow::MainWindow(StickMan *stickMan) -{ - initActions(stickMan); -} - -MainWindow::~MainWindow() -{ -} - -void MainWindow::initActions(StickMan *stickMan) -{ - AnimationDialog *dialog = new AnimationDialog(stickMan, this); - dialog->show(); - - QMenu *fileMenu = menuBar()->addMenu("&File"); - QAction *loadAction = fileMenu->addAction("&Open"); - QAction *saveAction = fileMenu->addAction("&Save"); - QAction *exitAction = fileMenu->addAction("E&xit"); - - QMenu *animationMenu = menuBar()->addMenu("&Animation"); - QAction *newAnimationAction = animationMenu->addAction("&New animation"); - - connect(loadAction, SIGNAL(triggered()), dialog, SLOT(loadAnimation())); - connect(saveAction, SIGNAL(triggered()), dialog, SLOT(saveAnimation())); - connect(exitAction, SIGNAL(triggered()), QApplication::instance(), SLOT(quit())); - connect(newAnimationAction, SIGNAL(triggered()), dialog, SLOT(newAnimation())); - -} diff --git a/examples/animation/stickman/editor/mainwindow.h b/examples/animation/stickman/editor/mainwindow.h deleted file mode 100644 index ef122d9..0000000 --- a/examples/animation/stickman/editor/mainwindow.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MAINWINDOW_H -#define MAINWINDOW_H - -#include - -class StickMan; -class MainWindow: public QMainWindow -{ -public: - MainWindow(StickMan *stickMan); - ~MainWindow(); - -private: - void initActions(StickMan *stickMan); -}; - -#endif diff --git a/examples/animation/stickman/graphicsview.cpp b/examples/animation/stickman/graphicsview.cpp index 760c31b..89f2430 100644 --- a/examples/animation/stickman/graphicsview.cpp +++ b/examples/animation/stickman/graphicsview.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "graphicsview.h" -#include "editor/mainwindow.h" #include "stickman.h" #include @@ -53,28 +52,6 @@ void GraphicsView::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) close(); - -#if 0 - if (e->key() == Qt::Key_F1) { - if (m_editor == 0) { - QGraphicsScene *scene = new QGraphicsScene; - StickMan *stickMan = new StickMan; - stickMan->setDrawSticks(true); - scene->addItem(stickMan); - - QGraphicsView *view = new QGraphicsView; - view->setBackgroundBrush(Qt::black); - view->setRenderHints(QPainter::Antialiasing); - view->setScene(scene); - - m_editor = new MainWindow(stickMan); - m_editor->setCentralWidget(view); - } - - m_editor->showMaximized(); - } -#endif - emit keyPressed(Qt::Key(e->key())); } diff --git a/examples/animation/stickman/stickman.pro b/examples/animation/stickman/stickman.pro index 1dbbce9..7f8be33 100644 --- a/examples/animation/stickman/stickman.pro +++ b/examples/animation/stickman/stickman.pro @@ -12,8 +12,6 @@ SOURCES += main.cpp \ INCLUDEPATH += $$PWD -include(editor/editor.pri) - # install target.path = $$[QT_INSTALL_EXAMPLES]/animation/stickman sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS stickman.pro -- cgit v0.12 From 2db22b1b12cc7579d08a83ad889efe7f8f07c843 Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 21 Jul 2009 13:18:46 +0200 Subject: use /usr/bin/env perl as interpreter --- tests/auto/test.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/test.pl b/tests/auto/test.pl index 9fd5c9d..a9e3da8 100755 --- a/tests/auto/test.pl +++ b/tests/auto/test.pl @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl use strict; use Cwd; -- cgit v0.12 From 31e358f2290c145b839fc5b7b277922c1ab6e19b Mon Sep 17 00:00:00 2001 From: Harald Fernengel Date: Tue, 21 Jul 2009 13:19:49 +0200 Subject: fix tests for QT_NO_PROCESS and when running tests as root --- tests/auto/bic/tst_bic.cpp | 6 ++++- .../auto/compilerwarnings/tst_compilerwarnings.cpp | 6 ++++- tests/auto/moc/tst_moc.cpp | 20 ++++++++-------- tests/auto/qapplication/tst_qapplication.cpp | 2 ++ tests/auto/qbytearray/tst_qbytearray.cpp | 2 ++ tests/auto/qclipboard/tst_qclipboard.cpp | 2 ++ tests/auto/qcopchannel/tst_qcopchannel.cpp | 2 +- tests/auto/qdir/tst_qdir.cpp | 17 ++++++++++--- tests/auto/qdirectpainter/tst_qdirectpainter.cpp | 4 ++++ tests/auto/qfile/tst_qfile.cpp | 28 +++++++++++++++------- tests/auto/qobject/tst_qobject.cpp | 4 ++++ tests/auto/qprocess/tst_qprocess.cpp | 5 ++++ tests/auto/qsettings/tst_qsettings.cpp | 6 +++-- tests/auto/qtextcodec/tst_qtextcodec.cpp | 4 ++++ 14 files changed, 82 insertions(+), 26 deletions(-) diff --git a/tests/auto/bic/tst_bic.cpp b/tests/auto/bic/tst_bic.cpp index cec5e76..36c35ff 100644 --- a/tests/auto/bic/tst_bic.cpp +++ b/tests/auto/bic/tst_bic.cpp @@ -43,6 +43,10 @@ #include #include +#ifdef QT_NO_PROCESS +QTEST_NOOP_MAIN +#else + #include "qbic.h" #include @@ -367,4 +371,4 @@ void tst_Bic::sizesAndVTables() QTEST_APPLESS_MAIN(tst_Bic) #include "tst_bic.moc" - +#endif diff --git a/tests/auto/compilerwarnings/tst_compilerwarnings.cpp b/tests/auto/compilerwarnings/tst_compilerwarnings.cpp index 57795c9..d5fef1b 100644 --- a/tests/auto/compilerwarnings/tst_compilerwarnings.cpp +++ b/tests/auto/compilerwarnings/tst_compilerwarnings.cpp @@ -47,6 +47,10 @@ #include +#ifdef QT_NO_PROCESS +QTEST_NOOP_MAIN +#else + #include QT_USE_NAMESPACE @@ -248,4 +252,4 @@ void tst_CompilerWarnings::warnings() QTEST_APPLESS_MAIN(tst_CompilerWarnings) #include "tst_compilerwarnings.moc" - +#endif // QT_NO_PROCESS diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 3a40ae0..898cfe1 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -510,7 +510,7 @@ private: void tst_Moc::initTestCase() { -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS) QProcess proc; proc.start("qmake", QStringList() << "-query" << "QT_INSTALL_HEADERS"); QVERIFY(proc.waitForFinished()); @@ -555,7 +555,7 @@ void tst_Moc::oldStyleCasts() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; proc.start("moc", QStringList(srcify("/oldstyle-casts.h"))); QVERIFY(proc.waitForFinished()); @@ -585,7 +585,7 @@ void tst_Moc::warnOnExtraSignalSlotQualifiaction() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; proc.start("moc", QStringList(srcify("extraqualification.h"))); QVERIFY(proc.waitForFinished()); @@ -627,7 +627,7 @@ void tst_Moc::inputFileNameWithDotsButNoExtension() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; proc.setWorkingDirectory(QString(SRCDIR) + "/task71021"); proc.start("moc", QStringList("../Header")); @@ -835,7 +835,7 @@ void tst_Moc::warnOnMultipleInheritance() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; QStringList args; args << "-I" << qtIncludePath + "/QtGui" @@ -858,7 +858,7 @@ void tst_Moc::forgottenQInterface() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; QStringList args; args << "-I" << qtIncludePath + "/QtCore" @@ -940,7 +940,7 @@ void tst_Moc::frameworkSearchPath() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) && !defined(QT_NO_PROCESS) QStringList args; args << "-F" << srcify(".") << srcify("interface-from-framework.h") @@ -978,7 +978,7 @@ void tst_Moc::templateGtGt() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; proc.start("moc", QStringList(srcify("template-gtgt.h"))); QVERIFY(proc.waitForFinished()); @@ -994,7 +994,7 @@ void tst_Moc::templateGtGt() void tst_Moc::defineMacroViaCmdline() { -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; QStringList args; @@ -1082,7 +1082,7 @@ void tst_Moc::warnOnPropertyWithoutREAD() #ifdef MOC_CROSS_COMPILED QSKIP("Not tested when cross-compiled", SkipAll); #endif -#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) QProcess proc; proc.start("moc", QStringList(srcify("warn-on-property-without-read.h"))); QVERIFY(proc.waitForFinished()); diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 8532723..7cb6bfa 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -1382,6 +1382,7 @@ void tst_QApplication::testDeleteLaterProcessEvents() */ void tst_QApplication::desktopSettingsAware() { +#ifndef QT_NO_PROCESS QProcess testProcess; #ifdef Q_OS_WINCE int argc = 0; @@ -1399,6 +1400,7 @@ void tst_QApplication::desktopSettingsAware() QVERIFY(testProcess.waitForFinished(10000)); QCOMPARE(int(testProcess.state()), int(QProcess::NotRunning)); QVERIFY(int(testProcess.error()) != int(QProcess::Crashed)); +#endif } void tst_QApplication::setActiveWindow() diff --git a/tests/auto/qbytearray/tst_qbytearray.cpp b/tests/auto/qbytearray/tst_qbytearray.cpp index 78fbf32..b7e4717 100644 --- a/tests/auto/qbytearray/tst_qbytearray.cpp +++ b/tests/auto/qbytearray/tst_qbytearray.cpp @@ -235,6 +235,8 @@ void tst_QByteArray::qUncompress() QSKIP("Corrupt data causes this tests to lock up on HP-UX / PA-RISC with gcc", SkipAll); #elif defined Q_OS_SOLARIS QSKIP("Corrupt data causes this tests to lock up on Solaris", SkipAll); +#elif defined Q_OS_QNX + QSKIP("Currupt data cuases this test to lock up on QNX", SkipAll); #endif QTEST(::qUncompress(in), "out"); diff --git a/tests/auto/qclipboard/tst_qclipboard.cpp b/tests/auto/qclipboard/tst_qclipboard.cpp index f400754..bcdf043 100644 --- a/tests/auto/qclipboard/tst_qclipboard.cpp +++ b/tests/auto/qclipboard/tst_qclipboard.cpp @@ -192,6 +192,7 @@ void tst_QClipboard::testSignals() */ void tst_QClipboard::copy_exit_paste() { +#ifndef QT_NO_PROCESS #if defined Q_WS_X11 || defined Q_WS_QWS QSKIP("This test does not make sense on X11 and embedded, copied data disappears from the clipboard when the application exits ", SkipAll); // ### It's still possible to test copy/paste - just keep the apps running @@ -205,6 +206,7 @@ void tst_QClipboard::copy_exit_paste() QTest::qWait(100); #endif QCOMPARE(QProcess::execute("paster/paster", stringArgument), 0); +#endif } void tst_QClipboard::setMimeData() diff --git a/tests/auto/qcopchannel/tst_qcopchannel.cpp b/tests/auto/qcopchannel/tst_qcopchannel.cpp index d07898a..ce97eae 100644 --- a/tests/auto/qcopchannel/tst_qcopchannel.cpp +++ b/tests/auto/qcopchannel/tst_qcopchannel.cpp @@ -42,7 +42,7 @@ #include -#ifdef Q_WS_QWS +#if defined(Q_WS_QWS) && !defined(QT_NO_PROCESS) //TESTED_CLASS= //TESTED_FILES= diff --git a/tests/auto/qdir/tst_qdir.cpp b/tests/auto/qdir/tst_qdir.cpp index 1fd5e88..e5b23ab 100644 --- a/tests/auto/qdir/tst_qdir.cpp +++ b/tests/auto/qdir/tst_qdir.cpp @@ -571,10 +571,21 @@ void tst_QDir::entryList() return; } - for (int i=0; i 100); // sanity check proc.kill(); +#endif } class MyObject : public QObject diff --git a/tests/auto/qfile/tst_qfile.cpp b/tests/auto/qfile/tst_qfile.cpp index 8d9c2be..66f29dd 100644 --- a/tests/auto/qfile/tst_qfile.cpp +++ b/tests/auto/qfile/tst_qfile.cpp @@ -382,6 +382,12 @@ void tst_QFile::open() QFETCH( bool, ok ); +#ifdef Q_OS_UNIX + if (::getuid() == 0) + // root and Chuck Norris don't care for file permissions. Skip. + QSKIP("Running this test as root doesn't make sense", SkipAll); +#endif + #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) QEXPECT_FAIL("noreadfile", "Windows does not currently support non-readable files.", Abort); #endif @@ -2493,14 +2499,20 @@ void tst_QFile::map() file.close(); - // Change permissions on a file, just to confirm it would fail - QFile::Permissions originalPermissions = file.permissions(); - QVERIFY(file.setPermissions(QFile::ReadOther)); - QVERIFY(!file.open(QFile::ReadWrite)); - memory = file.map(offset, size); - QCOMPARE(file.error(), QFile::PermissionsError); - QVERIFY(!memory); - QVERIFY(file.setPermissions(originalPermissions)); +#ifdef Q_OS_UNIX + if (::getuid() != 0) + // root always has permissions +#endif + { + // Change permissions on a file, just to confirm it would fail + QFile::Permissions originalPermissions = file.permissions(); + QVERIFY(file.setPermissions(QFile::ReadOther)); + QVERIFY(!file.open(QFile::ReadWrite)); + memory = file.map(offset, size); + QCOMPARE(file.error(), QFile::PermissionsError); + QVERIFY(!memory); + QVERIFY(file.setPermissions(originalPermissions)); + } QVERIFY(file.remove()); } diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 8ce7c3a..4f25af6 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -2426,11 +2426,15 @@ void tst_QObject::dynamicProperties() void tst_QObject::recursiveSignalEmission() { +#ifdef QT_NO_PROCESS + QSKIP("Test requires QProcess", SkipAll); +#else QProcess proc; proc.start("./signalbug"); QVERIFY(proc.waitForFinished()); QVERIFY(proc.exitStatus() == QProcess::NormalExit); QCOMPARE(proc.exitCode(), 0); +#endif } void tst_QObject::blockingQueuedConnection() diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index c19d0a5..d235dff 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -50,6 +50,10 @@ #include #include +#ifdef QT_NO_PROCESS +QTEST_NOOP_MAIN +#else + #if defined(Q_OS_WIN) #include #endif @@ -2132,3 +2136,4 @@ void tst_QProcess::invalidProgramString() QTEST_MAIN(tst_QProcess) #include "tst_qprocess.moc" +#endif diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp index 77fef1f..5b9e9e1 100644 --- a/tests/auto/qsettings/tst_qsettings.cpp +++ b/tests/auto/qsettings/tst_qsettings.cpp @@ -716,6 +716,9 @@ void tst_QSettings::testErrorHandling() #ifdef QT_BUILD_INTERNAL #ifdef Q_OS_WIN QSKIP("Windows doesn't support most file modes, including read-only directories, so this test is moot.", SkipAll); +#elif defined(Q_OS_UNIX) + if (::getuid() == 0) + QSKIP("Running this test as root doesn't work, since file perms do not bother him", SkipAll); #else QFETCH(int, filePerms); QFETCH(int, dirPerms); @@ -724,8 +727,7 @@ void tst_QSettings::testErrorHandling() QFETCH(int, statusAfterGet); QFETCH(int, statusAfterSetAndSync); - - system(QString("chmod 700 %1 2>/dev/null").arg(settingsPath("someDir")).toLatin1()); + system(QString("chmod 700 %1 2>/dev/null").arg(settingsPath("someDir")).toLatin1()); system(QString("chmod -R u+rwx %1 2>/dev/null").arg(settingsPath("someDir")).toLatin1()); system(QString("rm -fr %1").arg(settingsPath("someDir")).toLatin1()); diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index f2da1ec..9f51805 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -1875,6 +1875,9 @@ void tst_QTextCodec::codecForUtfText() #ifdef Q_OS_UNIX void tst_QTextCodec::toLocal8Bit() { +#ifdef QT_NO_PROCESS + QSKIP("This test requires QProcess", SkipAll); +#else QProcess process; process.start("echo/echo"); QString string(QChar(0x410)); @@ -1884,6 +1887,7 @@ void tst_QTextCodec::toLocal8Bit() process.waitForFinished(); QCOMPARE(process.exitStatus(), QProcess::NormalExit); QCOMPARE(process.exitCode(), 0); +#endif } #endif -- cgit v0.12 From 08b3511a0c20cfbfdec91e547a2592afce67f0e6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 21 Jul 2009 13:48:25 +0200 Subject: configure -dont-process must build the host tools on Windows CE Reviewed-by: mauricek --- configure.exe | Bin 1102848 -> 1131520 bytes tools/configure/configureapp.cpp | 2 +- tools/configure/main.cpp | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.exe b/configure.exe index b4b7c50..14eaef4 100644 Binary files a/configure.exe and b/configure.exe differ diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index a899adb..61daca8 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3109,6 +3109,7 @@ void Configure::buildQmake() void Configure::buildHostTools() { + dictionary[ "DONE" ] = "yes"; if (!dictionary.contains("XQMAKESPEC")) return; @@ -3332,7 +3333,6 @@ void Configure::generateMakefiles() } else { cout << "Processing of project files have been disabled." << endl; cout << "Only use this option if you really know what you're doing." << endl << endl; - dictionary[ "DONE" ] = "yes"; return; } } diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp index 0e13c7a..e5c04cc 100644 --- a/tools/configure/main.cpp +++ b/tools/configure/main.cpp @@ -95,7 +95,7 @@ int runConfigure( int argc, char** argv ) #endif if( !app.isDone() ) app.generateMakefiles(); - if( !app.isDone() && app.isOk() ) + if( !app.isDone() ) app.buildHostTools(); if( !app.isDone() ) app.showSummary(); -- cgit v0.12 From 2c1e529e4d9edf9892d9a8d30806ecdfa8d093a3 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 21 Jul 2009 13:53:00 +0200 Subject: New Binary --- configure.exe | Bin 1131520 -> 1892397 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/configure.exe b/configure.exe index 14eaef4..5c5c199 100644 Binary files a/configure.exe and b/configure.exe differ -- cgit v0.12 From 7624741ce0d2ab709f7a7418632c3e7969f536a6 Mon Sep 17 00:00:00 2001 From: Andy Date: Tue, 21 Jul 2009 14:03:13 +0200 Subject: Fix building in a namespace when building with -arch ppc on Mac OS X Task-number: 257080 Reviewed-by: nrc --- src/corelib/arch/qatomic_powerpc.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/arch/qatomic_powerpc.h b/src/corelib/arch/qatomic_powerpc.h index ea3f458..c3b31f9 100644 --- a/src/corelib/arch/qatomic_powerpc.h +++ b/src/corelib/arch/qatomic_powerpc.h @@ -101,8 +101,6 @@ template Q_INLINE_TEMPLATE bool QBasicAtomicPointer::isFetchAndAddWaitFree() { return false; } -QT_BEGIN_NAMESPACE - #if defined(Q_CC_GNU) #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) \ -- cgit v0.12 From f616cebd67a6044d6e26d57bc26975ee153479ea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jul 2009 14:06:07 +0200 Subject: Disable visibility on CC 5.9 since the compiler doesn't like it --- src/corelib/global/qglobal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 0ef48fa..866247a 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -665,7 +665,8 @@ namespace QT_NAMESPACE {} # define Q_ALIGNOF(type) __alignof__(type) # define Q_TYPEOF(expr) __typeof__(expr) # define Q_DECL_ALIGN(n) __attribute__((__aligned__(n))) -# define Q_DECL_EXPORT __attribute__((__visibility__("default"))) +// using CC 5.9: Warning: attribute visibility is unsupported and will be skipped.. +//# define Q_DECL_EXPORT __attribute__((__visibility__("default"))) # endif # if !defined(_BOOL) # define Q_NO_BOOL_TYPE -- cgit v0.12 From 8714892977269591bb9b348c6eb549a7f2c45cbc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jul 2009 14:06:50 +0200 Subject: There's no need to include qstringmatcher.h in qstringlist.h --- src/corelib/tools/qstringlist.cpp | 1 + src/corelib/tools/qstringlist.h | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index 5a2b37a..5c550af 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -41,6 +41,7 @@ #include #include +#include QT_BEGIN_NAMESPACE diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h index 665c0d0..f36567a 100644 --- a/src/corelib/tools/qstringlist.h +++ b/src/corelib/tools/qstringlist.h @@ -47,7 +47,6 @@ #include #include #include -#include #ifdef QT_INCLUDE_COMPAT #include #endif -- cgit v0.12 From c5e9b0238f0bfe0b8e2c415078011c6d6b34fb11 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Tue, 21 Jul 2009 14:16:12 +0200 Subject: QHttpNetworkConnection: Clarifying code comment about compression Reviewed-by: TrustMe --- src/network/access/qhttpnetworkconnection.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 726b954..2169f97 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -228,7 +228,12 @@ void QHttpNetworkConnectionPrivate::prepareRequest(HttpMessagePair &messagePair) #ifndef QT_NO_NETWORKPROXY } #endif - // set the gzip header + + // If the request had a accept-encoding set, we better not mess + // with it. If it was not set, we announce that we understand gzip + // and remember this fact in request.d->autoDecompress so that + // we can later decompress the HTTP reply if it has such an + // encoding. value = request.headerField("accept-encoding"); if (value.isEmpty()) { #ifndef QT_NO_COMPRESS -- cgit v0.12 From 21556aeb9bbfe86b742af9b75a160c44c914f41c Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 21 Jul 2009 14:19:50 +0200 Subject: Another fix needed to build in a namespace on Mac with -arch ppc Don't know how this got lost in the original submit since I had added both. Task-number: 257080 Reviewed-by: nrc --- src/gui/kernel/qt_cocoa_helpers_mac_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h index 5156b9c..9cb5398 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h +++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h @@ -105,6 +105,8 @@ #include #include "private/qt_mac_p.h" +struct HIContentBorderMetrics; + #ifdef Q_WS_MAC32 typedef struct _NSPoint NSPoint; // Just redefine here so I don't have to pull in all of Cocoa. #else @@ -121,7 +123,6 @@ void macWindowToolbarSet( void * /*OSWindowRef*/ window, void* toolbarRef ); bool macWindowToolbarVisible( void * /*OSWindowRef*/ window ); void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow ); void macWindowFlush(void * /*OSWindowRef*/ window); -struct HIContentBorderMetrics; void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics); void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm); void qt_mac_update_mouseTracking(QWidget *widget); -- cgit v0.12 From ba191b0a26b966ad1fb596a905307399922bc44a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jul 2009 14:28:01 +0200 Subject: Fix warning with Sun CC 5.9 and xlC 7: no new types inside anonymous unions. These compilers compile this code fine, but this warning shows up *everywhere* when building Qt (or used to, since qstringlist.h included qstringmatcher.h). Move the structure definition to outside the union. --- src/corelib/tools/qstringmatcher.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/corelib/tools/qstringmatcher.h b/src/corelib/tools/qstringmatcher.h index 2b8edc9..61b7a95 100644 --- a/src/corelib/tools/qstringmatcher.h +++ b/src/corelib/tools/qstringmatcher.h @@ -81,13 +81,14 @@ private: // explicitely allow anonymous unions for RVCT to prevent compiler warnings #pragma anon_unions #endif + struct Data { + uchar q_skiptable[256]; + const QChar *uc; + int len; + }; union { uint q_data[256]; - struct { - uchar q_skiptable[256]; - const QChar *uc; - int len; - } p; + Data p; }; }; -- cgit v0.12 From 650f11129b74297f502f5ddd81f52a3193ea65c0 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jul 2009 14:15:01 +0200 Subject: Doc: Updated link and a bit more documentation for QWebSecurityOrigin and QWebDatabase. --- src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp | 21 ++++++++++++++++----- .../webkit/WebKit/qt/Api/qwebsecurityorigin.cpp | 15 ++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp index 7e85eaa..0d11381 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebdatabase.cpp @@ -34,9 +34,20 @@ using namespace WebCore; \brief The QWebDatabase class provides access to HTML 5 databases created with JavaScript. The upcoming HTML 5 standard includes support for SQL databases that web sites can create and - access on a local computer through JavaScript. QWebDatabase is the C++ interface to these databases. + access on a local computer through JavaScript. QWebDatabase is the C++ interface to these + databases. - For more information refer to the \l{http://www.w3.org/html/wg/html5/#sql}{HTML 5 Draft Standard}. + To get access to all databases defined by a security origin, use QWebSecurityOrigin::databases(). + Each database has an internal name(), as well as a user-friendly name, provided by displayName(). + + WebKit uses SQLite to create and access the local SQL databases. The location of the database + file in the local file system is returned by fileName(). You can access the database directly + through the QtSql database module. + + For each database the web site can define an expectedSize(). The current size of the database + in bytes is returned by size(). + + For more information refer to the \l{http://dev.w3.org/html5/webdatabase/}{HTML 5 Draft Standard}. \sa QWebSecurityOrigin */ @@ -127,7 +138,7 @@ QWebDatabase::QWebDatabase(QWebDatabasePrivate* priv) \endcode \note Concurrent access to a database from multiple threads or processes - is not very efficient because Sqlite is used as WebKit's database backend. + is not very efficient because SQLite is used as WebKit's database backend. */ QString QWebDatabase::fileName() const { @@ -149,8 +160,8 @@ QWebSecurityOrigin QWebDatabase::origin() const } /*! - Removes the database \a db from its security origin. All data stored in this database - will be destroyed. + Removes the database \a db from its security origin. All data stored in the + database \a db will be destroyed. */ void QWebDatabase::removeDatabase(const QWebDatabase &db) { diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp index da9278c..d2eaf10 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsecurityorigin.cpp @@ -36,10 +36,9 @@ using namespace WebCore; \brief The QWebSecurityOrigin class defines a security boundary for web sites. QWebSecurityOrigin provides access to the security domains defined by web sites. - An origin consists of a host name, a scheme, and a port number. Web sites with the same - security origin can access each other's resources for client-side scripting or databases. - - ### diagram + An origin consists of a host name, a scheme, and a port number. Web sites + with the same security origin can access each other's resources for client-side + scripting or databases. For example the site \c{http://www.example.com/my/page.html} is allowed to share the same database as \c{http://www.example.com/my/overview.html}, or access each other's @@ -47,7 +46,13 @@ using namespace WebCore; \c{http://www.malicious.com/evil.html} from accessing \c{http://www.example.com/}'s resources, because they are of a different security origin. - QWebSecurity also provides access to all databases defined within a security origin. + Call QWebFrame::securityOrigin() to get the QWebSecurityOrigin for a frame in a + web page, and use host(), scheme() and port() to identify the security origin. + + Use databases() to access the databases defined within a security origin. The + disk usage of the origin's databases can be limited with setDatabaseQuota(). + databaseQuota() and databaseUsage() report the current limit as well as the + current usage. For more information refer to the \l{http://en.wikipedia.org/wiki/Same_origin_policy}{"Same origin policy" Wikipedia Article}. -- cgit v0.12 From 1ba8d525d3c898c198821e493c7fa6c4eb4689a3 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Jul 2009 13:55:04 +0200 Subject: Fix compilation with xlC 7: the cast is necessary to get delete[] to understand what to delete Reviewed-By: Trust Me --- src/corelib/kernel/qobject.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index eb1bd0b..6503ab0 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -854,7 +854,7 @@ QObject::~QObject() QObjectPrivate::Connection::~Connection() { if (argumentTypes != &DIRECT_CONNECTION_ONLY) - delete [] argumentTypes; + delete [] static_cast(argumentTypes); } -- cgit v0.12 From 6c5cbdbee91ea200321480dcee243ae061a3a902 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Jul 2009 14:14:28 +0200 Subject: Add code to the Unix configure script to get the xlC version number --- configure | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 13bdf7f..87fe281 100755 --- a/configure +++ b/configure @@ -6114,8 +6114,34 @@ case "$XPLATFORM" in canBuildWebKit="no" ;; aix-xlc*) - canBuildWebKit="no" - canBuildQtXmlPatterns="no" + # Get the xlC version + cat > xlcver.c < +int main() +{ + printf("%d.%d\n", __xlC__ >> 8, __xlC__ & 0xFF); + return 0; +} +EOF + xlcver= + if ${QMAKE_CONF_COMPILER} -o xlcver xlcver.c >/dev/null 2>/dev/null; then + xlcver=`./xlcver 2>/dev/null` + rm -f ./xlcver + fi + if [ "$OPT_VERBOSE" = "yes" ]; then + if [ -n "$xlcver" ]; then + echo Found IBM xlC version: $xlcver. + else + echo Could not determine IBM xlC version, assuming oldest supported. + fi + fi + + case "$xlcver" in + *) + canBuildWebKit="no" + canBuildQtXmlPatterns="no" + ;; + esac ;; irix-cc*) canBuildWebKit="no" -- cgit v0.12 From cb64ac587249f5dc6563a035e2ef5a3ad2bc5d13 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Jul 2009 15:38:27 +0200 Subject: xlC 7 cannot compile QtConcurrent with these templates here --- src/corelib/concurrent/qfuture.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/concurrent/qfuture.h b/src/corelib/concurrent/qfuture.h index 47015ee..f2db5ac 100644 --- a/src/corelib/concurrent/qfuture.h +++ b/src/corelib/concurrent/qfuture.h @@ -210,7 +210,7 @@ public: bool operator==(const QFuture &other) const { return (d == other.d); } bool operator!=(const QFuture &other) const { return (d != other.d); } -#ifndef QT_NO_MEMBER_TEMPLATES +#if !defined(QT_NO_MEMBER_TEMPLATES) && !defined(Q_CC_XLC) template QFuture(const QFuture &other) : d(other.d) -- cgit v0.12 From 9025b909da8e52c700b0e0ac2f62bf441233c8c5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 19 Jul 2009 13:42:06 +0200 Subject: Fix compilation of QHash with xlC 7. Make sure that the function is found properly. It can't be static, for whatever reason. Reviewed-By: Peter Hartmann --- src/xmlpatterns/type/qprimitives_p.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/xmlpatterns/type/qprimitives_p.h b/src/xmlpatterns/type/qprimitives_p.h index 78bd4ae..b77698a 100644 --- a/src/xmlpatterns/type/qprimitives_p.h +++ b/src/xmlpatterns/type/qprimitives_p.h @@ -74,17 +74,6 @@ QT_BEGIN_NAMESPACE class QString; /** - * @internal - * - * A method to allow a QHash or QSet with QUrl - * as key type. - */ -inline uint qHash(const QUrl &uri) -{ - return qHash(uri.toString()); -} - -/** * @short The namespace for the internal API of QtXmlPatterns * @internal */ @@ -92,6 +81,17 @@ namespace QPatternist { /** + * @internal + * + * A method to allow a QHash or QSet with QUrl + * as key type. + */ + inline uint qHash(const QUrl &uri) + { + return qHash(uri.toString()); + } + + /** * @defgroup Patternist_cppWXSTypes C++ Primitives for W3C XML Schema Number Types * * The implementations of W3C XML Schema's(WXS) number types, more specifically @@ -208,6 +208,8 @@ namespace QPatternist QString Q_AUTOTEST_EXPORT escape(const QString &input); } +using QPatternist::qHash; + QT_END_NAMESPACE QT_END_HEADER -- cgit v0.12 From 4278109e1f6cca83e687977db55b193ef4f7fcd7 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 19 Jul 2009 14:02:10 +0200 Subject: Fix compilation with xlC 7: the compiler doesn't find statics in template expansions. parser/qmaintainingreader.cpp", line 175.40: 1540-0274 (S) The name lookup for "formatKeyword" did not find a declaration. parser/qmaintainingreader.cpp", line 175.40: 1540-1292 (I) Static declarations are not considered for a function call if the function is not qualified. Reviewed-By: Peter Hartmann Reviewed-By: Frans Englich --- src/xmlpatterns/utils/qpatternistlocale_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/xmlpatterns/utils/qpatternistlocale_p.h b/src/xmlpatterns/utils/qpatternistlocale_p.h index dc287bd..d8288c7 100644 --- a/src/xmlpatterns/utils/qpatternistlocale_p.h +++ b/src/xmlpatterns/utils/qpatternistlocale_p.h @@ -93,7 +93,8 @@ namespace QPatternist Q_DISABLE_COPY(QtXmlPatterns) }; - static inline QString formatKeyword(const QString &keyword) + // don't make this function static, otherwise xlC 7 cannot find it + inline QString formatKeyword(const QString &keyword) { return QLatin1String("") + escape(keyword) + -- cgit v0.12 From 9317e521f0b0f689c87b95b927102dbf55edb89f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 19 Jul 2009 14:03:49 +0200 Subject: Fix compilation with xlC 7: the compiler tries to expand qIsForwardIteratorEnd with QString This is used in other places too, so move the definition to the header. Reviewed-By: Trust Me --- src/xmlpatterns/api/qabstractxmlforwarditerator_p.h | 15 ++++++++++++++- src/xmlpatterns/functions/qsequencegeneratingfns.cpp | 13 ------------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h b/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h index d3188d3..b4eefeb 100644 --- a/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h +++ b/src/xmlpatterns/api/qabstractxmlforwarditerator_p.h @@ -55,7 +55,7 @@ #include #include #include - +#include QT_BEGIN_HEADER @@ -74,6 +74,19 @@ inline bool qIsForwardIteratorEnd(const T &unit) return !unit; } +/** + * @short Helper class for StringSplitter + * + * Needed by the QAbstractXmlForwardIterator sub-class. + * + * @relates StringSplitter + */ +template<> +inline bool qIsForwardIteratorEnd(const QString &unit) +{ + return unit.isNull(); +} + template class QAbstractXmlForwardIterator; class QAbstractXmlForwardIteratorPrivate; diff --git a/src/xmlpatterns/functions/qsequencegeneratingfns.cpp b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp index 81724f8..e3f30c5 100644 --- a/src/xmlpatterns/functions/qsequencegeneratingfns.cpp +++ b/src/xmlpatterns/functions/qsequencegeneratingfns.cpp @@ -69,19 +69,6 @@ Item IdFN::mapToItem(const QString &id, } /** - * @short Helper class for StringSplitter - * - * Needed by the QAbstractXmlForwardIterator sub-class. - * - * @relates StringSplitter - */ -template<> -bool qIsForwardIteratorEnd(const QString &unit) -{ - return unit.isNull(); -} - -/** * @short Helper class for IdFN. * * StringSplitter takes an Iterator which delivers strings of this kind: -- cgit v0.12 From 08ff267fe37dcccb7f63a8158b260e2e3b1e0965 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 16 Jul 2009 15:37:54 +0200 Subject: Use the configure script to enable/disable QtConcurrent and QtXmlPatterns Using qglobal.h and checking the compiler version with the preprocessor has the side-effect that moc won't generate proper code since it doesn't know about the compiler version. Enable both modules under Sun CC 5.9 and IBM xlC 7.0. --- configure | 44 +++++++++++++++++++++++++++++++------------- src/corelib/global/qglobal.h | 23 +++++------------------ 2 files changed, 36 insertions(+), 31 deletions(-) diff --git a/configure b/configure index 87fe281..e05e1d5 100755 --- a/configure +++ b/configure @@ -6057,6 +6057,7 @@ fi # canBuildQtXmlPatterns="yes" canBuildWebKit="$HAVE_STL" +canBuildQtConcurrent="yes" # WebKit requires stdint.h "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/stdint "Stdint" $L_FLAGS $I_FLAGS $l_FLAGS @@ -6088,9 +6089,9 @@ case "$XPLATFORM" in case "$(${QMAKE_CONF_COMPILER} -dumpversion)" in 4*|3.4*) ;; - 3.3*) - canBuildWebKit="no" - ;; + 3.3*) + canBuildWebKit="no" + ;; *) canBuildWebKit="no" canBuildQtXmlPatterns="no" @@ -6098,17 +6099,22 @@ case "$XPLATFORM" in esac ;; solaris-cc*) - # Check the compiler version - case `${QMAKE_CONF_COMPILER} -V 2>&1 | awk '{print $4}'` in - *) - canBuildWebKit="no" - canBuildQtXmlPatterns="no" - ;; - esac - ;; + # Check the compiler version + case `${QMAKE_CONF_COMPILER} -V 2>&1 | awk '{print $4}'` in + 5.[012345678]) + canBuildWebKit="no" + canBuildQtXmlPatterns="no" + canBuildQtConcurrent="no" + ;; + 5.9) + canBuildWebKit="no" + ;; + esac + ;; hpux-acc*) canBuildWebKit="no" canBuildQtXmlPatterns="no" + canBuildQtConcurrent="no" ;; hpuxi-acc*) canBuildWebKit="no" @@ -6137,17 +6143,28 @@ EOF fi case "$xlcver" in - *) + [123456].*) canBuildWebKit="no" canBuildQtXmlPatterns="no" + canBuildQtConcurrent="no" + ;; + *) + canBuildWebKit="no" ;; esac - ;; + ;; irix-cc*) canBuildWebKit="no" + canBuildQtConcurrent="no" ;; esac +CFG_CONCURRENT="yes" +if [ "$canBuildQtConcurrent" = "no" ]; then + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CONCURRENT" + CFG_CONCURRENT="no" +fi + if [ "$CFG_XMLPATTERNS" = "yes" -a "$CFG_EXCEPTIONS" = "no" ]; then echo "QtXmlPatterns was requested, but it can't be built due to exceptions being disabled." exit 1 @@ -7056,6 +7073,7 @@ echo "Qt 3 compatibility .. $CFG_QT3SUPPORT" [ "$CFG_DBUS" = "no" ] && echo "QtDBus module ....... no" [ "$CFG_DBUS" = "yes" ] && echo "QtDBus module ....... yes (run-time)" [ "$CFG_DBUS" = "linked" ] && echo "QtDBus module ....... yes (linked)" +echo "QtConcurrent code.... $CFG_CONCURRENT" echo "QtScriptTools module $CFG_SCRIPTTOOLS" echo "QtXmlPatterns module $CFG_XMLPATTERNS" echo "Phonon module ....... $CFG_PHONON" diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 866247a..7b16dff 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2408,28 +2408,15 @@ QT_LICENSED_MODULE(DBus) # define QT_NO_QFUTURE #endif -/* - Turn off certain features for compilers that have problems parsing - the code. -*/ -#if (defined(Q_CC_HPACC) && defined(QT_ARCH_PARISC)) \ - || defined(Q_CC_MIPS) \ - || defined(Q_CC_XLC) -// HP aCC A.03.*, MIPSpro, and xlC cannot handle -// the template function declarations for the QtConcurrent functions -# define QT_NO_QFUTURE -# define QT_NO_CONCURRENT -#endif - -// MSVC 6.0, MSVC .NET 2002, and old versions of Sun CC can`t handle the map(), etc templates, +// MSVC 6.0 and MSVC .NET 2002, can`t handle the map(), etc templates, // but the QFuture class compiles. -#if (defined(Q_CC_MSVC) && _MSC_VER <= 1300) || (defined (__SUNPRO_CC) && __SUNPRO_CC <= 0x590) +#if (defined(Q_CC_MSVC) && _MSC_VER <= 1300) # define QT_NO_CONCURRENT #endif -// Mingw uses a gcc 3 version which has problems with some of the -// map/filter overloads. So does IRIX and Solaris. -#if (defined(Q_OS_IRIX) || defined(Q_CC_MINGW) || defined (Q_OS_SOLARIS)) && (__GNUC__ < 4) +// gcc 3 version has problems with some of the +// map/filter overloads. +#if defined(Q_CC_GNU) && (__GNUC__ < 4) # define QT_NO_CONCURRENT_MAP # define QT_NO_CONCURRENT_FILTER #endif -- cgit v0.12 From 77d9528d802b4e36423814ae2c52abc3e36de40c Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jul 2009 15:27:50 +0200 Subject: Doc: More docu for the QPixmapCache::Key --- src/gui/image/qpixmapcache.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 82069d0..ecdcd8c 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -64,7 +64,8 @@ QT_BEGIN_NAMESPACE access the global pixmap cache. It creates an internal QCache object for caching the pixmaps. - The cache associates a pixmap with a string as a key or with a QPixmapCache::Key. + The cache associates a pixmap with a user-provided string as a key, + or with a QPixmapCache::Key that the cache generates. Using QPixmapCache::Key for keys is faster than using strings. The string API is very convenient for complex keys but the QPixmapCache::Key API will be very efficient and convenient for a one-to-one object-to-pixmap mapping \mdash in @@ -92,6 +93,17 @@ static int cache_limit = 10240; // 10 MB cache limit for desktop #endif /*! + \class QPixmapCache::Key + \brief The QPixmapCache::Key class can be used for efficient access + to the QPixmapCache. + \since 4.6 + + Use QPixmapCache::insert() to receive an instance of Key generated + by the pixmap cache. You can store the key in your own objects for + a very efficient one-to-one object-to-pixmap mapping. +*/ + +/*! Constructs an empty Key object. */ QPixmapCache::Key::Key() : d(0) -- cgit v0.12 From dcb735f92d87aacade6aa65079fe3da06efca553 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 21 Jul 2009 15:23:17 +0200 Subject: add autotest for adding transition from state machine's root It's not supported because the root state has no ancestor, which is a requirement for the state machine's transition selection algorithm. --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index efcb983..bafd848 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -127,6 +127,7 @@ private slots: void targetStateWithNoParent(); void targetStateDeleted(); void transitionToRootState(); + void transitionFromRootState(); void transitionEntersParent(); void defaultErrorState(); @@ -279,6 +280,15 @@ void tst_QStateMachine::transitionToRootState() QVERIFY(machine.configuration().contains(initialState)); } +void tst_QStateMachine::transitionFromRootState() +{ + QStateMachine machine; + QState *root = machine.rootState(); + QState *s1 = new QState(root); + QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition from root state"); + root->addTransition(new EventTransition(QEvent::User, s1)); +} + void tst_QStateMachine::transitionEntersParent() { QStateMachine machine; -- cgit v0.12 From 641ba0bb2c144a4bef25982d90ac49d9af354202 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 21 Jul 2009 15:41:16 +0200 Subject: Fix memory leak with wrapped events Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index bf3ee31..a00e7e1 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -2155,6 +2155,8 @@ QSignalEvent::~QSignalEvent() Constructs a new QWrappedEvent object with the given \a object and \a event. + + The QWrappedEvent object takes ownership of \a event. */ QWrappedEvent::QWrappedEvent(QObject *object, QEvent *event) : QEvent(QEvent::Wrapped), m_object(object), m_event(event) @@ -2166,6 +2168,7 @@ QWrappedEvent::QWrappedEvent(QObject *object, QEvent *event) */ QWrappedEvent::~QWrappedEvent() { + delete m_event; } /*! -- cgit v0.12 From ea7830a2551f1c68e5dbc53ee9a5ce3a8fcbe872 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Tue, 21 Jul 2009 15:47:37 +0200 Subject: Fix memleaks in the autotests --- tests/auto/qstatemachine/tst_qstatemachine.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index bafd848..44fc998 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -285,8 +285,11 @@ void tst_QStateMachine::transitionFromRootState() QStateMachine machine; QState *root = machine.rootState(); QState *s1 = new QState(root); + EventTransition *trans = new EventTransition(QEvent::User, s1); QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition from root state"); - root->addTransition(new EventTransition(QEvent::User, s1)); + root->addTransition(trans); + QCOMPARE(trans->sourceState(), (QState*)0); + delete trans; } void tst_QStateMachine::transitionEntersParent() @@ -3113,6 +3116,8 @@ void tst_QStateMachine::specificTargetValueOfAnimation() QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 2.0); QCOMPARE(anim->endValue().toDouble(), 10.0); + + delete anim; } void tst_QStateMachine::addDefaultAnimation() @@ -3145,6 +3150,8 @@ void tst_QStateMachine::addDefaultAnimation() QVERIFY(machine.configuration().contains(s3)); QCOMPARE(object->property("foo").toDouble(), 2.0); + + delete object; } void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() @@ -3224,6 +3231,9 @@ void tst_QStateMachine::removeDefaultAnimation() machine.removeDefaultAnimation(anim2); QCOMPARE(machine.defaultAnimations().size(), 0); + + delete anim; + delete anim2; } void tst_QStateMachine::overrideDefaultAnimationWithSpecific() @@ -3264,6 +3274,9 @@ void tst_QStateMachine::overrideDefaultAnimationWithSpecific() QVERIFY(machine.configuration().contains(s3)); QCOMPARE(counter.counter, 2); // specific animation started and stopped + + delete defaultAnimation; + delete moreSpecificAnimation; } /* -- cgit v0.12 From b6b12bc6b8296d7e199cab0ece35c9eb9ae7fe64 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 Mar 2009 14:36:52 +0100 Subject: Implement strict STD3 checking of hostnames in URLs. Made the toPunycodeHelper function write to a QString. Renamed qt_from_ACE to qt_ACE_do to indicate what it actually does. Added the STD3 rules for hostnames, forcing hostnames to have to strictly comply to STD3. Also, execute nameprep in the correct order (before trying to encode to Punycode). Validate hostnames when QUrlPrivate::canonicalHost() called, including validation of IP Literals. Validation of IPv4 is missing. Adapted other functions to use qt_ACE_do, notably QUrl::toAce (avoid code duplication). --- src/corelib/io/qurl.cpp | 241 ++++++++++++++++++++++++++++++------------- tests/auto/qurl/tst_qurl.cpp | 96 ++++++++++++++--- 2 files changed, 256 insertions(+), 81 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 180e9ec..dc27dfb 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2901,8 +2901,17 @@ static bool isBidirectionalL(const QChar &ch) return false; } +#ifdef QT_BUILD_INTERNAL +// export for tst_qurl.cpp +Q_AUTOTEST_EXPORT QString qt_nameprep(const QString &); +Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QStringRef &); +#else +// non-test build, keep the symbols for ourselves +static QString qt_nameprep(const QString &); +static bool qt_check_std3rules(const QStringRef &); +#endif -Q_AUTOTEST_EXPORT QString qt_nameprep(const QString &source) +QString qt_nameprep(const QString &source) { QString mapped = source; @@ -2959,8 +2968,32 @@ Q_AUTOTEST_EXPORT QString qt_nameprep(const QString &source) return mapped; } +bool qt_check_std3rules(const QStringRef &source) +{ + int len = source.length(); + if (len > 63) + return false; + + for (int i = 0; i < len; ++i) { + register ushort c = source.at(i).unicode(); + if (c == '-' && (i == 0 || i == len - 1)) + return false; -static inline char encodeDigit(uint digit) + // verifying the absence of LDH is the same as verifying that + // only LDH is present + if (c == '-' || (c >= '0' && c <= '9') + || (c >= 'A' && c <= 'Z') + || (c >= 'a' && c <= 'z')) + continue; + + return false; + } + + return true; +} + + +static inline uint encodeDigit(uint digit) { return digit + 22 + 75 * (digit < 26); } @@ -2977,7 +3010,7 @@ static inline uint adapt(uint delta, uint numpoints, bool firsttime) return k + (((base - tmin + 1) * delta) / (delta + skew)); } -static inline void appendEncode(QByteArray* output, uint& delta, uint& bias, uint& b, uint& h) +static inline void appendEncode(QString* output, uint& delta, uint& bias, uint& b, uint& h) { uint qq; uint k; @@ -2991,17 +3024,17 @@ static inline void appendEncode(QByteArray* output, uint& delta, uint& bias, uin t = (k <= bias) ? tmin : (k >= bias + tmax) ? tmax : k - bias; if (qq < t) break; - *output += encodeDigit(t + (qq - t) % (base - t)); + *output += QChar(encodeDigit(t + (qq - t) % (base - t))); qq = (qq - t) / (base - t); } - *output += encodeDigit(qq); + *output += QChar(encodeDigit(qq)); bias = adapt(delta, h + 1, h == b); delta = 0; ++h; } -static void toPunycodeHelper(const QChar *s, int ucLength, QByteArray *output) +static void toPunycodeHelper(const QChar *s, int ucLength, QString *output) { uint n = initial_n; uint delta = 0; @@ -3010,7 +3043,7 @@ static void toPunycodeHelper(const QChar *s, int ucLength, QByteArray *output) int outLen = output->length(); output->resize(outLen + ucLength); - char *d = output->data() + outLen; + QChar *d = output->data() + outLen; bool skipped = false; // copy all basic code points verbatim to output. for (uint j = 0; j < (uint) ucLength; ++j) { @@ -3035,7 +3068,7 @@ static void toPunycodeHelper(const QChar *s, int ucLength, QByteArray *output) // if basic code points were copied, add the delimiter character. if (h > 0) - *output += 0x2d; + *output += QChar(0x2d); // while there are still unprocessed non-basic code points left in // the input string... @@ -3083,7 +3116,7 @@ static void toPunycodeHelper(const QChar *s, int ucLength, QByteArray *output) } // prepend ACE prefix - output->insert(outLen, "xn--"); + output->insert(outLen, QLatin1String("xn--")); return; } @@ -3164,46 +3197,118 @@ static bool qt_is_idn_enabled(const QString &domain) return equal(tld, len, idn_whitelist[i]); } -static QString qt_from_ACE(const QString &domainMC) +static inline bool isDotDelimiter(ushort uc) { + // IDNA / rfc3490 describes these four delimiters used for + // separating labels in unicode international domain + // names. + return uc == 0x2e || uc == 0x3002 || uc == 0xff0e || uc == 0xff61; +} + +static int nextDotDelimiter(const QString &domain, int from = 0) +{ + const QChar *b = domain.unicode(); + const QChar *ch = b + from; + const QChar *e = b + domain.length(); + while (ch < e) { + if (isDotDelimiter(ch->unicode())) + break; + else + ++ch; + } + return ch - b; +} + +enum AceOperation { ToAceOnly, NormalizeAce }; +static QString qt_ACE_do(const QString &domainMC, AceOperation op) +{ + if (domainMC.isEmpty()) + return domainMC; QString domain = domainMC.toLower(); - int idx = domain.indexOf(QLatin1Char('.')); - if (idx != -1) { - if (!domain.contains(QLatin1String("xn--"))) { - bool simple = true; - for (int i = 0; i < domain.size(); ++i) { - ushort ch = domain.at(i).unicode(); - if (ch > 'z' || ch < '-' || ch == '/' || (ch > '9' && ch < 'A') || (ch > 'Z' && ch < 'a')) { - simple = false; - break; - } + + QString result; + result.reserve(domain.length()); + + const bool isIdnEnabled = op == NormalizeAce ? qt_is_idn_enabled(domain) : false; + int lastIdx = 0; + while (1) { + int idx = nextDotDelimiter(domain, lastIdx); + if (idx == lastIdx) + return QString(); // two delimiters in a row -- empty label not allowed + + // RFC 3490 says, about the ToASCII operation: + // 3. If the UseSTD3ASCIIRules flag is set, then perform these checks: + // + // (a) Verify the absence of non-LDH ASCII code points; that is, the + // absence of 0..2C, 2E..2F, 3A..40, 5B..60, and 7B..7F. + // + // (b) Verify the absence of leading and trailing hyphen-minus; that + // is, the absence of U+002D at the beginning and end of the + // sequence. + // and: + // 8. Verify that the number of code points is in the range 1 to 63 + // inclusive. + + bool simple = true; + for (int i = lastIdx; i < idx; ++i) { + ushort ch = domain.at(i).unicode(); + if (ch > 0x7f) { + simple = false; + break; } - if (simple) - return domain; } - - const bool isIdnEnabled = qt_is_idn_enabled(domain); - int lastIdx = 0; - QString result; - while (1) { + + if (simple && idx > lastIdx + 4) { + // ACE form domains are simple, but we can't consider them simple + // is this an ACE form? + static const ushort acePrefixUtf16[] = { 'x', 'n', '-', '-' }; + if (memcmp(domain.utf16() + lastIdx, acePrefixUtf16, sizeof acePrefixUtf16) == 0) + simple = false; + } + + QString aux; + QStringRef label; + if (simple) { + // fastest conversion: this is the common case (non IDN-domains) + // just memcpy from source (domain) to destination (result) + // there's no need to nameprep since everything is ASCII already + int prevLen = result.size(); + result.resize(prevLen + idx - lastIdx); + memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar)); + + label = QStringRef(&result, prevLen, result.length() - prevLen); + } else { // Nameprep the host. If the labels in the hostname are Punycode // encoded, we decode them immediately, then nameprep them. - QByteArray label; - toPunycodeHelper(domain.constData() + lastIdx, idx - lastIdx, &label); - result += qt_nameprep(isIdnEnabled ? QUrl::fromPunycode(label) : QString::fromLatin1(label)); - lastIdx = idx + 1; - if (lastIdx < domain.size() + 1) - result += QLatin1Char('.'); - else - break; - idx = domain.indexOf(QLatin1Char('.'), lastIdx); - if (idx == -1) - idx = domain.size(); + QString tmp = domain.mid(lastIdx, idx - lastIdx); + tmp = qt_nameprep(tmp); + + if (isIdnEnabled) { + toPunycodeHelper(tmp.constData(), tmp.size(), &aux); + label = QStringRef(&aux); + + tmp = QUrl::fromPunycode(aux.toLatin1()); + if (tmp.isEmpty()) + return QString(); + result += tmp; + } else { + int prevLen = result.size(); + toPunycodeHelper(tmp.constData(), tmp.size(), &result); + + label = QStringRef(&result, prevLen, result.length() - prevLen); + } } - return result; - } else { - return qt_nameprep(domain); + + if (!qt_check_std3rules(label)) + return QString(); + + lastIdx = idx + 1; + if (lastIdx < domain.size() + 1) + result += QLatin1Char('.'); + else + break; } + return result; } @@ -3246,12 +3351,27 @@ QUrlPrivate::QUrlPrivate(const QUrlPrivate ©) QString QUrlPrivate::canonicalHost() const { - if (QURL_HASFLAG(stateFlags, HostCanonicalized)) + if (QURL_HASFLAG(stateFlags, HostCanonicalized) || host.isEmpty()) return host; QUrlPrivate *that = const_cast(this); QURL_SETFLAG(that->stateFlags, HostCanonicalized); - that->host = qt_from_ACE(host); + if (host.contains(QLatin1Char(':'))) { + // This is an IP Literal, use _IPLiteral to validate + QByteArray ba = host.toLatin1(); + if (!ba.startsWith('[')) { + // surround the IP Literal with [ ] if it's not already done so + ba.reserve(ba.length() + 2); + ba.prepend('['); + ba.append(']'); + } + + const char *ptr = ba.constData(); + if (!_IPLiteral(&ptr)) + that->host.clear(); + } else { + that->host = qt_ACE_do(host, NormalizeAce); + } return that->host; } @@ -3737,7 +3857,10 @@ QByteArray QUrlPrivate::toEncoded(QUrl::FormattingOptions options) const } } - url += QUrl::toAce(host); + if (host.startsWith(QLatin1Char('['))) + url += host.toLatin1(); + else + url += QUrl::toAce(host); if (!(options & QUrl::RemovePort) && port != -1) { url += ':'; url += QString::number(port).toAscii(); @@ -4412,8 +4535,6 @@ void QUrl::setHost(const QString &host) QURL_UNSETFLAG(d->stateFlags, QUrlPrivate::Validated | QUrlPrivate::Normalized | QUrlPrivate::HostCanonicalized); d->host = host; - if (d->host.contains(QLatin1Char(':'))) - d->host = QLatin1Char('[') + d->host + QLatin1Char(']'); } /*! @@ -5425,9 +5546,9 @@ QByteArray QUrl::toPercentEncoding(const QString &input, const QByteArray &exclu */ QByteArray QUrl::toPunycode(const QString &uc) { - QByteArray output; + QString output; toPunycodeHelper(uc.constData(), uc.size(), &output); - return output; + return output.toLatin1(); } /*! @@ -5528,7 +5649,7 @@ QString QUrl::fromPunycode(const QByteArray &pc) */ QString QUrl::fromAce(const QByteArray &domain) { - return qt_from_ACE(QString::fromLatin1(domain)); + return qt_ACE_do(QString::fromLatin1(domain), NormalizeAce); } /*! @@ -5545,26 +5666,8 @@ QString QUrl::fromAce(const QByteArray &domain) */ QByteArray QUrl::toAce(const QString &domain) { - // IDNA / rfc3490 describes these four delimiters used for - // separating labels in unicode international domain - // names. - QString nameprepped = qt_nameprep(domain); - int lastIdx = 0; - QByteArray result; - for (int i = 0; i < nameprepped.size(); ++i) { - ushort uc = nameprepped.at(i).unicode(); - if (uc == 0x2e || uc == 0x3002 || uc == 0xff0e || uc == 0xff61) { - if (lastIdx) - result += '.'; - toPunycodeHelper(nameprepped.constData() + lastIdx, i - lastIdx, &result); - lastIdx = i + 1; - } - } - if (lastIdx) - result += '.'; - toPunycodeHelper(nameprepped.constData() + lastIdx, nameprepped.size() - lastIdx, &result); - - return result; + QString result = qt_ACE_do(domain, ToAceOnly); + return result.toLatin1(); } /*! diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index 723f882..fcced37 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -162,6 +162,8 @@ private slots: void nameprep_testsuite(); void ace_testsuite_data(); void ace_testsuite(); + void std3violations_data(); + void std3violations(); void tldRestrictions_data(); void tldRestrictions(); void emptyQueryOrFragment(); @@ -3100,6 +3102,11 @@ void tst_QUrl::ace_testsuite_data() QTest::newRow("ascii-upper") << "FLUKE" << "fluke" << "fluke" << "fluke"; QTest::newRow("asciifolded") << QString::fromLatin1("stra\337e") << "strasse" << "." << "strasse"; + QTest::newRow("asciifolded-dotcom") << QString::fromLatin1("stra\337e.example.com") << "strasse.example.com" << "." << "strasse.example.com"; + QTest::newRow("greek-mu") << QString::fromLatin1("\265V") + <<"xn--v-lmb" + << "." + << QString::fromUtf8("\316\274v"); QTest::newRow("non-ascii-lower") << QString::fromLatin1("alqualond\353") << "xn--alqualond-34a" @@ -3132,6 +3139,9 @@ void tst_QUrl::ace_testsuite_data() QTest::newRow("idn-upper") << "XN--ALQUALOND-34A" << "xn--alqualond-34a" << QString::fromLatin1("alqualond\353") << QString::fromLatin1("alqualond\353"); + + QTest::newRow("separator-3002") << QString::fromUtf8("example\343\200\202com") + << "example.com" << "." << "example.com"; } void tst_QUrl::ace_testsuite() @@ -3142,23 +3152,85 @@ void tst_QUrl::ace_testsuite() QFETCH(QString, fromace); QFETCH(QString, unicode); - QString domain = in + canonsuffix; - QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + canonsuffix); + const char *suffix = canonsuffix; + if (toace.contains('.')) + suffix = 0; + + QString domain = in + suffix; + QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); if (fromace != ".") - QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + canonsuffix); - QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + canonsuffix); + QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); + QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); - domain = in + ".troll.No"; - QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + canonsuffix); + domain = in + (suffix ? ".troll.No" : ""); + QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); if (fromace != ".") - QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + canonsuffix); - QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + canonsuffix); + QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); + QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); - domain = in + ".troll.NO"; - QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + canonsuffix); + domain = in + (suffix ? ".troll.NO" : ""); + QCOMPARE(QString::fromLatin1(QUrl::toAce(domain)), toace + suffix); if (fromace != ".") - QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + canonsuffix); - QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + canonsuffix); + QCOMPARE(QUrl::fromAce(domain.toLatin1()), fromace + suffix); + QCOMPARE(QUrl::fromAce(QUrl::toAce(domain)), unicode + suffix); +} + +void tst_QUrl::std3violations_data() +{ + QTest::addColumn("source"); + QTest::addColumn("validUrl"); + + QTest::newRow("too-long") << "this-domain-is-far-too-long-for-its-own-good-and-should-have-been-limited-to-63-chars" << false; + QTest::newRow("dash-begin") << "-x-foo" << false; + QTest::newRow("dash-end") << "x-foo-" << false; + QTest::newRow("dash-begin-end") << "-foo-" << false; + + QTest::newRow("control") << "\033foo" << false; + QTest::newRow("bang") << "foo!" << false; + QTest::newRow("plus") << "foo+bar" << false; + QTest::newRow("dot") << "foo.bar"; + QTest::newRow("slash") << "foo/bar" << true; + QTest::newRow("colon") << "foo:80" << true; + QTest::newRow("question") << "foo?bar" << true; + QTest::newRow("at") << "foo@bar" << true; + QTest::newRow("backslash") << "foo\\bar" << false; + QTest::newRow("underline") << "foo_bar" << false; + + // these characters are transformed by NFKC to non-LDH characters + QTest::newRow("dot-like") << QString::fromUtf8("foo\342\200\244bar") << false; // U+2024 ONE DOT LEADER + QTest::newRow("slash-like") << QString::fromUtf8("foo\357\274\217bar") << false; // U+FF0F FULLWIDTH SOLIDUS + + // The following should be invalid but isn't + // the DIVISON SLASH doesn't case-fold to a slash + // is this a problem with RFC 3490? + //QTest::newRow("slash-like2") << QString::fromUtf8("foo\342\210\225bar") << false; // U+2215 DIVISION SLASH +} + +void tst_QUrl::std3violations() +{ + QFETCH(QString, source); + + extern QString qt_nameprep(const QString &); + extern bool qt_check_std3rules(const QStringRef &); + + { + QString prepped = qt_nameprep(source); + QVERIFY(!qt_check_std3rules(QStringRef(&prepped))); + } + + if (source.contains('.')) + return; // this test ends here + + QUrl url; + url.setHost(source); + QVERIFY(url.host().isEmpty()); + + QFETCH(bool, validUrl); + if (validUrl) + return; // test ends here for these cases + + url = QUrl("http://" + source + "/some/path"); + QVERIFY(!url.isValid()); } void tst_QUrl::tldRestrictions_data() -- cgit v0.12 From e3c5ca076ee15975dd2d8973b871ec0115c614fc Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 Mar 2009 21:42:04 +0100 Subject: Add qt_string_normalize to do in-place Unicode normalization. This way, we can improve QUrl parsing performance by avoiding unnecessary copies. --- src/corelib/tools/qchar.cpp | 28 +++++++++++--------------- src/corelib/tools/qstring.cpp | 46 ++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 88053d6..1558f7d 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -1421,16 +1421,15 @@ QDataStream &operator>>(QDataStream &in, QChar &chr) // --------------------------------------------------------------------------- -static QString decomposeHelper - (const QString &str, bool canonical, QChar::UnicodeVersion version) +static void decomposeHelper(QString *str, bool canonical, QChar::UnicodeVersion version, int from) { unsigned short buffer[3]; - QString s = str; + QString &s = *str; const unsigned short *utf16 = s.utf16(); const unsigned short *uc = utf16 + s.length(); - while (uc != utf16) { + while (uc != utf16 + from) { uint ucs4 = *(--uc); if (QChar(ucs4).isLowSurrogate() && uc != utf16) { ushort high = *(uc - 1); @@ -1453,8 +1452,6 @@ static QString decomposeHelper utf16 = s.utf16(); uc = utf16 + pos + length; } - - return s; } @@ -1489,17 +1486,17 @@ static ushort ligatureHelper(ushort u1, ushort u2) return 0; } -static QString composeHelper(const QString &str) +static void composeHelper(QString *str, int from) { - QString s = str; + QString &s = *str; - if (s.length() < 2) - return s; + if (s.length() - from < 2) + return; // the loop can partly ignore high Unicode as all ligatures are in the BMP int starter = 0; int lastCombining = 0; - int pos = 0; + int pos = from; while (pos < s.length()) { uint uc = s.utf16()[pos]; if (QChar(uc).isHighSurrogate() && pos < s.length()-1) { @@ -1524,16 +1521,14 @@ static QString composeHelper(const QString &str) lastCombining = combining; ++pos; } - return s; } -static QString canonicalOrderHelper - (const QString &str, QChar::UnicodeVersion version) +static void canonicalOrderHelper(QString *str, QChar::UnicodeVersion version, int from) { - QString s = str; + QString &s = *str; const int l = s.length()-1; - int pos = 0; + int pos = from; while (pos < l) { int p2 = pos+1; uint u1 = s.at(pos).unicode(); @@ -1593,7 +1588,6 @@ static QString canonicalOrderHelper ++pos; } } - return s; } int QT_FASTCALL QUnicodeTables::script(unsigned int uc) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b97ba45..99fbaa9 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6028,6 +6028,7 @@ QString QString::repeated(int times) const return result; } +void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, int from); /*! \overload \fn QString QString::normalized(NormalizationForm mode, QChar::UnicodeVersion version) const @@ -6037,42 +6038,48 @@ QString QString::repeated(int times) const */ QString QString::normalized(QString::NormalizationForm mode, QChar::UnicodeVersion version) const { + QString copy = *this; + qt_string_normalize(©, mode, version, 0); + return copy; +} + +void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, int from) +{ bool simple = true; - for (int i = 0; i < d->size; ++i) { - if (d->data[i] >= 0x80) { + const QChar *p = data->constData(); + int len = data->length(); + for (int i = from; i < len; ++i) { + if (p[i].unicode() >= 0x80) { simple = false; break; } } if (simple) - return *this; + return; - QString s = *this; + QString &s = *data; if (version != CURRENT_VERSION) { for (int i = 0; i < NumNormalizationCorrections; ++i) { const NormalizationCorrection &n = uc_normalization_corrections[i]; if (n.version > version) { + int pos = from; if (n.ucs4 > 0xffff) { ushort ucs4High = QChar::highSurrogate(n.ucs4); ushort ucs4Low = QChar::lowSurrogate(n.ucs4); ushort oldHigh = QChar::highSurrogate(n.old_mapping); ushort oldLow = QChar::lowSurrogate(n.old_mapping); - int pos = 0; - while (pos < s.d->size - 1) { - if (s.d->data[pos] == ucs4High && s.d->data[pos + 1] == ucs4Low) { - s.detach(); - s.d->data[pos] = oldHigh; - s.d->data[pos + 1] = oldLow; + while (pos < s.length() - 1) { + if (s.at(pos).unicode() == ucs4High && s.at(pos + 1).unicode() == ucs4Low) { + s[pos] = oldHigh; + s[pos + 1] = oldLow; ++pos; } ++pos; } } else { - int pos = 0; - while (pos < s.d->size) { - if (s.d->data[pos] == n.ucs4) { - s.detach(); - s.d->data[pos] = n.old_mapping; + while (pos < s.length()) { + if (s.at(pos).unicode() == n.ucs4) { + s[pos] = n.old_mapping; } ++pos; } @@ -6080,15 +6087,14 @@ QString QString::normalized(QString::NormalizationForm mode, QChar::UnicodeVersi } } } - s = decomposeHelper(s, mode < QString::NormalizationForm_KD, version); + decomposeHelper(data, mode < QString::NormalizationForm_KD, version, from); - s = canonicalOrderHelper(s, version); + canonicalOrderHelper(data, version, from); if (mode == QString::NormalizationForm_D || mode == QString::NormalizationForm_KD) - return s; - - return composeHelper(s); + return; + composeHelper(data, from); } -- cgit v0.12 From 3b545a4008fed0250d61ce1bb54af1a47fd8df92 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 Mar 2009 22:39:03 +0100 Subject: Change qt_nameprep to do in-line nameprepping This will allow to do less allocations in qt_ACE_do. --- src/corelib/io/qurl.cpp | 50 +++++++++++++++++++++----------------------- tests/auto/qurl/tst_qurl.cpp | 12 +++++------ 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index dc27dfb..d65cee2 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2336,12 +2336,12 @@ static const NameprepCaseFoldingEntry NameprepCaseFolding[] = { { 0x1D7BB, { 0x03C3, 0x0000, 0x0000, 0x0000 } } }; -static void mapToLowerCase(QString *str) +static void mapToLowerCase(QString *str, int from) { int N = sizeof(NameprepCaseFolding) / sizeof(NameprepCaseFolding[0]); QChar *d = 0; - for (int i = 0; i < str->size(); ++i) { + for (int i = from; i < str->size(); ++i) { int uc = str->at(i).unicode(); if (uc < 0x80) { if (uc <= 'Z' && uc >= 'A') { @@ -2388,11 +2388,11 @@ static bool isMappedToNothing(const QChar &ch) } -static void stripProhibitedOutput(QString *str) +static void stripProhibitedOutput(QString *str, int from) { - ushort *out = (ushort *)str->data(); + ushort *out = (ushort *)str->data() + from; const ushort *in = out; - const ushort *end = out + str->size(); + const ushort *end = (ushort *)str->data() + str->size(); while (in < end) { ushort uc = *in; if (uc < 0x80 || @@ -2903,36 +2903,34 @@ static bool isBidirectionalL(const QChar &ch) #ifdef QT_BUILD_INTERNAL // export for tst_qurl.cpp -Q_AUTOTEST_EXPORT QString qt_nameprep(const QString &); +Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from); Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QStringRef &); #else // non-test build, keep the symbols for ourselves -static QString qt_nameprep(const QString &); +static QString void qt_nameprep(QString *source, int from) static bool qt_check_std3rules(const QStringRef &); #endif -QString qt_nameprep(const QString &source) +void qt_nameprep(QString *source, int from) { - QString mapped = source; + QString &mapped = *source; - bool simple = true; - for (int i = 0; i < mapped.size(); ++i) { - ushort uc = mapped.at(i).unicode(); + for ( ; from < mapped.size(); ++from) { + ushort uc = mapped.at(from).unicode(); if (uc > 0x80) { - simple = false; break; } else if (uc >= 'A' && uc <= 'Z') { - mapped[i] = QChar(uc | 0x20); + mapped[from] = QChar(uc | 0x20); } } - if (simple) - return mapped; + if (from == mapped.size()) + return; // everything was mapped easily (lowercased, actually) // Characters commonly mapped to nothing are simply removed // (Table B.1) - QChar *out = mapped.data(); + QChar *out = mapped.data() + from; const QChar *in = out; - const QChar *e = in + mapped.size(); + const QChar *e = mapped.constData() + mapped.size(); while (in < e) { if (!isMappedToNothing(*in)) *out++ = *in; @@ -2942,30 +2940,30 @@ QString qt_nameprep(const QString &source) mapped.truncate(out - mapped.constData()); // Map to lowercase (Table B.2) - mapToLowerCase(&mapped); + mapToLowerCase(&mapped, from); // Normalize to Unicode 3.2 form KC - mapped = mapped.normalized(QString::NormalizationForm_KC, QChar::Unicode_3_2); + extern void qt_string_normalize(QString *data, QString::NormalizationForm mode, + QChar::UnicodeVersion version, int from); + qt_string_normalize(&mapped, QString::NormalizationForm_KC, QChar::Unicode_3_2, from); // Strip prohibited output - stripProhibitedOutput(&mapped); + stripProhibitedOutput(&mapped, from); // Check for valid bidirectional characters bool containsLCat = false; bool containsRandALCat = false; - for (int j = 0; j < mapped.size() && (!containsLCat || !containsRandALCat); ++j) { + for (int j = from; j < mapped.size() && (!containsLCat || !containsRandALCat); ++j) { if (isBidirectionalL(mapped.at(j))) containsLCat = true; else if (isBidirectionalRorAL(mapped.at(j))) containsRandALCat = true; } if (containsRandALCat) { - if (containsLCat || (!isBidirectionalRorAL(mapped.at(0)) + if (containsLCat || (!isBidirectionalRorAL(mapped.at(from)) || !isBidirectionalRorAL(mapped.at(mapped.size() - 1)))) mapped.clear(); } - - return mapped; } bool qt_check_std3rules(const QStringRef &source) @@ -3281,7 +3279,7 @@ static QString qt_ACE_do(const QString &domainMC, AceOperation op) // Nameprep the host. If the labels in the hostname are Punycode // encoded, we decode them immediately, then nameprep them. QString tmp = domain.mid(lastIdx, idx - lastIdx); - tmp = qt_nameprep(tmp); + qt_nameprep(&tmp, 0); if (isIdnEnabled) { toPunycodeHelper(tmp.constData(), tmp.size(), &aux); diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index fcced37..94abbb3 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -3061,7 +3061,8 @@ void tst_QUrl::nameprep_testsuite_data() #ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE -extern QString qt_nameprep(const QString &source); +extern void qt_nameprep(QString *source, int from); +extern bool qt_check_std3rules(const QStringRef &); QT_END_NAMESPACE #endif @@ -3086,7 +3087,8 @@ void tst_QUrl::nameprep_testsuite() "Investigate further", Continue); QEXPECT_FAIL("Larger test (expanding)", "Investigate further", Continue); - QCOMPARE(qt_nameprep(in), out); + qt_nameprep(&in, 0); + QCOMPARE(in, out); #endif } @@ -3210,11 +3212,9 @@ void tst_QUrl::std3violations() { QFETCH(QString, source); - extern QString qt_nameprep(const QString &); - extern bool qt_check_std3rules(const QStringRef &); - { - QString prepped = qt_nameprep(source); + QString prepped = source; + qt_nameprep(&prepped, 0); QVERIFY(!qt_check_std3rules(QStringRef(&prepped))); } -- cgit v0.12 From b01ae86c02d2ca81f30055be4641ca418ac94d9b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 19 Mar 2009 11:34:54 +0100 Subject: Improve performance in QUrl parsing by doing in-line operations. Unfortunately, I can't do it all inline because the punycode encoding and decoding requires reading the source several times. (Maybe the decoding can be done with some effort in the future) --- src/corelib/io/qurl.cpp | 63 ++++++++++++++++++++++---------------------- tests/auto/qurl/tst_qurl.cpp | 4 +-- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index d65cee2..fcae0d6 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2904,11 +2904,11 @@ static bool isBidirectionalL(const QChar &ch) #ifdef QT_BUILD_INTERNAL // export for tst_qurl.cpp Q_AUTOTEST_EXPORT void qt_nameprep(QString *source, int from); -Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QStringRef &); +Q_AUTOTEST_EXPORT bool qt_check_std3rules(const QChar *uc, int len); #else // non-test build, keep the symbols for ourselves -static QString void qt_nameprep(QString *source, int from) -static bool qt_check_std3rules(const QStringRef &); +static void qt_nameprep(QString *source, int from); +static bool qt_check_std3rules(const QChar *uc, int len); #endif void qt_nameprep(QString *source, int from) @@ -2966,14 +2966,13 @@ void qt_nameprep(QString *source, int from) } } -bool qt_check_std3rules(const QStringRef &source) +bool qt_check_std3rules(const QChar *uc, int len) { - int len = source.length(); if (len > 63) return false; for (int i = 0; i < len; ++i) { - register ushort c = source.at(i).unicode(); + register ushort c = uc[i].unicode(); if (c == '-' && (i == 0 || i == len - 1)) return false; @@ -3264,41 +3263,43 @@ static QString qt_ACE_do(const QString &domainMC, AceOperation op) simple = false; } - QString aux; - QStringRef label; + // copy the label to the destination, which also serves as our scratch area + int prevLen = result.size(); + result.resize(prevLen + idx - lastIdx); + memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar)); + if (simple) { - // fastest conversion: this is the common case (non IDN-domains) - // just memcpy from source (domain) to destination (result) + // fastest case: this is the common case (non IDN-domains) // there's no need to nameprep since everything is ASCII already - int prevLen = result.size(); - result.resize(prevLen + idx - lastIdx); - memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar)); - - label = QStringRef(&result, prevLen, result.length() - prevLen); - } else { + // so we're done + if (!qt_check_std3rules(result.constData() + prevLen, result.length() - prevLen)) + return QString(); + } else { // Nameprep the host. If the labels in the hostname are Punycode - // encoded, we decode them immediately, then nameprep them. - QString tmp = domain.mid(lastIdx, idx - lastIdx); - qt_nameprep(&tmp, 0); + // encoded, we decode them immediately. + qt_nameprep(&result, prevLen); - if (isIdnEnabled) { - toPunycodeHelper(tmp.constData(), tmp.size(), &aux); - label = QStringRef(&aux); + // Punycode encoding and decoding cannot be done in-place + // That means we need one or two temporaries + QString aceForm; + aceForm.reserve(result.size() - prevLen + 4 + 4); // "xn--" and "-xyz" + toPunycodeHelper(result.constData() + prevLen, result.size() - prevLen, &aceForm); - tmp = QUrl::fromPunycode(aux.toLatin1()); + if (isIdnEnabled) { + QString tmp = QUrl::fromPunycode(aceForm.toLatin1()); if (tmp.isEmpty()) - return QString(); - result += tmp; + return QString(); // shouldn't happen, since we've just punycode-encoded it + result.resize(prevLen + tmp.size()); + memcpy(result.data() + prevLen, tmp.constData(), tmp.size() * sizeof(QChar)); } else { - int prevLen = result.size(); - toPunycodeHelper(tmp.constData(), tmp.size(), &result); - - label = QStringRef(&result, prevLen, result.length() - prevLen); + result.resize(prevLen + aceForm.size()); + memcpy(result.data() + prevLen, aceForm.constData(), aceForm.size() * sizeof(QChar)); } + + if (!qt_check_std3rules(aceForm.constData(), aceForm.size())) + return QString(); } - if (!qt_check_std3rules(label)) - return QString(); lastIdx = idx + 1; if (lastIdx < domain.size() + 1) diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp index 94abbb3..78ea146 100644 --- a/tests/auto/qurl/tst_qurl.cpp +++ b/tests/auto/qurl/tst_qurl.cpp @@ -3062,7 +3062,7 @@ void tst_QUrl::nameprep_testsuite_data() #ifdef QT_BUILD_INTERNAL QT_BEGIN_NAMESPACE extern void qt_nameprep(QString *source, int from); -extern bool qt_check_std3rules(const QStringRef &); +extern bool qt_check_std3rules(const QChar *, int); QT_END_NAMESPACE #endif @@ -3215,7 +3215,7 @@ void tst_QUrl::std3violations() { QString prepped = source; qt_nameprep(&prepped, 0); - QVERIFY(!qt_check_std3rules(QStringRef(&prepped))); + QVERIFY(!qt_check_std3rules(prepped.constData(), prepped.length())); } if (source.contains('.')) -- cgit v0.12 From 8e6293712a9126c2740bf5628e02325d04721b2e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 19 Mar 2009 11:55:18 +0100 Subject: One more improvement in QUrl: avoid an extra lowercasing step. Since we're going to do nameprepping anyways, avoid the lowercasing step at the function entry (and thus, one extra temporary). The nameprepping step is also faster than QString::toLower for the ASCII case. --- src/corelib/io/qurl.cpp | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index fcae0d6..fe3ad82 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3178,7 +3178,7 @@ static bool qt_is_idn_enabled(const QString &domain) int len = domain.size() - idx - 1; if (user_idn_whitelist) - return user_idn_whitelist->contains(QString(tld, len)); + return user_idn_whitelist->contains(QString::fromRawData(tld, len).toLower()); int l = 0; int r = sizeof(idn_whitelist)/sizeof(const char *) - 1; @@ -3217,11 +3217,10 @@ static int nextDotDelimiter(const QString &domain, int from = 0) } enum AceOperation { ToAceOnly, NormalizeAce }; -static QString qt_ACE_do(const QString &domainMC, AceOperation op) +static QString qt_ACE_do(const QString &domain, AceOperation op) { - if (domainMC.isEmpty()) - return domainMC; - QString domain = domainMC.toLower(); + if (domain.isEmpty()) + return domain; QString result; result.reserve(domain.length()); @@ -3255,30 +3254,27 @@ static QString qt_ACE_do(const QString &domainMC, AceOperation op) } } + // copy the label to the destination, which also serves as our scratch area + // then nameprep it (in the case of "simple", it will cause a simple lowercasing) + int prevLen = result.size(); + result.resize(prevLen + idx - lastIdx); + memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar)); + qt_nameprep(&result, prevLen); + if (simple && idx > lastIdx + 4) { - // ACE form domains are simple, but we can't consider them simple + // ACE form domains contain only ASCII characters, but we can't consider them simple // is this an ACE form? static const ushort acePrefixUtf16[] = { 'x', 'n', '-', '-' }; - if (memcmp(domain.utf16() + lastIdx, acePrefixUtf16, sizeof acePrefixUtf16) == 0) + if (memcmp(result.utf16() + prevLen, acePrefixUtf16, sizeof acePrefixUtf16) == 0) simple = false; } - // copy the label to the destination, which also serves as our scratch area - int prevLen = result.size(); - result.resize(prevLen + idx - lastIdx); - memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar)); - if (simple) { // fastest case: this is the common case (non IDN-domains) - // there's no need to nameprep since everything is ASCII already // so we're done if (!qt_check_std3rules(result.constData() + prevLen, result.length() - prevLen)) return QString(); } else { - // Nameprep the host. If the labels in the hostname are Punycode - // encoded, we decode them immediately. - qt_nameprep(&result, prevLen); - // Punycode encoding and decoding cannot be done in-place // That means we need one or two temporaries QString aceForm; -- cgit v0.12 From 4c64137c6dfbfcc5a6fecbb04f5159ec491842e1 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 19 Mar 2009 14:43:41 +0100 Subject: Fix bug in locating non-lowercase TLDs: must lowercase. Use qt_nameprep after all since it's extremely fast for ASCII only and it does in-place replacement. --- src/corelib/io/qurl.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index fe3ad82..78e314e 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3174,11 +3174,15 @@ static bool qt_is_idn_enabled(const QString &domain) int idx = domain.lastIndexOf(QLatin1Char('.')); if (idx == -1) return false; - const QChar *tld = domain.constData() + idx + 1; + int len = domain.size() - idx - 1; + QString tldString(domain.constData() + idx + 1, len); + qt_nameprep(&tldString, 0); + + const QChar *tld = tldString.constData(); if (user_idn_whitelist) - return user_idn_whitelist->contains(QString::fromRawData(tld, len).toLower()); + return user_idn_whitelist->contains(tldString); int l = 0; int r = sizeof(idn_whitelist)/sizeof(const char *) - 1; -- cgit v0.12 From 52f5eee17a629fca785f79dcfc8b7bf0b23d1da2 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 19 Mar 2009 14:45:41 +0100 Subject: Minor performance improvements in nameprepping. Avoid calling functions that may have other side effects, like QString::utf16(). Use pointers whenever possible when iterating over the string. --- src/corelib/io/qurl.cpp | 43 +++++++++++++++++++++++-------------------- src/corelib/tools/qchar.cpp | 10 +++++----- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 78e314e..49c0d538 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -2913,56 +2913,59 @@ static bool qt_check_std3rules(const QChar *uc, int len); void qt_nameprep(QString *source, int from) { - QString &mapped = *source; - - for ( ; from < mapped.size(); ++from) { - ushort uc = mapped.at(from).unicode(); + QChar *src = source->data(); // causes a detach, so we're sure the only one using it + QChar *out = src + from; + const QChar *e = src + source->size(); + + for ( ; out < e; ++out) { + register ushort uc = out->unicode(); if (uc > 0x80) { break; } else if (uc >= 'A' && uc <= 'Z') { - mapped[from] = QChar(uc | 0x20); + *out = QChar(uc | 0x20); } } - if (from == mapped.size()) + if (out == e) return; // everything was mapped easily (lowercased, actually) - + int firstNonAscii = out - src; + // Characters commonly mapped to nothing are simply removed // (Table B.1) - QChar *out = mapped.data() + from; const QChar *in = out; - const QChar *e = mapped.constData() + mapped.size(); while (in < e) { if (!isMappedToNothing(*in)) *out++ = *in; ++in; } if (out != in) - mapped.truncate(out - mapped.constData()); + source->truncate(out - src); // Map to lowercase (Table B.2) - mapToLowerCase(&mapped, from); + mapToLowerCase(source, firstNonAscii); // Normalize to Unicode 3.2 form KC extern void qt_string_normalize(QString *data, QString::NormalizationForm mode, QChar::UnicodeVersion version, int from); - qt_string_normalize(&mapped, QString::NormalizationForm_KC, QChar::Unicode_3_2, from); + qt_string_normalize(source, QString::NormalizationForm_KC, QChar::Unicode_3_2, firstNonAscii); // Strip prohibited output - stripProhibitedOutput(&mapped, from); + stripProhibitedOutput(source, firstNonAscii); // Check for valid bidirectional characters bool containsLCat = false; bool containsRandALCat = false; - for (int j = from; j < mapped.size() && (!containsLCat || !containsRandALCat); ++j) { - if (isBidirectionalL(mapped.at(j))) + src = source->data(); + e = src + source->size(); + for (in = src + from; in < e && (!containsLCat || !containsRandALCat); ++in) { + if (isBidirectionalL(*in)) containsLCat = true; - else if (isBidirectionalRorAL(mapped.at(j))) + else if (isBidirectionalRorAL(*in)) containsRandALCat = true; } if (containsRandALCat) { - if (containsLCat || (!isBidirectionalRorAL(mapped.at(from)) - || !isBidirectionalRorAL(mapped.at(mapped.size() - 1)))) - mapped.clear(); + if (containsLCat || (!isBidirectionalRorAL(src[from]) + || !isBidirectionalRorAL(e[-1]))) + source->resize(from); // not allowed, clear the label } } @@ -3269,7 +3272,7 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) // ACE form domains contain only ASCII characters, but we can't consider them simple // is this an ACE form? static const ushort acePrefixUtf16[] = { 'x', 'n', '-', '-' }; - if (memcmp(result.utf16() + prevLen, acePrefixUtf16, sizeof acePrefixUtf16) == 0) + if (memcmp(result.constData() + prevLen, acePrefixUtf16, sizeof acePrefixUtf16) == 0) simple = false; } diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp index 1558f7d..458a383 100644 --- a/src/corelib/tools/qchar.cpp +++ b/src/corelib/tools/qchar.cpp @@ -1427,7 +1427,7 @@ static void decomposeHelper(QString *str, bool canonical, QChar::UnicodeVersion QString &s = *str; - const unsigned short *utf16 = s.utf16(); + const unsigned short *utf16 = reinterpret_cast(s.data()); const unsigned short *uc = utf16 + s.length(); while (uc != utf16 + from) { uint ucs4 = *(--uc); @@ -1449,7 +1449,7 @@ static void decomposeHelper(QString *str, bool canonical, QChar::UnicodeVersion s.replace(uc - utf16, ucs4 > 0x10000 ? 2 : 1, (const QChar *)d, length); // since the insert invalidates the pointers and we do decomposition recursive int pos = uc - utf16; - utf16 = s.utf16(); + utf16 = reinterpret_cast(s.data()); uc = utf16 + pos + length; } } @@ -1498,9 +1498,9 @@ static void composeHelper(QString *str, int from) int lastCombining = 0; int pos = from; while (pos < s.length()) { - uint uc = s.utf16()[pos]; + uint uc = s.at(pos).unicode(); if (QChar(uc).isHighSurrogate() && pos < s.length()-1) { - ushort low = s.utf16()[pos+1]; + ushort low = s.at(pos+1).unicode(); if (QChar(low).isLowSurrogate()) { uc = QChar::surrogateToUcs4(uc, low); ++pos; @@ -1509,7 +1509,7 @@ static void composeHelper(QString *str, int from) int combining = QChar::combiningClass(uc); if (starter == pos - 1 || combining > lastCombining) { // allowed to form ligature with S - QChar ligature = ligatureHelper(s.utf16()[starter], uc); + QChar ligature = ligatureHelper(s.at(starter).unicode(), uc); if (ligature.unicode()) { s[starter] = ligature; s.remove(pos, 1); -- cgit v0.12 From f15d4e5e02e109003b6e28cad71441f19b6ea608 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 19 Mar 2009 15:27:45 +0100 Subject: Slight performance improvement by caching the label size. --- src/corelib/io/qurl.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 49c0d538..096e37e 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3234,9 +3234,12 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) const bool isIdnEnabled = op == NormalizeAce ? qt_is_idn_enabled(domain) : false; int lastIdx = 0; + QString aceForm; // this variable is here for caching + while (1) { int idx = nextDotDelimiter(domain, lastIdx); - if (idx == lastIdx) + int labelLength = idx - lastIdx; + if (labelLength == 0) return QString(); // two delimiters in a row -- empty label not allowed // RFC 3490 says, about the ToASCII operation: @@ -3264,13 +3267,15 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) // copy the label to the destination, which also serves as our scratch area // then nameprep it (in the case of "simple", it will cause a simple lowercasing) int prevLen = result.size(); - result.resize(prevLen + idx - lastIdx); - memcpy(result.data() + prevLen, domain.constData() + lastIdx, (idx - lastIdx) * sizeof(QChar)); + result.resize(prevLen + labelLength); + memcpy(result.data() + prevLen, domain.constData() + lastIdx, labelLength * sizeof(QChar)); qt_nameprep(&result, prevLen); + labelLength = result.length() - prevLen; - if (simple && idx > lastIdx + 4) { + if (simple && labelLength > 6) { // ACE form domains contain only ASCII characters, but we can't consider them simple // is this an ACE form? + // the shortest valid ACE domain is 6 characters long (U+0080 would be 1, but it's not allowed) static const ushort acePrefixUtf16[] = { 'x', 'n', '-', '-' }; if (memcmp(result.constData() + prevLen, acePrefixUtf16, sizeof acePrefixUtf16) == 0) simple = false; @@ -3279,15 +3284,17 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) if (simple) { // fastest case: this is the common case (non IDN-domains) // so we're done - if (!qt_check_std3rules(result.constData() + prevLen, result.length() - prevLen)) + if (!qt_check_std3rules(result.constData() + prevLen, labelLength)) return QString(); } else { // Punycode encoding and decoding cannot be done in-place // That means we need one or two temporaries - QString aceForm; - aceForm.reserve(result.size() - prevLen + 4 + 4); // "xn--" and "-xyz" + register int toReserve = labelLength + 4 + 6; // "xn--" plus some extra bytes + if (toReserve > aceForm.capacity()) + aceForm.reserve(toReserve); toPunycodeHelper(result.constData() + prevLen, result.size() - prevLen, &aceForm); + // We use resize()+memcpy() here because we're overwriting the data we've copied if (isIdnEnabled) { QString tmp = QUrl::fromPunycode(aceForm.toLatin1()); if (tmp.isEmpty()) -- cgit v0.12 From ff1280178ac8739e5943fd081be5317b70717fa8 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 19 Mar 2009 15:46:32 +0100 Subject: Merge the memcpy with the lowercasing and the non-ASCII detection. This gives a 5% improvement in performance by avoiding iterating over the contents more than once. --- src/corelib/io/qurl.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 096e37e..79cd2f0 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3255,23 +3255,25 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) // 8. Verify that the number of code points is in the range 1 to 63 // inclusive. + // copy the label to the destination, which also serves as our scratch area, lowercasing it + int prevLen = result.size(); bool simple = true; - for (int i = lastIdx; i < idx; ++i) { - ushort ch = domain.at(i).unicode(); - if (ch > 0x7f) { - simple = false; - break; + result.resize(prevLen + labelLength); + { + QChar *out = result.data() + prevLen; + const QChar *in = domain.constData() + lastIdx; + const QChar *e = in + labelLength; + for (; in < e; ++in, ++out) { + register ushort uc = in->unicode(); + if (uc > 0x7f) + simple = false; + if (uc >= 'A' && uc <= 'Z') + *out = QChar(uc | 0x20); + else + *out = *in; } } - // copy the label to the destination, which also serves as our scratch area - // then nameprep it (in the case of "simple", it will cause a simple lowercasing) - int prevLen = result.size(); - result.resize(prevLen + labelLength); - memcpy(result.data() + prevLen, domain.constData() + lastIdx, labelLength * sizeof(QChar)); - qt_nameprep(&result, prevLen); - labelLength = result.length() - prevLen; - if (simple && labelLength > 6) { // ACE form domains contain only ASCII characters, but we can't consider them simple // is this an ACE form? @@ -3289,6 +3291,8 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) } else { // Punycode encoding and decoding cannot be done in-place // That means we need one or two temporaries + qt_nameprep(&result, prevLen); + labelLength = result.length() - prevLen; register int toReserve = labelLength + 4 + 6; // "xn--" plus some extra bytes if (toReserve > aceForm.capacity()) aceForm.reserve(toReserve); -- cgit v0.12 From 3c2ebb7f209035f85a35dbb05e76dd7e80238ecb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 21 Jul 2009 15:46:29 +0200 Subject: Add the information about QUrl being more strict to the changelog --- dist/changes-4.6.0 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/dist/changes-4.6.0 b/dist/changes-4.6.0 index bef2923..6c7e450 100644 --- a/dist/changes-4.6.0 +++ b/dist/changes-4.6.0 @@ -72,5 +72,18 @@ information about a particular change. QGraphicsWidget and QGraphicsProxyWidget). - QDesktopWidget on X11 no longer emits the resized(int) signal when screens - are added or removed. This was not done on other platforms. Use the + are added or removed. This was not done on other platforms. Use the screenCountChanged signal instead + +- QUrl's parser is more strict when for hostnames in URLs. QUrl now + enforces STD 3 rules: + + * each individual hostname section (between dots) must be at most + 63 ASCII characters in length; + + * only letters, digits, and the hyphen character are allowed in the + ASCII range; letters outside the ASCII range follow the normal + IDN rules + + That means QUrl no longer accepts some URLs that were invalid + before, but weren't interpreted as such. -- cgit v0.12 From 40649c420601bcc1f639fc8b337bfd7375d2b37e Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 20 Jul 2009 15:49:15 +0200 Subject: Fixed inheritence of SVG 'use' element fill attributes. Inheritence of fill attributes was implemented by copying attributes from the parent node. This approach wouldn't work if the node is referenced by a 'use' element. Now, only the fill attributes which have been explicitly set are applied on the painter while drawing. Reviewed-by: Tor Arne --- src/svg/qsvghandler.cpp | 25 +++++-------------------- src/svg/qsvgstyle.cpp | 38 ++++++++++++++++++++++++++++++-------- src/svg/qsvgstyle_p.h | 1 + 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 5f9d1dd..5857e1c 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -644,26 +644,19 @@ static void parseBrush(QSvgNode *node, QString opacity = attributes.value(QLatin1String("fill-opacity")).toString(); QString myId = someId(attributes); - QSvgFillStyle *inherited = - static_cast(node->parent()->styleProperty( - QSvgStyleProperty::FILL)); - QSvgFillStyle *prop = new QSvgFillStyle(QColor(Qt::black)); + QSvgFillStyle *prop = new QSvgFillStyle(0); //fill-rule attribute handling - Qt::FillRule f = Qt::WindingFill; if (!fillRule.isEmpty() && fillRule != QLatin1String("inherit")) { if (fillRule == QLatin1String("evenodd")) - f = Qt::OddEvenFill; - } else if (inherited) { - f = inherited->fillRule(); + prop->setFillRule(Qt::OddEvenFill); + else if (fillRule == QLatin1String("nonzero")) + prop->setFillRule(Qt::WindingFill); } //fill-opacity atttribute handling - qreal fillOpacity = 1.0; if (!opacity.isEmpty() && opacity != QLatin1String("inherit")) { - fillOpacity = qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity))); - } else if (inherited) { - fillOpacity = inherited->fillOpacity(); + prop->setFillOpacity(qMin(qreal(1.0), qMax(qreal(0.0), toDouble(opacity)))); } //fill attribute handling @@ -685,15 +678,7 @@ static void parseBrush(QSvgNode *node, } else { prop->setBrush(QBrush(Qt::NoBrush)); } - } else if (inherited) { - if (inherited->style()) { - prop->setFillStyle(inherited->style()); - } else { - prop->setBrush(inherited->qbrush()); - } } - prop->setFillOpacity(fillOpacity); - prop->setFillRule(f); node->appendStyleProperty(prop,myId); } diff --git a/src/svg/qsvgstyle.cpp b/src/svg/qsvgstyle.cpp index b693429..c3c0a68 100644 --- a/src/svg/qsvgstyle.cpp +++ b/src/svg/qsvgstyle.cpp @@ -81,12 +81,25 @@ void QSvgQualityStyle::revert(QPainter *, QSvgExtraStates &) } QSvgFillStyle::QSvgFillStyle(const QBrush &brush) - : m_fill(brush), m_style(0), m_fillRuleSet(false), m_fillRule(Qt::WindingFill), m_fillOpacitySet(false), m_fillOpacity(1.0), m_gradientResolved (true) + : m_fill(brush) + , m_style(0) + , m_fillRuleSet(false) + , m_fillRule(Qt::WindingFill) + , m_fillOpacitySet(false) + , m_fillOpacity(1.0) + , m_gradientResolved(true) + , m_fillSet(true) { } QSvgFillStyle::QSvgFillStyle(QSvgStyleProperty *style) - : m_style(style), m_fillRuleSet(false), m_fillRule(Qt::WindingFill), m_fillOpacitySet(false), m_fillOpacity(1.0), m_gradientResolved (true) + : m_style(style) + , m_fillRuleSet(false) + , m_fillRule(Qt::WindingFill) + , m_fillOpacitySet(false) + , m_fillOpacity(1.0) + , m_gradientResolved(true) + , m_fillSet(style != 0) { } @@ -105,11 +118,14 @@ void QSvgFillStyle::setFillOpacity(qreal opacity) void QSvgFillStyle::setFillStyle(QSvgStyleProperty* style) { m_style = style; + m_fillSet = true; } void QSvgFillStyle::setBrush(QBrush brush) { m_fill = brush; + m_style = 0; + m_fillSet = true; } static void recursivelySetFill(QSvgNode *node, Qt::FillRule f) @@ -136,20 +152,26 @@ void QSvgFillStyle::apply(QPainter *p, const QRectF &rect, QSvgNode *node, QSvgE recursivelySetFill(node, m_fillRule); m_fillRuleSet = false;//set it only on the first run } - p->setBrush(m_fill); + if (m_fillSet) { + if (m_style) + m_style->apply(p, rect, node, states); + else + p->setBrush(m_fill); + } if (m_fillOpacitySet) states.fillOpacity = m_fillOpacity; - if (m_style) - m_style->apply(p, rect, node, states); } void QSvgFillStyle::revert(QPainter *p, QSvgExtraStates &states) { - if (m_style) - m_style->revert(p, states); - p->setBrush(m_oldFill); if (m_fillOpacitySet) states.fillOpacity = m_oldOpacity; + if (m_fillSet) { + if (m_style) + m_style->revert(p, states); + else + p->setBrush(m_oldFill); + } } QSvgViewportFillStyle::QSvgViewportFillStyle(const QBrush &brush) diff --git a/src/svg/qsvgstyle_p.h b/src/svg/qsvgstyle_p.h index ac5e109..70ecf5b 100644 --- a/src/svg/qsvgstyle_p.h +++ b/src/svg/qsvgstyle_p.h @@ -281,6 +281,7 @@ private: qreal m_oldOpacity; QString m_gradientId; bool m_gradientResolved; + bool m_fillSet; }; class QSvgViewportFillStyle : public QSvgStyleProperty -- cgit v0.12 From 8c97cd7a91e99a2665e871efe1bf577e33eaff3a Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 20 Jul 2009 12:41:47 +0200 Subject: Fixed GL2 engine shader manager to work with more than one context. I added a QGLContextResource class which can be used internally in Qt for sharing resources between contexts. The QGLContextResource is a hash map where the context is used as 'key', and the resource is the 'value'. All the sharing contexts point to the same resource, and the resource is automatically deleted when it is not referenced any more. Now, the shader manager uses the QGLContextResource class. I also added a pointer to a struct in the QGLContextPrivate class. The struct is shared between all the sharing contexts and is deleted automatically. Currently, the struct only contains the resolved OpenGL function pointers. The shared context register code has been simplified. Reviewed-by: Tom --- .../gl2paintengineex/qglengineshadermanager.cpp | 22 +++ .../gl2paintengineex/qglengineshadermanager_p.h | 3 + .../gl2paintengineex/qpaintengineex_opengl2.cpp | 11 +- src/opengl/qgl.cpp | 159 ++++++++++++++++++++- src/opengl/qgl.h | 1 + src/opengl/qgl_p.h | 95 ++++++------ 6 files changed, 228 insertions(+), 63 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 27636f4..d7c91b8 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -49,6 +49,28 @@ QT_BEGIN_NAMESPACE +static void QGLEngineShaderManager_free(void *ptr) +{ + delete reinterpret_cast(ptr); +} + +Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_shader_managers, (QGLEngineShaderManager_free)) + +QGLEngineShaderManager *QGLEngineShaderManager::managerForContext(const QGLContext *context) +{ + QGLEngineShaderManager *p = reinterpret_cast(qt_shader_managers()->value(context)); + if (!p) { + QGLContext *oldContext = const_cast(QGLContext::currentContext()); + if (oldContext != context) + const_cast(context)->makeCurrent(); + p = new QGLEngineShaderManager(const_cast(context)); + qt_shader_managers()->insert(context, p); + if (oldContext && oldContext != context) + oldContext->makeCurrent(); + } + return p; +} + const char* QGLEngineShaderManager::qglEngineShaderSourceCode[] = { 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 442edfe..99711bd40 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -220,6 +220,7 @@ #include #include #include +#include QT_BEGIN_HEADER @@ -314,6 +315,8 @@ public: QGLShaderProgram* simpleProgram(); // Used to draw into e.g. stencil buffers QGLShaderProgram* blitProgram(); // Used to blit a texture into the framebuffer + static QGLEngineShaderManager *managerForContext(const QGLContext *context); + enum ShaderName { MainVertexShader, MainWithTexCoordsVertexShader, diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 2bfbf4a..9b0321d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -266,10 +266,6 @@ extern QImage qt_imageForBrush(int brushStyle, bool invert); QGL2PaintEngineExPrivate::~QGL2PaintEngineExPrivate() { - if (shaderManager) { - delete shaderManager; - shaderManager = 0; - } } void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id) @@ -1209,11 +1205,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) qt_resolve_version_2_0_functions(d->ctx); #endif - if (d->shaderManager) { - d->shaderManager->setDirty(); - } else { - d->shaderManager = new QGLEngineShaderManager(d->ctx); - } + d->shaderManager = QGLEngineShaderManager::managerForContext(d->ctx); + d->shaderManager->setDirty(); glViewport(0, 0, d->width, d->height); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 0169ea2..f51b271 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3363,8 +3363,13 @@ bool QGLWidget::event(QEvent *e) #elif defined(Q_WS_WIN) if (e->type() == QEvent::ParentChange) { QGLContext *newContext = new QGLContext(d->glcx->requestedFormat(), this); - qgl_share_reg()->replaceShare(d->glcx, newContext); + QList shares = qgl_share_reg()->shares(d->glcx); setContext(newContext); + for (int i = 0; i < shares.size(); ++i) { + if (newContext != shares.at(i)) + qgl_share_reg()->addShare(newContext, shares.at(i)); + } + // the overlay needs to be recreated as well delete d->olcx; if (isValid() && context()->format().hasOverlay()) { @@ -4612,4 +4617,156 @@ bool QGLDrawable::autoFillBackground() const return false; } + +bool QGLShareRegister::checkSharing(const QGLContext *context1, const QGLContext *context2) { + bool sharing = (context1 && context2 && context1->d_ptr->groupResources == context2->d_ptr->groupResources); + return sharing; +} + +void QGLShareRegister::addShare(const QGLContext *context, const QGLContext *share) { + Q_ASSERT(context && share); + if (context->d_ptr->groupResources == share->d_ptr->groupResources) + return; + + // Make sure 'context' is not already shared with another group of contexts. + Q_ASSERT(reg.find(context->d_ptr->groupResources) == reg.end()); + Q_ASSERT(context->d_ptr->groupResources->refs == 1); + + // Free 'context' group resources and make it use the same resources as 'share'. + delete context->d_ptr->groupResources; + context->d_ptr->groupResources = share->d_ptr->groupResources; + context->d_ptr->groupResources->refs.ref(); + + // Maintain a list of all the contexts in each group of sharing contexts. + SharingHash::iterator it = reg.find(share->d_ptr->groupResources); + if (it == reg.end()) + it = reg.insert(share->d_ptr->groupResources, ContextList() << share); + it.value() << context; +} + +QList QGLShareRegister::shares(const QGLContext *context) { + SharingHash::const_iterator it = reg.find(context->d_ptr->groupResources); + if (it == reg.end()) + return ContextList(); + return it.value(); +} + +void QGLShareRegister::removeShare(const QGLContext *context) { + SharingHash::iterator it = reg.find(context->d_ptr->groupResources); + if (it == reg.end()) + return; + + int count = it.value().removeAll(context); + Q_ASSERT(count == 1); + + Q_ASSERT(it.value().size() != 0); + if (it.value().size() == 1) + reg.erase(it); +} + +QGLContextResource::QGLContextResource(FreeFunc f, QObject *parent) + : QObject(parent), free(f) +{ + connect(QGLSignalProxy::instance(), SIGNAL(aboutToDestroyContext(const QGLContext *)), this, SLOT(aboutToDestroyContext(const QGLContext *))); +} + +QGLContextResource::~QGLContextResource() +{ + while (!m_resources.empty()) + remove(m_resources.begin().key()); +} + +void QGLContextResource::insert(const QGLContext *key, void *value) +{ + QList shares = qgl_share_reg()->shares(key); + if (shares.size() == 0) + shares.append(key); + void *oldValue = 0; + for (int i = 0; i < shares.size(); ++i) { + ResourceHash::iterator it = m_resources.find(shares.at(i)); + if (it != m_resources.end()) { + Q_ASSERT(oldValue == 0 || oldValue == it.value()); + oldValue = it.value(); + it.value() = value; + } else { + m_resources.insert(shares.at(i), value); + } + } + if (oldValue != 0 && oldValue != value) { + QGLContext *oldContext = const_cast(QGLContext::currentContext()); + if (oldContext != key) + const_cast(key)->makeCurrent(); + free(oldValue); + if (oldContext && oldContext != key) + oldContext->makeCurrent(); + } +} + +void *QGLContextResource::value(const QGLContext *key) +{ + ResourceHash::const_iterator it = m_resources.find(key); + // Check if there is a value associated with 'key'. + if (it != m_resources.end()) + return it.value(); + // Check if there is a value associated with sharing contexts. + QList shares = qgl_share_reg()->shares(key); + for (int i = 0; i < shares.size() && it == m_resources.end(); ++i) + it = m_resources.find(shares.at(i)); + if (it == m_resources.end()) + return 0; // Didn't find anything. + + // Found something! Share this info with all the buddies. + for (int i = 0; i < shares.size(); ++i) + m_resources.insert(shares.at(i), it.value()); + return it.value(); +} + +void QGLContextResource::remove(const QGLContext *key) +{ + QList shares = qgl_share_reg()->shares(key); + if (shares.size() == 0) + shares.append(key); + void *oldValue = 0; + for (int i = 0; i < shares.size(); ++i) { + ResourceHash::iterator it = m_resources.find(shares.at(i)); + if (it != m_resources.end()) { + Q_ASSERT(oldValue == 0 || oldValue == it.value()); + oldValue = it.value(); + m_resources.erase(it); + } + } + if (oldValue != 0) { + QGLContext *oldContext = const_cast(QGLContext::currentContext()); + if (oldContext != key) + const_cast(key)->makeCurrent(); + free(oldValue); + if (oldContext && oldContext != key) + oldContext->makeCurrent(); + } +} + +void QGLContextResource::aboutToDestroyContext(const QGLContext *key) +{ + ResourceHash::iterator it = m_resources.find(key); + if (it == m_resources.end()) + return; + + QList shares = qgl_share_reg()->shares(key); + if (shares.size() > 1) { + Q_ASSERT(key->isSharing()); + // At least one of the shared contexts must stay in the cache. + // Otherwise, the value pointer is lost. + for (int i = 0; i < 2/*shares.size()*/; ++i) + m_resources.insert(shares.at(i), it.value()); + } else { + QGLContext *oldContext = const_cast(QGLContext::currentContext()); + if (oldContext != key) + const_cast(key)->makeCurrent(); + free(it.value()); + if (oldContext && oldContext != key) + oldContext->makeCurrent(); + } + m_resources.erase(it); +} + QT_END_NAMESPACE diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 86555da..31b9543 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -364,6 +364,7 @@ private: friend class QGLPixmapData; friend class QGLPixmapFilterBase; friend class QGLTextureGlyphCache; + friend class QGLShareRegister; friend QGLFormat::OpenGLVersionFlags QGLFormat::openGLVersionFlags(); #ifdef Q_WS_MAC public: diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index ac19d64..fda0257 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -196,12 +196,19 @@ public: #endif }; +struct QGLContextGroupResources +{ + QGLContextGroupResources() : refs(1) { } + QGLExtensionFuncs extensionFuncs; + QAtomicInt refs; +}; + class QGLContextPrivate { Q_DECLARE_PUBLIC(QGLContext) public: - explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {} - ~QGLContextPrivate() {} + explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {groupResources = new QGLContextGroupResources;} + ~QGLContextPrivate() {if (!groupResources->refs.deref()) delete groupResources;} GLuint bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key, bool clean = false); GLuint bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean); @@ -257,14 +264,14 @@ public: QGLContext *q_ptr; QGLFormat::OpenGLVersionFlags version_flags; - QGLExtensionFuncs extensionFuncs; + QGLContextGroupResources *groupResources; GLint max_texture_size; GLuint current_fbo; QPaintEngine *active_engine; #ifdef Q_WS_WIN - static inline QGLExtensionFuncs& qt_get_extension_funcs(const QGLContext *ctx) { return ctx->d_ptr->extensionFuncs; } + static inline QGLExtensionFuncs& qt_get_extension_funcs(const QGLContext *ctx) { return ctx->d_ptr->groupResources->extensionFuncs; } #endif #if defined(Q_WS_X11) || defined(Q_WS_MAC) || defined(Q_WS_QWS) @@ -371,62 +378,21 @@ struct QGLThreadContext { }; extern QThreadStorage qgl_context_storage; -typedef QMultiHash QGLSharingHash; class QGLShareRegister { public: QGLShareRegister() {} ~QGLShareRegister() { reg.clear(); } - bool checkSharing(const QGLContext *context1, const QGLContext *context2, const QGLContext * skip=0) { - if (context1 == context2) - return true; - QList shares = reg.values(context1); - for (int k=0; k shares(const QGLContext *context) { - return reg.values(context); - } - + bool checkSharing(const QGLContext *context1, const QGLContext *context2); + void addShare(const QGLContext *context, const QGLContext *share); + QList shares(const QGLContext *context); + void removeShare(const QGLContext *context); private: - QGLSharingHash reg; + // Use a context's 'groupResources' pointer to uniquely identify a group. + typedef QList ContextList; + typedef QHash SharingHash; + SharingHash reg; }; extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg(); @@ -464,6 +430,29 @@ inline GLenum qt_gl_preferredTextureTarget() #endif } +// One resource per group of shared contexts. +class QGLContextResource : public QObject +{ + Q_OBJECT +public: + typedef void (*FreeFunc)(void *); + QGLContextResource(FreeFunc f, QObject *parent = 0); + ~QGLContextResource(); + // Set resource 'value' for 'key' and all its shared contexts. + void insert(const QGLContext *key, void *value); + // Return resource for 'key' or a shared context. + void *value(const QGLContext *key); + // Free resource for 'key' and all its shared contexts. + void remove(const QGLContext *key); +private slots: + // Remove entry 'key' from cache and delete resource if there are no shared contexts. + void aboutToDestroyContext(const QGLContext *key); +private: + typedef QHash ResourceHash; + ResourceHash m_resources; + FreeFunc free; +}; + QT_END_NAMESPACE #endif // QGL_P_H -- cgit v0.12 From 6aeb2f208f2978f1445ba2ac0043491db75359aa Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Tue, 30 Jun 2009 10:54:59 +0200 Subject: Used QGLContextResource for the gradient cache in the GL2 paint engine. Reviewed-by: Tom --- src/opengl/gl2paintengineex/qglgradientcache.cpp | 29 +++++++++++++++++----- src/opengl/gl2paintengineex/qglgradientcache_p.h | 27 ++++++-------------- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 5 +--- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/opengl/gl2paintengineex/qglgradientcache.cpp b/src/opengl/gl2paintengineex/qglgradientcache.cpp index 8c6b4f0..7c54bb9 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache.cpp +++ b/src/opengl/gl2paintengineex/qglgradientcache.cpp @@ -46,6 +46,28 @@ QT_BEGIN_NAMESPACE +static void QGL2GradientCache_free(void *ptr) +{ + delete reinterpret_cast(ptr); +} + +Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_gradient_caches, (QGL2GradientCache_free)) + +QGL2GradientCache *QGL2GradientCache::cacheForContext(const QGLContext *context) +{ + QGL2GradientCache *p = reinterpret_cast(qt_gradient_caches()->value(context)); + if (!p) { + QGLContext *oldContext = const_cast(QGLContext::currentContext()); + if (oldContext != context) + const_cast(context)->makeCurrent(); + p = new QGL2GradientCache; + qt_gradient_caches()->insert(context, p); + if (oldContext && oldContext != context) + oldContext->makeCurrent(); + } + return p; +} + void QGL2GradientCache::cleanCache() { QGLGradientColorTableHash::const_iterator it = cache.constBegin(); for (; it != cache.constEnd(); ++it) { @@ -55,13 +77,8 @@ void QGL2GradientCache::cleanCache() { cache.clear(); } -GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity, const QGLContext *ctx) +GLuint QGL2GradientCache::getBuffer(const QGradient &gradient, qreal opacity) { - if (buffer_ctx && !qgl_share_reg()->checkSharing(buffer_ctx, ctx)) - cleanCache(); - - buffer_ctx = ctx; - quint64 hash_val = 0; QGradientStops stops = gradient.stops(); diff --git a/src/opengl/gl2paintengineex/qglgradientcache_p.h b/src/opengl/gl2paintengineex/qglgradientcache_p.h index 55c7b65..ba698bc 100644 --- a/src/opengl/gl2paintengineex/qglgradientcache_p.h +++ b/src/opengl/gl2paintengineex/qglgradientcache_p.h @@ -53,12 +53,12 @@ #include #include #include +#include QT_BEGIN_NAMESPACE -class QGL2GradientCache : public QObject +class QGL2GradientCache { - Q_OBJECT struct CacheInfo { inline CacheInfo(QGradientStops s, qreal op, QGradient::InterpolationMode mode) : @@ -73,16 +73,12 @@ class QGL2GradientCache : public QObject typedef QMultiHash QGLGradientColorTableHash; public: - QGL2GradientCache() : QObject(), buffer_ctx(0) - { -/* - connect(QGLSignalProxy::instance(), - SIGNAL(aboutToDestroyContext(const QGLContext *)), - SLOT(cleanupGLContextRefs(const QGLContext *))); -*/ - } + static QGL2GradientCache *cacheForContext(const QGLContext *context); + + QGL2GradientCache() { } + ~QGL2GradientCache() {cleanCache();} - GLuint getBuffer(const QGradient &gradient, qreal opacity, const QGLContext *ctx); + GLuint getBuffer(const QGradient &gradient, qreal opacity); inline int paletteSize() const { return 1024; } protected: @@ -95,15 +91,6 @@ protected: void cleanCache(); QGLGradientColorTableHash cache; - const QGLContext *buffer_ctx; - -public slots: - void cleanupGLContextRefs(const QGLContext *context) { - if (context == buffer_ctx) { - cleanCache(); - buffer_ctx = 0; - } - } }; QT_END_NAMESPACE diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 9b0321d..939cd0d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -334,9 +334,6 @@ void QGL2PaintEngineExPrivate::useSimpleShader() } } - -Q_GLOBAL_STATIC(QGL2GradientCache, qt_opengl_gradient_cache) - void QGL2PaintEngineExPrivate::updateBrushTexture() { // qDebug("QGL2PaintEngineExPrivate::updateBrushTexture()"); @@ -357,7 +354,7 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() // We apply global opacity in the fragment shaders, so we always pass 1.0 // for opacity to the cache. - GLuint texId = qt_opengl_gradient_cache()->getBuffer(*g, 1.0, ctx); + GLuint texId = QGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true); -- cgit v0.12 From fdacdd4335f80aea8385b5cfb745df9eda99ece6 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Thu, 2 Jul 2009 13:16:45 +0200 Subject: Fixed crash in the GL2 engine's texture glyph cache. Reviewed-by: Tom --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 939cd0d..3007b4c 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -115,6 +115,7 @@ public Q_SLOTS: glDeleteFramebuffers(1, &m_fbo); if (m_width || m_height) glDeleteTextures(1, &m_texture); + ctx = 0; } else { // since the context holding the texture is shared, and // about to be destroyed, we have to transfer ownership @@ -151,10 +152,17 @@ QGLTextureGlyphCache::QGLTextureGlyphCache(QGLContext *context, QFontEngineGlyph QGLTextureGlyphCache::~QGLTextureGlyphCache() { - glDeleteFramebuffers(1, &m_fbo); - - if (m_width || m_height) - glDeleteTextures(1, &m_texture); + if (ctx) { + QGLContext *oldContext = const_cast(QGLContext::currentContext()); + if (oldContext != ctx) + ctx->makeCurrent(); + glDeleteFramebuffers(1, &m_fbo); + + if (m_width || m_height) + glDeleteTextures(1, &m_texture); + if (oldContext && oldContext != ctx) + oldContext->makeCurrent(); + } } void QGLTextureGlyphCache::createTextureData(int width, int height) -- cgit v0.12 From 492a32d53f31a0617f0aac45aad3e8a5c9e3f5ed Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Mon, 6 Jul 2009 11:17:39 +0200 Subject: Corrected the value of GL_MAX_SAMPLES_EXT. Reviewed-by: Tom --- src/opengl/qglextensions_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 3bb42c8..4f15197 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -535,7 +535,7 @@ struct QGLExtensionFuncs #endif #ifndef GL_MAX_SAMPLES_EXT -#define GL_MAX_SAMPLES_EXT 0x8D5 +#define GL_MAX_SAMPLES_EXT 0x8D57 #endif #ifndef GL_DRAW_FRAMEBUFFER_EXT -- cgit v0.12 From 89038235d08a039145792e545c3efedfd3d93323 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Tue, 21 Jul 2009 14:39:30 +0200 Subject: Fixed gradient bug in the GL2 paint engine. Texture filtering was set before binding the texture, so the gradient spread was not set correctly. Reviewed-by: Tom --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 3007b4c..fa6b966 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -364,15 +364,15 @@ void QGL2PaintEngineExPrivate::updateBrushTexture() // for opacity to the cache. GLuint texId = QGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0); + glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); + glBindTexture(GL_TEXTURE_2D, texId); + if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient) updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, true); else if (g->spread() == QGradient::ReflectSpread) updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT_IBM, true); else updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, true); - - glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); - glBindTexture(GL_TEXTURE_2D, texId); } else if (style == Qt::TexturePattern) { const QPixmap& texPixmap = currentBrush->texture(); -- cgit v0.12 From 704bfb1c67dd20d465f56bb1704500cd044f9494 Mon Sep 17 00:00:00 2001 From: Kim Motoyoshi Kalland Date: Fri, 17 Jul 2009 14:36:47 +0200 Subject: Fixed opacity bug in the GL2 paint engine. When premultiplying a color with the opacity, the color's alpha channel was not set correcly. Reviewed-by: Tom --- src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index fa6b966..7e8a281 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -299,6 +299,7 @@ void QGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMod QColor QGL2PaintEngineExPrivate::premultiplyColor(QColor c, GLfloat opacity) { qreal alpha = c.alphaF() * opacity; + c.setAlphaF(alpha); c.setRedF(c.redF() * alpha); c.setGreenF(c.greenF() * alpha); c.setBlueF(c.blueF() * alpha); -- cgit v0.12 From 134396b0100c33e271561edc8f5ec141fe0d611e Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jul 2009 16:01:56 +0200 Subject: Doc: document reimplementations of internal functions as internal. --- src/gui/embedded/qscreenproxy_qws.cpp | 8 ++++---- src/qt3support/dialogs/q3tabdialog.cpp | 2 +- src/qt3support/itemviews/q3table.cpp | 2 +- src/qt3support/widgets/q3scrollview.cpp | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/gui/embedded/qscreenproxy_qws.cpp b/src/gui/embedded/qscreenproxy_qws.cpp index ade16ca..3d7451b 100644 --- a/src/gui/embedded/qscreenproxy_qws.cpp +++ b/src/gui/embedded/qscreenproxy_qws.cpp @@ -537,7 +537,7 @@ int QProxyScreen::transformOrientation() const } /*! -\reimp +\internal */ int QProxyScreen::memoryNeeded(const QString &str) { @@ -548,7 +548,7 @@ int QProxyScreen::memoryNeeded(const QString &str) } /*! -\reimp +\internal */ int QProxyScreen::sharedRamSize(void *ptr) { @@ -559,7 +559,7 @@ int QProxyScreen::sharedRamSize(void *ptr) } /*! -\reimp +\internal */ void QProxyScreen::haltUpdates() { @@ -568,7 +568,7 @@ void QProxyScreen::haltUpdates() } /*! -\reimp +\internal */ void QProxyScreen::resumeUpdates() { diff --git a/src/qt3support/dialogs/q3tabdialog.cpp b/src/qt3support/dialogs/q3tabdialog.cpp index 50dbd48..a65affc 100644 --- a/src/qt3support/dialogs/q3tabdialog.cpp +++ b/src/qt3support/dialogs/q3tabdialog.cpp @@ -1038,7 +1038,7 @@ QString Q3TabDialog::tabLabel(QWidget * w) } -/*! \reimp +/*! \internal */ void Q3TabDialog::styleChange(QStyle& s) { diff --git a/src/qt3support/itemviews/q3table.cpp b/src/qt3support/itemviews/q3table.cpp index 11c70b4..6c3e90c 100644 --- a/src/qt3support/itemviews/q3table.cpp +++ b/src/qt3support/itemviews/q3table.cpp @@ -6411,7 +6411,7 @@ void Q3Table::startDrag() #endif -/*! \reimp */ +/*! \internal */ void Q3Table::windowActivationChange(bool oldActive) { if (oldActive && autoScrollTimer) diff --git a/src/qt3support/widgets/q3scrollview.cpp b/src/qt3support/widgets/q3scrollview.cpp index cea385a..95e2117 100644 --- a/src/qt3support/widgets/q3scrollview.cpp +++ b/src/qt3support/widgets/q3scrollview.cpp @@ -669,7 +669,7 @@ bool Q3ScrollView::isVerticalSliderPressed() } /*! - \reimp + \internal */ void Q3ScrollView::styleChange(QStyle& old) { @@ -679,7 +679,7 @@ void Q3ScrollView::styleChange(QStyle& old) } /*! - \reimp + \internal */ void Q3ScrollView::fontChange(const QFont &old) { -- cgit v0.12 From 5fd5f9da3b4b433d43a4fe5c6d1a07cbc4712128 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jul 2009 16:33:25 +0200 Subject: Silence compiler warnings on shadowing of member functions. --- src/corelib/tools/qcontiguouscache.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h index 7d52f1e..0020d22 100644 --- a/src/corelib/tools/qcontiguouscache.h +++ b/src/corelib/tools/qcontiguouscache.h @@ -166,8 +166,8 @@ void QContiguousCache::detach_helper() T *dest = x.d->array + x.d->start; T *src = d->array + d->start; - int count = x.d->count; - while (count--) { + int oldcount = x.d->count; + while (oldcount--) { if (QTypeInfo::isComplex) { new (dest) T(*src); } else { @@ -200,8 +200,8 @@ void QContiguousCache::setCapacity(int asize) x.d->start = x.d->offset % x.d->alloc; T *dest = x.d->array + (x.d->start + x.d->count-1) % x.d->alloc; T *src = d->array + (d->start + d->count-1) % d->alloc; - int count = x.d->count; - while (count--) { + int oldcount = x.d->count; + while (oldcount--) { if (QTypeInfo::isComplex) { new (dest) T(*src); } else { @@ -224,10 +224,10 @@ void QContiguousCache::clear() { if (d->ref == 1) { if (QTypeInfo::isComplex) { - int count = d->count; + int oldcount = d->count; T * i = d->array + d->start; T * e = d->array + d->alloc; - while (count--) { + while (oldcount--) { i->~T(); i++; if (i == e) @@ -254,11 +254,11 @@ inline QContiguousCacheData *QContiguousCache::malloc(int aalloc) } template -QContiguousCache::QContiguousCache(int capacity) +QContiguousCache::QContiguousCache(int cap) { - p = malloc(capacity); + p = malloc(cap); d->ref = 1; - d->alloc = capacity; + d->alloc = cap; d->count = d->start = d->offset = 0; d->sharable = true; } @@ -295,10 +295,10 @@ template void QContiguousCache::free(Data *x) { if (QTypeInfo::isComplex) { - int count = d->count; + int oldcount = d->count; T * i = d->array + d->start; T * e = d->array + d->alloc; - while (count--) { + while (oldcount--) { i->~T(); i++; if (i == e) -- cgit v0.12 From a033edc2517a0a108fc3c23190557a22465c96fb Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jul 2009 18:06:13 +0200 Subject: Doc: make potentially incorrect overloads obsolete. Also add additional overload. Reviewed-by: Andreas --- src/gui/graphicsview/qgraphicsscene.cpp | 23 ++++++++++++++++++++++- src/gui/graphicsview/qgraphicsscene.h | 5 +++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 38e5938..21fe49a 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1926,21 +1926,42 @@ QPainterPath QGraphicsScene::selectionArea() const } /*! + \since 4.6 + Sets the selection area to \a path. All items within this area are immediately selected, and all items outside are unselected. You can get the list of all selected items by calling selectedItems(). + \a deviceTransform is the transformation that applies to the view, and needs to + be provided if the scene contains items that ignore transformations. + For an item to be selected, it must be marked as \e selectable (QGraphicsItem::ItemIsSelectable). \sa clearSelection(), selectionArea() */ +void QGraphicsScene::setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform) +{ + setSelectionArea(path, Qt::IntersectsItemShape, deviceTransform); +} + +/*! + \obsolete + \overload + + Sets the selection area to \a path. + + This function is deprecated and leads to incorrect results if the scene + contains items that ignore transformations. Use the overload that takes + a QTransform instead. +*/ void QGraphicsScene::setSelectionArea(const QPainterPath &path) { - setSelectionArea(path, Qt::IntersectsItemShape); + setSelectionArea(path, Qt::IntersectsItemShape, QTransform()); } /*! + \obsolete \overload \since 4.3 diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index d790f90..c0c6e75 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -182,8 +182,9 @@ public: QList selectedItems() const; QPainterPath selectionArea() const; - void setSelectionArea(const QPainterPath &path); - void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode); + void setSelectionArea(const QPainterPath &path); // ### obsolete + void setSelectionArea(const QPainterPath &path, const QTransform &deviceTransform); + void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode); // ### obsolete void setSelectionArea(const QPainterPath &path, Qt::ItemSelectionMode mode, const QTransform &deviceTransform); QGraphicsItemGroup *createItemGroup(const QList &items); -- cgit v0.12 From 685e98b24ce27fee3085e9f2359494960a7952ff Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Tue, 21 Jul 2009 18:27:04 +0200 Subject: Doc: documentation for boolean properties should say what happens when the property is set, not what doesn't happen when the property is not set. --- src/gui/graphicsview/qgraphicsscene.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 21fe49a..b017022 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -2694,15 +2694,17 @@ void QGraphicsScene::clearFocus() /*! \property QGraphicsScene::stickyFocus - \brief whether or not clicking the scene will clear focus + \brief whether clicking into the scene background will clear focus \since 4.6 - If this property is false (the default), then clicking on the scene - background or on an item that does not accept focus, will clear - focus. Otherwise, focus will remain unchanged. + In a QGraphicsScene with stickyFocus set to true, focus will remain + unchanged when the user clicks into the scene background or on an item + that does not accept focus. Otherwise, focus will be cleared. - The focus change happens in response to a mouse press. You can reimplement + By default, this property is false. + + Focus changes in response to a mouse press. You can reimplement mousePressEvent() in a subclass of QGraphicsScene to toggle this property based on where the user has clicked. -- cgit v0.12 From 150470d47d6871d163226de19f27c8b11a0131cf Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Tue, 21 Jul 2009 16:00:32 -0700 Subject: Make sure DFB version macros are defined Reviewed-by: Donald --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h index 9d1e670..090a685 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.h @@ -44,6 +44,7 @@ #include #include +#include QT_BEGIN_HEADER -- cgit v0.12 From b9b6258729585803e00b71280e175618b6bd50c2 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 22 Jul 2009 09:28:35 +1000 Subject: Fixed valgrind warnings related to sigaction from every testcase. Whoops, don't do sigaction for (nonexistent) signal 0. --- src/testlib/qtestcase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 5de37dc..1d0bbcf 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1480,7 +1480,7 @@ FatalSignalHandler::~FatalSignalHandler() struct sigaction oldact; - for (int i = 0; i < 32; ++i) { + for (int i = 1; i < 32; ++i) { if (!sigismember(&handledSignals, i)) continue; sigaction(i, &act, &oldact); -- cgit v0.12 From 5be62fbd822206c625cab4892ab485923dc79a00 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 22 Jul 2009 10:19:34 +1000 Subject: Fixed compile with -qtnamespace and MSVC. When an extern function is declared in the scope of another function, MSVC sometimes ignores the enclosing namespace {}. --- src/gui/kernel/qapplication.cpp | 10 ++++++---- src/opengl/qpixmapdata_gl.cpp | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index b168188..3453408 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -819,6 +819,12 @@ QApplication::QApplication(Display *dpy, int &argc, char **argv, #endif // Q_WS_X11 extern void qInitDrawhelperAsm(); +extern int qRegisterGuiVariant(); +extern int qUnregisterGuiVariant(); +#ifndef QT_NO_STATEMACHINE +extern int qRegisterGuiStateMachine(); +extern int qUnregisterGuiStateMachine(); +#endif /*! \fn void QApplicationPrivate::initialize() @@ -832,11 +838,9 @@ void QApplicationPrivate::initialize() if (qt_appType != QApplication::Tty) (void) QApplication::style(); // trigger creation of application style // trigger registering of QVariant's GUI types - extern int qRegisterGuiVariant(); qRegisterGuiVariant(); #ifndef QT_NO_STATEMACHINE // trigger registering of QStateMachine's GUI types - extern int qRegisterGuiStateMachine(); qRegisterGuiStateMachine(); #endif @@ -1060,11 +1064,9 @@ QApplication::~QApplication() #ifndef QT_NO_STATEMACHINE // trigger unregistering of QStateMachine's GUI types - extern int qUnregisterGuiStateMachine(); qUnregisterGuiStateMachine(); #endif // trigger unregistering of QVariant's GUI types - extern int qUnregisterGuiVariant(); qUnregisterGuiVariant(); } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index f0c7e20..fe3bb0c 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -303,6 +303,8 @@ QImage QGLPixmapData::fillImage(const QColor &color) const return img; } +extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); + QImage QGLPixmapData::toImage() const { if (!isValid()) @@ -319,7 +321,6 @@ QImage QGLPixmapData::toImage() const } QGLShareContextScope ctx(qt_gl_share_widget()->context()); - extern QImage qt_gl_read_texture(const QSize &size, bool alpha_format, bool include_alpha); glBindTexture(GL_TEXTURE_2D, m_textureId); return qt_gl_read_texture(QSize(w, h), true, true); } -- cgit v0.12 From d0a4c6ab4d801b8b02638324505b29dbaa822f5c Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Wed, 22 Jul 2009 13:49:39 +1000 Subject: Make "-graphicssystem openvg" select OpenVG as default graphics system Reviewed-by: Lincoln Ramsay --- configure | 9 +++++++++ src/gui/painting/qgraphicssystemfactory.cpp | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/configure b/configure index f7e8005..60222a7 100755 --- a/configure +++ b/configure @@ -1166,6 +1166,8 @@ while [ "$#" -gt 0 ]; do else if [ "$VAL" = "opengl" ]; then CFG_GRAPHICS_SYSTEM="opengl" + elif [ "$VAL" = "openvg" ]; then + CFG_GRAPHICS_SYSTEM="openvg" elif [ "$VAL" = "raster" ]; then CFG_GRAPHICS_SYSTEM="raster" else @@ -5612,6 +5614,12 @@ if [ "$CFG_OPENVG" != "no" ]; then fi fi +# if openvg is disabled and the user specified graphicssystem vg, disable it... +if [ "$CFG_GRAPHICS_SYSTEM" = "openvg" ] && [ "$CFG_OPENVG" = "no" ]; then + echo "OpenVG Graphics System is disabled due to missing OpenVG support..." + CFG_GRAPHICS_SYSTEM=default +fi + if [ "$CFG_PTMALLOC" != "no" ]; then # build ptmalloc, copy .a file to lib/ echo "Building ptmalloc. Please wait..." @@ -6638,6 +6646,7 @@ QMakeVar set sql-plugins "$SQL_PLUGINS" if [ "$PLATFORM_QWS" != "yes" ]; then [ "$CFG_GRAPHICS_SYSTEM" = "raster" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_GRAPHICSSYSTEM_RASTER" [ "$CFG_GRAPHICS_SYSTEM" = "opengl" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_GRAPHICSSYSTEM_OPENGL" + [ "$CFG_GRAPHICS_SYSTEM" = "openvg" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_GRAPHICSSYSTEM_OPENVG" fi # X11/Unix/Mac only configs diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index b618d8b..ddc66f3 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -64,6 +64,10 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system.isEmpty()) { system = QLatin1String("opengl"); } +#elif defined (QT_GRAPHICSSYSTEM_OPENVG) + if (system.isEmpty()) { + system = QLatin1String("openvg"); + } #elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) if (system.isEmpty()) { system = QLatin1String("raster"); -- cgit v0.12 From 220b1cbcd253c8133ad185cd2be55db584071e67 Mon Sep 17 00:00:00 2001 From: Rohan McGovern Date: Wed, 22 Jul 2009 15:33:39 +1000 Subject: Add a (failing) test for QProcess bug 258462. --- tests/auto/qprocess/tst_qprocess.cpp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 6318d1d..3ce080a 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -141,6 +141,7 @@ private slots: void startFinishStartFinish(); void invalidProgramString_data(); void invalidProgramString(); + void processEventsInAReadyReadSlot(); // keep these at the end, since they use lots of processes and sometimes // caused obscure failures to occur in tests that followed them (esp. on the Mac) @@ -154,6 +155,7 @@ protected slots: void restartProcess(); void waitForReadyReadInAReadyReadSlotSlot(); void waitForBytesWrittenInABytesWrittenSlotSlot(); + void processEventsInAReadyReadSlotSlot(); private: QProcess *process; @@ -2024,5 +2026,34 @@ void tst_QProcess::invalidProgramString() QVERIFY(!QProcess::startDetached(programString)); } +//----------------------------------------------------------------------------- +void tst_QProcess::processEventsInAReadyReadSlot() +{ +#ifdef Q_OS_WINCE + QSKIP("Reading and writing to a process is not supported on Qt/CE", SkipAll); +#endif + + QProcess process; + QVERIFY(QObject::connect(&process, SIGNAL(readyReadStandardOutput()), this, SLOT(processEventsInAReadyReadSlotSlot()))); + + for (int i = 0; i < 10; ++i) { + QCOMPARE(process.state(), QProcess::NotRunning); + +#ifdef Q_OS_MAC + process.start("testProcessOutput/testProcessOutput.app"); +#else + process.start("testProcessOutput/testProcessOutput"); +#endif + + QVERIFY(process.waitForFinished(10000)); + } +} + +//----------------------------------------------------------------------------- +void tst_QProcess::processEventsInAReadyReadSlotSlot() +{ + qApp->processEvents(); +} + QTEST_MAIN(tst_QProcess) #include "tst_qprocess.moc" -- cgit v0.12 From e43eae35b242bf90c801e719d61fff4a20549ead Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Tue, 21 Jul 2009 19:32:28 +0200 Subject: Fix Warning saying that signal cannot be made virtual The test for virtual signal did not work. But we cannot make an error right now or it might break existing code (exemple in task 210879) Reviewed-by: Kent Hansen --- src/tools/moc/moc.cpp | 20 +++++++++----------- tests/auto/moc/tst_moc.cpp | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp index da5733a..797595f 100644 --- a/src/tools/moc/moc.cpp +++ b/src/tools/moc/moc.cpp @@ -337,11 +337,10 @@ bool Moc::testFunctionAttribute(Token tok, FunctionDef *def) bool Moc::parseFunction(FunctionDef *def, bool inMacro) { def->isVirtual = false; - while (test(INLINE) || test(STATIC) || test(VIRTUAL) - || testFunctionAttribute(def)) { - if (lookup() == VIRTUAL) - def->isVirtual = true; - } + //skip modifiers and attributes + while (test(INLINE) || test(STATIC) || + (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + || testFunctionAttribute(def)) {} bool templateFunction = (lookup() == TEMPLATE); def->type = parseType(); if (def->type.name.isEmpty()) { @@ -429,11 +428,10 @@ bool Moc::parseFunction(FunctionDef *def, bool inMacro) bool Moc::parseMaybeFunction(const ClassDef *cdef, FunctionDef *def) { def->isVirtual = false; - while (test(EXPLICIT) || test(INLINE) || test(STATIC) || test(VIRTUAL) - || testFunctionAttribute(def)) { - if (lookup() == VIRTUAL) - def->isVirtual = true; - } + //skip modifiers and attributes + while (test(INLINE) || test(STATIC) || + (test(VIRTUAL) && (def->isVirtual = true)) //mark as virtual + || testFunctionAttribute(def)) {} bool tilde = test(TILDE); def->type = parseType(); if (def->type.name.isEmpty()) @@ -862,7 +860,7 @@ void Moc::parseSignals(ClassDef *def) funcDef.access = FunctionDef::Protected; parseFunction(&funcDef); if (funcDef.isVirtual) - error("Signals cannot be declared virtual"); + warning("Signals cannot be declared virtual"); if (funcDef.inlineCode) error("Not a signal declaration"); def->signalList += funcDef; diff --git a/tests/auto/moc/tst_moc.cpp b/tests/auto/moc/tst_moc.cpp index 898cfe1..d66791f 100644 --- a/tests/auto/moc/tst_moc.cpp +++ b/tests/auto/moc/tst_moc.cpp @@ -488,6 +488,7 @@ private slots: void warnOnPropertyWithoutREAD(); void constructors(); void typenameWithUnsigned(); + void warnOnVirtualSignal(); signals: void sigWithUnsignedArg(unsigned foo); @@ -1180,6 +1181,27 @@ void tst_Moc::typenameWithUnsigned() QVERIFY(mobj->indexOfSlot("l(unsignedQImage)") != -1); } + +void tst_Moc::warnOnVirtualSignal() +{ +#ifdef MOC_CROSS_COMPILED + QSKIP("Not tested when cross-compiled", SkipAll); +#endif +#if defined(Q_OS_LINUX) && defined(Q_CC_GNU) && !defined(QT_NO_PROCESS) + QProcess proc; + proc.start("moc", QStringList(srcify("pure-virtual-signals.h"))); + QVERIFY(proc.waitForFinished()); + QCOMPARE(proc.exitCode(), 0); + QByteArray mocOut = proc.readAllStandardOutput(); + QVERIFY(!mocOut.isEmpty()); + QString mocWarning = QString::fromLocal8Bit(proc.readAllStandardError()); + QCOMPARE(mocWarning, QString(SRCDIR) + QString("/pure-virtual-signals.h:48: Warning: Signals cannot be declared virtual\n") + + QString(SRCDIR) + QString("/pure-virtual-signals.h:50: Warning: Signals cannot be declared virtual\n")); +#else + QSKIP("Only tested on linux/gcc", SkipAll); +#endif +} + QTEST_MAIN(tst_Moc) #include "tst_moc.moc" -- cgit v0.12 From cdff58107507a1a7a2d81e8b824d1c5361a77905 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 22 Jul 2009 10:28:03 +0200 Subject: delete incorrect documentation --- src/corelib/statemachine/qabstracttransition.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index c040c58..670aa7d 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -330,18 +330,6 @@ QList QAbstractTransition::animations() const This function is called to determine whether the given \a event should cause this transition to trigger. Reimplement this function and return true if the event should trigger the transition, otherwise return false. - - - Note that \a event is a QWrappedEvent, which contains a clone of - the event generated by Qt. For instance, if you want to check a - key press event, do the following: - - \snippet doc/src/snippets/statemachine/eventtest.cpp 0 - - You need to check if \a event is a QWrappedEvent because Qt also - uses other events for internal reasons; you don't need to concern - yourself with these in any case. - */ /*! -- cgit v0.12 From 6ecce8dfe0c71bc4dcc510d7920f70f7799cb0a7 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 22 Jul 2009 10:35:03 +0200 Subject: Fix a potential crash due to the fact that _q_UpdateIndex() is reentered This is confirmed to resolve a number of problems from the original reportee. It's already fixed in Qt 4.6 in a more wider fix, but this one liner is a good to have in Qt 4.5.x anyway. Task-number: 258194 Reviewed-by: alexis --- src/gui/graphicsview/qgraphicsscene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 053338b..247347a 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -542,7 +542,7 @@ void QGraphicsScenePrivate::_q_updateIndex() // Regenerate the tree. if (regenerateIndex) { regenerateIndex = false; - bspTree.initialize(q->sceneRect(), depth); + bspTree.initialize(sceneRect, depth); unindexedItems = indexedItems; lastItemCount = indexedItems.size(); q->update(); -- cgit v0.12 From b0f37b81cb1972bc66ebc53ef5d4ea237ae83525 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 22 Jul 2009 10:46:41 +0200 Subject: qdoc: Changed to build qdoc3 in release mode. --- tools/qdoc3/qdoc3.pro | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro index 1291272..49a16e6 100644 --- a/tools/qdoc3/qdoc3.pro +++ b/tools/qdoc3/qdoc3.pro @@ -7,10 +7,11 @@ DEFINES += QT_NO_CAST_TO_ASCII QT = core xml CONFIG += console CONFIG -= debug_and_release_target -CONFIG += debug +#CONFIG += debug build_all:!build_pass { CONFIG -= build_all - CONFIG += debug + CONFIG += release +# CONFIG += debug } mac:CONFIG -= app_bundle HEADERS += apigenerator.h \ -- cgit v0.12 From 236579465c8328fd4022a3dbbb68bf6fa9ffe4f4 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 22 Jul 2009 10:57:24 +0200 Subject: qdoc: Added page for obsolete classes. The classes marked \obsolete are no longer included in the "All Classes" list. They are listed separately on an "Obsolete Classes" list. The new page is reachable from the "All Classes" page and from the "Grouped Classes" page. --- doc/src/classes.qdoc | 10 +++--- doc/src/obsoleteclasses.qdoc | 59 +++++++++++++++++++++++++++++++++ tools/qdoc3/htmlgenerator.cpp | 77 ++++++++++++++++++++++++++++++++----------- tools/qdoc3/htmlgenerator.h | 3 +- 4 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 doc/src/obsoleteclasses.qdoc diff --git a/doc/src/classes.qdoc b/doc/src/classes.qdoc index dddc96f..9a5d3ec 100644 --- a/doc/src/classes.qdoc +++ b/doc/src/classes.qdoc @@ -44,13 +44,15 @@ \title Qt's Classes \ingroup classlists - This is a list of all Qt classes excluding the \l{Qt 3 - compatibility classes}. For a shorter list that only includes the - most frequently used classes, see \l{Qt's Main Classes}. + This is a list of all Qt classes. For a shorter list of the most + frequently used Qt classes, see \l{Qt's Main Classes}. For a list + of the classes provided for compatibility with Qt3, see \l{Qt 3 + compatibility classes}. For classes that have been deprecated, see + the \l{Obsolete Classes} list. \generatelist classes - \sa {Qt 3 Compatibility Classes}, {Qt's Modules} + \sa {Qt 3 Compatibility Classes}, {Qt's Modules}, {Obsolete Classes} */ /*! diff --git a/doc/src/obsoleteclasses.qdoc b/doc/src/obsoleteclasses.qdoc new file mode 100644 index 0000000..3658dfc --- /dev/null +++ b/doc/src/obsoleteclasses.qdoc @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page obsoleteclasses.html + \group obsolete + \title Obsolete Classes + \ingroup classlists + \ingroup groups + + \brief Qt classes that are obsolete (deprecated). + + This is a list of Qt classes that are obsolete (deprecated). These + classes are provided to keep old source code working but they are + no longer maintained. We strongly advise against using these + classes in new code. + + \generatelist obsoleteclasses + + \sa {Qt's Classes}, {Qt's Modules} +*/ diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index c007b9b..8d5e3d3 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -294,6 +294,7 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) nonCompatClasses.clear(); mainClasses.clear(); compatClasses.clear(); + obsoleteClasses.clear(); moduleClassMap.clear(); moduleNamespaceMap.clear(); funcIndex.clear(); @@ -381,7 +382,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::AutoLink: if (!inLink && !inContents && !inSectionHeading) { const Node *node = 0; - QString link = getLink(atom, relative, marker, node); + QString link = getLink(atom, relative, marker, &node); if (!link.isEmpty()) { beginLink(link, node, relative, marker); generateLink(atom, relative, marker); @@ -567,6 +568,9 @@ int HtmlGenerator::generateAtom(const Atom *atom, else if (atom->string() == "compatclasses") { generateCompactList(relative, marker, compatClasses); } + else if (atom->string() == "obsoleteclasses") { + generateCompactList(relative, marker, obsoleteClasses); + } else if (atom->string() == "functionindex") { generateFunctionIndex(relative, marker); } @@ -648,11 +652,12 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::Link: { const Node *node = 0; - QString myLink = getLink(atom, relative, marker, node); - if (myLink.isEmpty()) + QString myLink = getLink(atom, relative, marker, &node); + if (myLink.isEmpty()) { relative->doc().location().warning(tr("Cannot link to '%1' in %2") .arg(atom->string()) .arg(marker->plainFullName(relative))); + } beginLink(myLink, node, relative, marker); skipAhead = 1; } @@ -3261,6 +3266,9 @@ void HtmlGenerator::findAllClasses(const InnerNode *node) if ((*c)->status() == Node::Compat) { compatClasses.insert(className, *c); } + else if ((*c)->status() == Node::Obsolete) { + obsoleteClasses.insert(className, *c); + } else { nonCompatClasses.insert(className, *c); if ((*c)->status() == Node::Main) @@ -3457,10 +3465,10 @@ const QPair HtmlGenerator::anchorForNode(const Node *node) QString HtmlGenerator::getLink(const Atom *atom, const Node *relative, CodeMarker *marker, - const Node *node) + const Node** node) { QString link; - node = 0; + *node = 0; if (atom->string().contains(":") && (atom->string().startsWith("file:") @@ -3484,40 +3492,69 @@ QString HtmlGenerator::getLink(const Atom *atom, QString first = path.first().trimmed(); if (first.isEmpty()) { - node = relative; + *node = relative; } else if (first.endsWith(".html")) { - node = tre->root()->findNode(first, Node::Fake); + *node = tre->root()->findNode(first, Node::Fake); } else { - node = marker->resolveTarget(first, tre, relative); - if (!node) - node = tre->findFakeNodeByTitle(first); - if (!node) - node = tre->findUnambiguousTarget(first, targetAtom); + *node = marker->resolveTarget(first, tre, relative); + if (!*node) + *node = tre->findFakeNodeByTitle(first); + if (!*node) + *node = tre->findUnambiguousTarget(first, targetAtom); } - if (node) { - if (!node->url().isEmpty()) - return node->url(); + if (*node) { + if (!(*node)->url().isEmpty()) + return (*node)->url(); else path.removeFirst(); } else { - node = relative; + *node = relative; + } +#if 0 + if (*node) { + if ((*node)->status() == Node::Obsolete) { + if (relative) { + if (relative->parent() != *node) { + if (relative->status() != Node::Obsolete) { + qDebug() << "Link to Obsolete entity" + << (*node)->name(); + qDebug() << " relative entity" + << relative->name(); + } + } + } + else { + qDebug() << "Link to Obsolete entity" + << (*node)->name() << "no relative"; + } + } +#if 0 + else if ((*node)->status() == Node::Deprecated) { + qDebug() << "Link to Deprecated entity"; + } + else if ((*node)->status() == Node::Internal) { + qDebug() << "Link to Internal entity"; + } + //else + //qDebug() << "Node Status:" << (*node)->status(); +#endif } - +#endif while (!path.isEmpty()) { - targetAtom = tre->findTarget(path.first(), node); + targetAtom = tre->findTarget(path.first(), *node); if (targetAtom == 0) break; path.removeFirst(); } if (path.isEmpty()) { - link = linkForNode(node, relative); + link = linkForNode(*node, relative); if (targetAtom) - link += "#" + refForAtom(targetAtom, node); + link += "#" + refForAtom(targetAtom, *node); } } return link; diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index dc5e5cf..a7f4009 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -202,7 +202,7 @@ class HtmlGenerator : public PageGenerator virtual QString getLink(const Atom *atom, const Node *relative, CodeMarker *marker, - const Node *node = 0); + const Node** node); virtual void generateDcf(const QString &fileBase, const QString &startPage, const QString &title, DcfSection &dcfRoot); @@ -256,6 +256,7 @@ class HtmlGenerator : public PageGenerator QMap nonCompatClasses; QMap mainClasses; QMap compatClasses; + QMap obsoleteClasses; QMap namespaceIndex; QMap serviceClasses; #ifdef QDOC_QML -- cgit v0.12 From 3a8968dd2aab9c4e40ed34222f557bec6a98349e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Wed, 22 Jul 2009 11:47:02 +0200 Subject: qdoc: Reported links to obsolete things that appear in non-obsolete things. Also marked the other QHttpXxx classes as \obsolete. --- src/network/access/qhttp.cpp | 3 +++ tools/qdoc3/htmlgenerator.cpp | 9 +++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 790b48a..faa2398 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -513,6 +513,7 @@ public: /*! \class QHttpHeader + \obsolete \brief The QHttpHeader class contains header information for HTTP. \ingroup io @@ -1007,6 +1008,7 @@ public: /*! \class QHttpResponseHeader + \obsolete \brief The QHttpResponseHeader class contains response header information for HTTP. \ingroup io @@ -1211,6 +1213,7 @@ public: /*! \class QHttpRequestHeader + \obsolete \brief The QHttpRequestHeader class contains request header information for HTTP. \ingroup io diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 8d5e3d3..e31f6cf 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -3514,16 +3514,21 @@ QString HtmlGenerator::getLink(const Atom *atom, else { *node = relative; } -#if 0 + if (*node) { if ((*node)->status() == Node::Obsolete) { if (relative) { if (relative->parent() != *node) { if (relative->status() != Node::Obsolete) { + relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") + .arg(atom->string()) + .arg(marker->plainFullName(relative))); +#if 0 qDebug() << "Link to Obsolete entity" << (*node)->name(); qDebug() << " relative entity" << relative->name(); +#endif } } } @@ -3543,7 +3548,7 @@ QString HtmlGenerator::getLink(const Atom *atom, //qDebug() << "Node Status:" << (*node)->status(); #endif } -#endif + while (!path.isEmpty()) { targetAtom = tre->findTarget(path.first(), *node); if (targetAtom == 0) -- cgit v0.12 From 336954fb9b990c6d7c44ed3a8d676a6e21b2057f Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 22 Jul 2009 13:19:32 +0200 Subject: Simplify the computation of the QProgressBar progress. This is also a work around for a bug in gcc on powerpc (embedded-linux) Task-number: 258358 Reviewed-by: jbache --- src/gui/styles/qcleanlooksstyle.cpp | 7 +++---- src/gui/styles/qgtkstyle.cpp | 4 ++-- src/gui/widgets/qprogressbar.cpp | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 01f19c6..779fbc2 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -1745,10 +1745,9 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o int maxWidth = rect.width() - 4; int minWidth = 4; - qint64 progress = (qint64)qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar - double vc6_workaround = ((progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * maxWidth); - int progressBarWidth = (int(vc6_workaround) > minWidth ) ? int(vc6_workaround) : minWidth; - int width = indeterminate ? maxWidth : progressBarWidth; + int progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar + int progressBarWidth = qMax(minWidth, (progress - bar->minimum) * maxWidth / qMax(1, bar->maximum - bar->minimum)); + int width = indeterminate ? maxWidth : progressBarWidth; bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical; if (inverted) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index b6ef4c9..2ba151e 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2075,8 +2075,8 @@ void QGtkStyle::drawControl(ControlElement element, } if (vertical) rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height - const int progressIndicatorPos = static_cast((bar->progress - qint64(bar->minimum)) / - qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * rect.width()); + const int progressIndicatorPos = (bar->progress - bar->minimum) * rect.width() / + qMax(1, bar->maximum - bar->minimum); if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height()); if (vertical) diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp index d168028..846f127 100644 --- a/src/gui/widgets/qprogressbar.cpp +++ b/src/gui/widgets/qprogressbar.cpp @@ -447,7 +447,7 @@ QString QProgressBar::text() const || (d->value == INT_MIN && d->minimum == INT_MIN)) return QString(); - qint64 totalSteps = qint64(d->maximum) - qint64(d->minimum); + int totalSteps = d->maximum - d->minimum; QString result = d->format; result.replace(QLatin1String("%m"), QString::number(totalSteps)); @@ -461,7 +461,7 @@ QString QProgressBar::text() const return result; } - int progress = int(((qreal(d->value) - qreal(d->minimum)) * 100.0) / totalSteps); + int progress = (d->value - d->minimum) * 100 / totalSteps; result.replace(QLatin1String("%p"), QString::number(progress)); return result; } -- cgit v0.12 From 27e5a1f9542b03a6930f002e8d7dafd97cf88a1a Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 22 Jul 2009 13:56:51 +0200 Subject: Support for very large range in QProgressBar Regression since my last commit. Task-number: 152227 --- src/gui/styles/qcleanlooksstyle.cpp | 6 +++--- src/gui/styles/qgtkstyle.cpp | 4 ++-- src/gui/styles/qplastiquestyle.cpp | 3 +-- src/gui/widgets/qprogressbar.cpp | 4 ++-- tests/auto/qprogressbar/tst_qprogressbar.cpp | 32 +++++++++++++++++++++++++++- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index 779fbc2..ccf81cb 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -1745,9 +1745,9 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o int maxWidth = rect.width() - 4; int minWidth = 4; - int progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar - int progressBarWidth = qMax(minWidth, (progress - bar->minimum) * maxWidth / qMax(1, bar->maximum - bar->minimum)); - int width = indeterminate ? maxWidth : progressBarWidth; + qreal progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar + int progressBarWidth = (progress - bar->minimum) * qreal(maxWidth) / qMax(1.0, qreal(bar->maximum) - bar->minimum); + int width = indeterminate ? maxWidth : qMax(minWidth, progressBarWidth); bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical; if (inverted) diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 2ba151e..53f3db9 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2075,8 +2075,8 @@ void QGtkStyle::drawControl(ControlElement element, } if (vertical) rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height - const int progressIndicatorPos = (bar->progress - bar->minimum) * rect.width() / - qMax(1, bar->maximum - bar->minimum); + const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() / + qMax(1.0, qreal(bar->maximum) - bar->minimum); if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height()); if (vertical) diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index cd0bd0a..80c9881 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -2571,8 +2571,7 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op painter->setTransform(m, true); } - double vc6_workaround = ((bar->progress - qint64(bar->minimum)) / qMax(double(1.0), double(qint64(bar->maximum) - qint64(bar->minimum))) * rect.width()); - int progressIndicatorPos = int(vc6_workaround); + int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) / qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum) * rect.width(); bool flip = (!vertical && (((bar->direction == Qt::RightToLeft) && !inverted) || ((bar->direction == Qt::LeftToRight) && inverted))) || (vertical && ((!inverted && !bottomToTop) || (inverted && bottomToTop))); diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp index 846f127..6b38e9f 100644 --- a/src/gui/widgets/qprogressbar.cpp +++ b/src/gui/widgets/qprogressbar.cpp @@ -447,7 +447,7 @@ QString QProgressBar::text() const || (d->value == INT_MIN && d->minimum == INT_MIN)) return QString(); - int totalSteps = d->maximum - d->minimum; + qint64 totalSteps = qint64(d->maximum) - d->minimum; QString result = d->format; result.replace(QLatin1String("%m"), QString::number(totalSteps)); @@ -461,7 +461,7 @@ QString QProgressBar::text() const return result; } - int progress = (d->value - d->minimum) * 100 / totalSteps; + int progress = (qreal(d->value) - d->minimum) * 100.0 / totalSteps; result.replace(QLatin1String("%p"), QString::number(progress)); return result; } diff --git a/tests/auto/qprogressbar/tst_qprogressbar.cpp b/tests/auto/qprogressbar/tst_qprogressbar.cpp index 403b56b..452250c 100644 --- a/tests/auto/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/qprogressbar/tst_qprogressbar.cpp @@ -62,6 +62,8 @@ private slots: void format(); void setValueRepaint(); void sizeHint(); + void formatedText_data(); + void formatedText(); void task245201_testChangeStyleAndDelete_data(); void task245201_testChangeStyleAndDelete(); @@ -174,7 +176,7 @@ void tst_QProgressBar::format() bar.repainted = false; bar.setFormat("%v of %m (%p%)"); qApp->processEvents(); -#ifndef Q_WS_MAC +#ifndef Q_WS_MAC // The Mac scroll bar is animated, which means we get paint events all the time. QVERIFY(!bar.repainted); #endif @@ -225,6 +227,34 @@ void tst_QProgressBar::sizeHint() QCOMPARE(barSize.height(), size.height()); } +void tst_QProgressBar::formatedText_data() +{ + QTest::addColumn("minimum"); + QTest::addColumn("maximum"); + QTest::addColumn("value"); + QTest::addColumn("format"); + QTest::addColumn("text"); + + QTest::newRow("1") << -100 << 100 << 0 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 50 - 0 - 200 "); +// QTest::newRow("2") << -100 << 0 << -25 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 75 - -25 - 100 "); + QTest::newRow("3") << 10 << 10 << 10 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 100 - 10 - 0 "); + QTest::newRow("task152227") << INT_MIN << INT_MAX << 42 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 50 - 42 - 4294967295 "); +} + +void tst_QProgressBar::formatedText() +{ + QFETCH(int, minimum); + QFETCH(int, maximum); + QFETCH(int, value); + QFETCH(QString, format); + QFETCH(QString, text); + QProgressBar bar; + bar.setRange(minimum, maximum); + bar.setValue(value); + bar.setFormat(format); + QCOMPARE(bar.text(), text); +} + void tst_QProgressBar::task245201_testChangeStyleAndDelete_data() { QTest::addColumn("style1_str"); -- cgit v0.12 From e3994b506c21b9967248ea404cfdfef82060c13e Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 22 Jul 2009 14:05:03 +0200 Subject: Show text even if maximum == 0 --- src/gui/widgets/qprogressbar.cpp | 2 +- tests/auto/qprogressbar/tst_qprogressbar.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qprogressbar.cpp b/src/gui/widgets/qprogressbar.cpp index 6b38e9f..6593cd6 100644 --- a/src/gui/widgets/qprogressbar.cpp +++ b/src/gui/widgets/qprogressbar.cpp @@ -443,7 +443,7 @@ QSize QProgressBar::minimumSizeHint() const QString QProgressBar::text() const { Q_D(const QProgressBar); - if (d->maximum == 0 || d->value < d->minimum + if ((d->maximum == 0 && d->minimum == 0) || d->value < d->minimum || (d->value == INT_MIN && d->minimum == INT_MIN)) return QString(); diff --git a/tests/auto/qprogressbar/tst_qprogressbar.cpp b/tests/auto/qprogressbar/tst_qprogressbar.cpp index 452250c..911d6b7 100644 --- a/tests/auto/qprogressbar/tst_qprogressbar.cpp +++ b/tests/auto/qprogressbar/tst_qprogressbar.cpp @@ -236,7 +236,7 @@ void tst_QProgressBar::formatedText_data() QTest::addColumn("text"); QTest::newRow("1") << -100 << 100 << 0 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 50 - 0 - 200 "); -// QTest::newRow("2") << -100 << 0 << -25 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 75 - -25 - 100 "); + QTest::newRow("2") << -100 << 0 << -25 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 75 - -25 - 100 "); QTest::newRow("3") << 10 << 10 << 10 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 100 - 10 - 0 "); QTest::newRow("task152227") << INT_MIN << INT_MAX << 42 << QString::fromLatin1(" %p - %v - %m ") << QString::fromLatin1(" 50 - 42 - 4294967295 "); } -- cgit v0.12 From 6c25a7cdea912f212ce00f43c7cfc862c1ecdd50 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 22 Jul 2009 14:08:07 +0200 Subject: Designer: Fixed bug in setting QUrl property values from resources. Setting a file from a resource would result in 'qrc::/file' as the resource browser returns ':/file'. Reviewed-by: Jarek Kobus Initial-patch-by: andy --- .../src/components/propertyeditor/designerpropertymanager.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp index 2f6a51e..1092b92 100644 --- a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp +++ b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp @@ -254,8 +254,11 @@ void TextEditor::resourceActionActivated() { QString oldPath = m_editor->text(); if (oldPath.startsWith(QLatin1String("qrc:"))) - oldPath = oldPath.mid(4); - const QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this); + oldPath.remove(0, 4); + // returns ':/file' + QString newPath = IconSelector::choosePixmapResource(m_core, m_core->resourceModel(), oldPath, this); + if (newPath.startsWith(QLatin1Char(':'))) + newPath.remove(0, 1); if (newPath.isEmpty() || newPath == oldPath) return; const QString newText = QLatin1String("qrc:") + newPath; -- cgit v0.12 From 6f9d5e9435b2c518df62278cc6fc1ab0fdf23ffe Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Wed, 22 Jul 2009 14:25:26 +0200 Subject: Update documentation for QMessageBox::open(). I had missed this one in my rounds of updates. Bad me. Reviewed-by: Thorbjorn --- src/gui/dialogs/qmessagebox.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/dialogs/qmessagebox.cpp b/src/gui/dialogs/qmessagebox.cpp index b3522ce..eeec95f 100644 --- a/src/gui/dialogs/qmessagebox.cpp +++ b/src/gui/dialogs/qmessagebox.cpp @@ -1368,8 +1368,10 @@ void QMessageBox::setVisible(bool visible) /*! \overload - Opens the dialog and connects its accepted() signal to the slot specified - by \a receiver and \a member. + Opens the dialog and connects its finished() or buttonClicked() signal to + the slot specified by \a receiver and \a member. If the slot in \a member + has a pointer for its first parameter the connection is to buttonClicked(), + otherwise the connection is to finished(). The signal will be disconnected from the slot when the dialog is closed. */ -- cgit v0.12 From be1d9a4288e2b17a3d5a699da229076682ef99bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 18:27:11 +0200 Subject: QDirIterator: refactor initializations in private constructor There's no need for initializing variables twice. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index c9c80bb..7de0a0b 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -134,12 +134,12 @@ public: */ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) - : engine(0), path(path), nextFileInfo(path), iteratorFlags(flags), followNextDir(false), first(true), done(false) + : engine(0), path(path), nextFileInfo(path), iteratorFlags(flags), + filters(filters), nameFilters(nameFilters), + followNextDir(false), first(true), done(false) { - if (filters == QDir::NoFilter) - filters = QDir::AllEntries; - this->filters = filters; - this->nameFilters = nameFilters; + if (QDir::NoFilter == filters) + this->filters = QDir::AllEntries; pushSubDirectory(nextFileInfo, nameFilters, filters); } -- cgit v0.12 From e316b2249f329b4754b23d9cc8c418c3645dc6db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 19:02:23 +0200 Subject: Faster condition comes first Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 7de0a0b..eae1dfa 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -240,7 +240,7 @@ bool QDirIteratorPrivate::shouldFollowDirectory(const QFileInfo &fileInfo) return false; // Check symlinks - if (fileInfo.isSymLink() && !(iteratorFlags & QDirIterator::FollowSymlinks)) { + if (!(iteratorFlags & QDirIterator::FollowSymlinks) && fileInfo.isSymLink()) { // Follow symlinks only if FollowSymlinks was passed return false; } -- cgit v0.12 From 5f18fa27a6e87ee7cd568388cdf59cf85a3620e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 20:48:39 +0200 Subject: QDirIterator moving around conditions Which is faster QFileInfo::isSymlink() or QFileInfo::fileName() followed by string comparisons? Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index eae1dfa..6d6542f 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -235,15 +235,14 @@ bool QDirIteratorPrivate::shouldFollowDirectory(const QFileInfo &fileInfo) if (!fileInfo.isDir()) return false; - // Never follow . and .. - if (fileInfo.fileName() == QLatin1String(".") || fileInfo.fileName() == QLatin1String("..")) + // Follow symlinks only when asked + if (!(iteratorFlags & QDirIterator::FollowSymlinks) && fileInfo.isSymLink()) return false; - // Check symlinks - if (!(iteratorFlags & QDirIterator::FollowSymlinks) && fileInfo.isSymLink()) { - // Follow symlinks only if FollowSymlinks was passed + // Never follow . and .. + QString fileName = fileInfo.fileName(); + if (QLatin1String(".") == fileName || QLatin1String("..") == fileName) return false; - } // Stop link loops if (visitedLinks.contains(fileInfo.canonicalFilePath())) -- cgit v0.12 From 316fec414c651fb4c5dc9666344219b0137e704f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Jul 2009 12:21:15 +0200 Subject: QDirIterator: Don't recurse into hidden directories unless asked If we're skipping hidden files, we should skip hidden directories as well. The user can still request that hidden directories not be skipped by specifying QDir::AllDirs in the filter. Incidentally, all other filters are ignored when recursing into sub-directories. Perhaps that should be addressed as well. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 6d6542f..f36320e 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -244,6 +244,10 @@ bool QDirIteratorPrivate::shouldFollowDirectory(const QFileInfo &fileInfo) if (QLatin1String(".") == fileName || QLatin1String("..") == fileName) return false; + // No hidden directories unless requested + if (!(filters & QDir::AllDirs) && !(filters & QDir::Hidden) && fileInfo.isHidden()) + return false; + // Stop link loops if (visitedLinks.contains(fileInfo.canonicalFilePath())) return false; -- cgit v0.12 From 3e1476237996a99f7da77bd6abcfcd130c1bb126 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 19:11:30 +0200 Subject: QDirIterator cleanup The authoritative copy of filters and nameFilters is available, there is no need to get this from the file engine iterators. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index f36320e..df2b0c9 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -106,8 +106,7 @@ public: QDir::Filters filters, QDirIterator::IteratorFlags flags); ~QDirIteratorPrivate(); - void pushSubDirectory(const QFileInfo &fileInfo, const QStringList &nameFilters, - QDir::Filters filters); + void pushSubDirectory(const QFileInfo &fileInfo); void advance(); bool shouldFollowDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; @@ -141,7 +140,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList if (QDir::NoFilter == filters) this->filters = QDir::AllEntries; - pushSubDirectory(nextFileInfo, nameFilters, filters); + pushSubDirectory(nextFileInfo); } /*! @@ -155,8 +154,7 @@ QDirIteratorPrivate::~QDirIteratorPrivate() /*! \internal */ -void QDirIteratorPrivate::pushSubDirectory(const QFileInfo &fileInfo, const QStringList &nameFilters, - QDir::Filters filters) +void QDirIteratorPrivate::pushSubDirectory(const QFileInfo &fileInfo) { QString path = fileInfo.filePath(); @@ -189,7 +187,7 @@ void QDirIteratorPrivate::advance() if (followNextDir) { // Start by navigating into the current directory. QAbstractFileEngineIterator *it = fileEngineIterators.top(); - pushSubDirectory(it->currentFileInfo(), it->nameFilters(), it->filters()); + pushSubDirectory(it->currentFileInfo()); followNextDir = false; } @@ -210,7 +208,7 @@ void QDirIteratorPrivate::advance() return; } else if (shouldFollowDirectory(info)) { - pushSubDirectory(info, it->nameFilters(), it->filters()); + pushSubDirectory(info); foundDirectory = true; break; } -- cgit v0.12 From 40276797e5a1e723826afe0c4d4cdeef99f1d309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Jul 2009 11:37:23 +0200 Subject: Still fixing QDirIterator... Setting nextFileInfo in the constructor would generate visible behavior changes on the first call to QDirIterator::hasNext(), and that's just wrong. Namely, fileName(), filePath() would return different results before and after calling hasNext(). Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index df2b0c9..5f37bd7 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -133,14 +133,14 @@ public: */ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) - : engine(0), path(path), nextFileInfo(path), iteratorFlags(flags), + : engine(0), path(path), iteratorFlags(flags), filters(filters), nameFilters(nameFilters), followNextDir(false), first(true), done(false) { if (QDir::NoFilter == filters) this->filters = QDir::AllEntries; - pushSubDirectory(nextFileInfo); + pushSubDirectory(QFileInfo(path)); } /*! -- cgit v0.12 From 615e3e55fc56a5f5378db404cd89a443e7e74e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 19:17:45 +0200 Subject: QDirIterator: another one bites the dust Removing another data member in QDirIteratorPrivate. The only reason I see for not doing this is to delay doing work as much as possible. Since copy constructors are disabled anyway, once QDirIterator is instantiated one has already signed up for the pain. The code also looks cleaner this way. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 5f37bd7..51bb98a 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -121,7 +121,6 @@ public: QDirIterator::IteratorFlags iteratorFlags; QDir::Filters filters; QStringList nameFilters; - bool followNextDir; bool first; bool done; @@ -135,7 +134,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList QDir::Filters filters, QDirIterator::IteratorFlags flags) : engine(0), path(path), iteratorFlags(flags), filters(filters), nameFilters(nameFilters), - followNextDir(false), first(true), done(false) + first(true), done(false) { if (QDir::NoFilter == filters) this->filters = QDir::AllEntries; @@ -183,14 +182,6 @@ void QDirIteratorPrivate::pushSubDirectory(const QFileInfo &fileInfo) */ void QDirIteratorPrivate::advance() { - // Advance to the next entry - if (followNextDir) { - // Start by navigating into the current directory. - QAbstractFileEngineIterator *it = fileEngineIterators.top(); - pushSubDirectory(it->currentFileInfo()); - followNextDir = false; - } - while (!fileEngineIterators.isEmpty()) { QAbstractFileEngineIterator *it = fileEngineIterators.top(); @@ -202,8 +193,10 @@ void QDirIteratorPrivate::advance() if (matchesFilters(it->currentFileName(), info)) { currentFileInfo = nextFileInfo; nextFileInfo = info; - // Signal that we want to follow this entry. - followNextDir = shouldFollowDirectory(nextFileInfo); + + if(shouldFollowDirectory(nextFileInfo)) + pushSubDirectory(nextFileInfo); + //We found a matching entry. return; -- cgit v0.12 From f2dce82831706a38cd97225edb2edc0ed2a1520e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Jul 2009 15:29:12 +0200 Subject: QDirIterator refactoring done was set no sooner and no later than the file engine iterators stack was emptied (in a single threaded setting, anyway). There is no need to maintain additional state separately. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 51bb98a..0ea7097 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -122,7 +122,6 @@ public: QDir::Filters filters; QStringList nameFilters; bool first; - bool done; QDirIterator *q; }; @@ -134,7 +133,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList QDir::Filters filters, QDirIterator::IteratorFlags flags) : engine(0), path(path), iteratorFlags(flags), filters(filters), nameFilters(nameFilters), - first(true), done(false) + first(true) { if (QDir::NoFilter == filters) this->filters = QDir::AllEntries; @@ -209,8 +208,8 @@ void QDirIteratorPrivate::advance() if (!foundDirectory) delete fileEngineIterators.pop(); } + currentFileInfo = nextFileInfo; - done = true; } /*! @@ -464,7 +463,7 @@ bool QDirIterator::hasNext() const d->first = false; d->advance(); } - return !d->done; + return !d->fileEngineIterators.isEmpty(); } /*! -- cgit v0.12 From 0ba33d83108f21abbd98cde1accdbba5bce625d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Jul 2009 15:31:41 +0200 Subject: QDirIterator: no point in delaying the inevitable The only reason I see for not calling advance() directly in the constructor is to delay potentially unnecessary work. However, since copy constructors have been explicitly disabled, once QDirIterator is instantiated one has signed up for all the pain that comes with it. That's also a couple less conditionals in each iteration of normal use cases. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 0ea7097..0e4d563 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -121,7 +121,6 @@ public: QDirIterator::IteratorFlags iteratorFlags; QDir::Filters filters; QStringList nameFilters; - bool first; QDirIterator *q; }; @@ -132,13 +131,14 @@ public: QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) : engine(0), path(path), iteratorFlags(flags), - filters(filters), nameFilters(nameFilters), - first(true) + filters(filters), nameFilters(nameFilters) { if (QDir::NoFilter == filters) this->filters = QDir::AllEntries; + // Populate fields for hasNext() and next() pushSubDirectory(QFileInfo(path)); + advance(); } /*! @@ -459,10 +459,6 @@ QString QDirIterator::next() */ bool QDirIterator::hasNext() const { - if (d->first) { - d->first = false; - d->advance(); - } return !d->fileEngineIterators.isEmpty(); } -- cgit v0.12 From 3d5b6f694f477a3529e79e72d66824b8befa0dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 21:17:38 +0200 Subject: QDirIterator refactoring Some pointless renaming and mashing up... Actually, some of it sets the stage for (yes, you guessed it!) more refactoring! Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 0e4d563..ae5318f 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -106,9 +106,10 @@ public: QDir::Filters filters, QDirIterator::IteratorFlags flags); ~QDirIteratorPrivate(); - void pushSubDirectory(const QFileInfo &fileInfo); void advance(); - bool shouldFollowDirectory(const QFileInfo &); + + void pushDirectory(const QFileInfo &fileInfo); + bool checkAndPushDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; QSet visitedLinks; @@ -137,7 +138,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList this->filters = QDir::AllEntries; // Populate fields for hasNext() and next() - pushSubDirectory(QFileInfo(path)); + pushDirectory(QFileInfo(path)); advance(); } @@ -152,7 +153,7 @@ QDirIteratorPrivate::~QDirIteratorPrivate() /*! \internal */ -void QDirIteratorPrivate::pushSubDirectory(const QFileInfo &fileInfo) +void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo) { QString path = fileInfo.filePath(); @@ -193,14 +194,12 @@ void QDirIteratorPrivate::advance() currentFileInfo = nextFileInfo; nextFileInfo = info; - if(shouldFollowDirectory(nextFileInfo)) - pushSubDirectory(nextFileInfo); + checkAndPushDirectory(nextFileInfo); //We found a matching entry. return; - } else if (shouldFollowDirectory(info)) { - pushSubDirectory(info); + } else if (checkAndPushDirectory(info)) { foundDirectory = true; break; } @@ -215,7 +214,7 @@ void QDirIteratorPrivate::advance() /*! \internal */ -bool QDirIteratorPrivate::shouldFollowDirectory(const QFileInfo &fileInfo) +bool QDirIteratorPrivate::checkAndPushDirectory(const QFileInfo &fileInfo) { // If we're doing flat iteration, we're done. if (!(iteratorFlags & QDirIterator::Subdirectories)) @@ -242,6 +241,7 @@ bool QDirIteratorPrivate::shouldFollowDirectory(const QFileInfo &fileInfo) if (visitedLinks.contains(fileInfo.canonicalFilePath())) return false; + pushDirectory(fileInfo); return true; } -- cgit v0.12 From a8aa2c7a7f40883680b7989465873554dfbba3d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 21:20:31 +0200 Subject: QDirIterator refactoring Now that the heavy lifting has been done, we can condense QDirIteratorPrivate::advance() further. It almost looks nice, even! Using fileEngineIterators.top() directly in the loop condition allows us to manipulate the stack without the foundDirectory check. Since QStack can be inlined, this shouldn't severely affect performance... Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index ae5318f..8c7645e 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -183,29 +183,25 @@ void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo) void QDirIteratorPrivate::advance() { while (!fileEngineIterators.isEmpty()) { - QAbstractFileEngineIterator *it = fileEngineIterators.top(); // Find the next valid iterator that matches the filters. - bool foundDirectory = false; - while (it->hasNext()) { + while (fileEngineIterators.top()->hasNext()) { + QAbstractFileEngineIterator *it = fileEngineIterators.top(); it->next(); + const QFileInfo info = it->currentFileInfo(); + checkAndPushDirectory(it->currentFileInfo()); + if (matchesFilters(it->currentFileName(), info)) { currentFileInfo = nextFileInfo; nextFileInfo = info; - checkAndPushDirectory(nextFileInfo); - //We found a matching entry. return; - - } else if (checkAndPushDirectory(info)) { - foundDirectory = true; - break; } } - if (!foundDirectory) - delete fileEngineIterators.pop(); + + delete fileEngineIterators.pop(); } currentFileInfo = nextFileInfo; -- cgit v0.12 From 4c58b5936b6d169f6745d5eea3e65744956b8d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 21:21:35 +0200 Subject: QDirIterator cleanup after refactoring Return value for checkAndPushDirectory is no longer used, we can just throw it out. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 8c7645e..2e8d9c4 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -109,7 +109,7 @@ public: void advance(); void pushDirectory(const QFileInfo &fileInfo); - bool checkAndPushDirectory(const QFileInfo &); + void checkAndPushDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; QSet visitedLinks; @@ -210,35 +210,34 @@ void QDirIteratorPrivate::advance() /*! \internal */ -bool QDirIteratorPrivate::checkAndPushDirectory(const QFileInfo &fileInfo) +void QDirIteratorPrivate::checkAndPushDirectory(const QFileInfo &fileInfo) { // If we're doing flat iteration, we're done. if (!(iteratorFlags & QDirIterator::Subdirectories)) - return false; + return; // Never follow non-directory entries if (!fileInfo.isDir()) - return false; + return; // Follow symlinks only when asked if (!(iteratorFlags & QDirIterator::FollowSymlinks) && fileInfo.isSymLink()) - return false; + return; // Never follow . and .. QString fileName = fileInfo.fileName(); if (QLatin1String(".") == fileName || QLatin1String("..") == fileName) - return false; + return; // No hidden directories unless requested if (!(filters & QDir::AllDirs) && !(filters & QDir::Hidden) && fileInfo.isHidden()) - return false; + return; // Stop link loops if (visitedLinks.contains(fileInfo.canonicalFilePath())) - return false; + return; pushDirectory(fileInfo); - return true; } /*! -- cgit v0.12 From 3da795b77f3bb0752eb14057086241f25293e26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Thu, 16 Jul 2009 21:22:04 +0200 Subject: QDirIterator: Cleaning up after one's self Well, why not? Resetting nextFileInfo when we're done allows removing unnecessary check in QDirIterator::next(), while retaining behavior. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 2e8d9c4..09001c6 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -205,6 +205,7 @@ void QDirIteratorPrivate::advance() } currentFileInfo = nextFileInfo; + nextFileInfo = QFileInfo(); } /*! @@ -440,8 +441,6 @@ QDirIterator::~QDirIterator() */ QString QDirIterator::next() { - if (!hasNext()) - return QString(); d->advance(); return filePath(); } -- cgit v0.12 From 919e6f1ba2a6441c554bdb1b2c7d8ca78e33c557 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Jul 2009 12:23:57 +0200 Subject: QDirIterator: fail early, fail often If nothing else changes, there's no point to keep trying. Let a broken QDirIterator be broken. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 09001c6..ea54941 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -131,7 +131,7 @@ public: */ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) - : engine(0), path(path), iteratorFlags(flags), + : engine(QAbstractFileEngine::create(path)), path(path), iteratorFlags(flags), filters(filters), nameFilters(nameFilters) { if (QDir::NoFilter == filters) @@ -165,7 +165,7 @@ void QDirIteratorPrivate::pushDirectory(const QFileInfo &fileInfo) if (iteratorFlags & QDirIterator::FollowSymlinks) visitedLinks << fileInfo.canonicalFilePath(); - if (engine || (engine = QAbstractFileEngine::create(this->path))) { + if (engine) { engine->setFileName(path); QAbstractFileEngineIterator *it = engine->beginEntryList(filters, nameFilters); if (it) { -- cgit v0.12 From eabc4109a2703aa761eff7a26cfa7001af8577a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Fri, 17 Jul 2009 12:31:29 +0200 Subject: QDirIterator refactoring Moving member data around and marking immutable data as such. Reviewed-by: Marius Storm-Olsen --- src/corelib/io/qdiriterator.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index ea54941..371e822 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -112,16 +112,19 @@ public: void checkAndPushDirectory(const QFileInfo &); bool matchesFilters(const QString &fileName, const QFileInfo &fi) const; - QSet visitedLinks; - QAbstractFileEngine *engine; + QAbstractFileEngine * const engine; + + const QString path; + const QStringList nameFilters; + const QDir::Filters filters; + const QDirIterator::IteratorFlags iteratorFlags; + QStack fileEngineIterators; - QString path; - QFileInfo nextFileInfo; - //This fileinfo is the current that we will return from the public API QFileInfo currentFileInfo; - QDirIterator::IteratorFlags iteratorFlags; - QDir::Filters filters; - QStringList nameFilters; + QFileInfo nextFileInfo; + + // Loop protection + QSet visitedLinks; QDirIterator *q; }; @@ -131,12 +134,12 @@ public: */ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList &nameFilters, QDir::Filters filters, QDirIterator::IteratorFlags flags) - : engine(QAbstractFileEngine::create(path)), path(path), iteratorFlags(flags), - filters(filters), nameFilters(nameFilters) + : engine(QAbstractFileEngine::create(path)) + , path(path) + , nameFilters(nameFilters) + , filters(QDir::NoFilter == filters ? QDir::AllEntries : filters) + , iteratorFlags(flags) { - if (QDir::NoFilter == filters) - this->filters = QDir::AllEntries; - // Populate fields for hasNext() and next() pushDirectory(QFileInfo(path)); advance(); -- cgit v0.12 From 8aaf775d3746529e8efa5110673a274ac6a7f8d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Jul 2009 12:49:01 +0200 Subject: QDirIterator refactoring '*' is functionally the same as having no name filters. Equating the equivalence in the constructor avoids repeated checks in the advance "loop". Reviewed-by: Olivier Goffart --- src/corelib/io/qdiriterator.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 371e822..f7df836 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -136,7 +136,7 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList QDir::Filters filters, QDirIterator::IteratorFlags flags) : engine(QAbstractFileEngine::create(path)) , path(path) - , nameFilters(nameFilters) + , nameFilters(nameFilters.contains(QLatin1String("*")) ? QStringList() : nameFilters) , filters(QDir::NoFilter == filters ? QDir::AllEntries : filters) , iteratorFlags(flags) { @@ -270,10 +270,9 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf return false; // name filter -#ifndef QT_NO_REGEXP - const bool hasNameFilters = !nameFilters.isEmpty() && !(nameFilters.contains(QLatin1String("*"))); +#ifndef QT_NO_REGEXP // Pass all entries through name filters, except dirs if the AllDirs - if (hasNameFilters && !((filters & QDir::AllDirs) && fi.isDir())) { + if (!nameFilters.isEmpty() && !((filters & QDir::AllDirs) && fi.isDir())) { bool matched = false; for (int i = 0; i < nameFilters.size(); ++i) { QRegExp regexp(nameFilters.at(i), @@ -377,7 +376,7 @@ QDirIterator::QDirIterator(const QDir &dir, IteratorFlags flags) \sa hasNext(), next(), IteratorFlags */ QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorFlags flags) - : d(new QDirIteratorPrivate(path, QStringList(QLatin1String("*")), filters, flags)) + : d(new QDirIteratorPrivate(path, QStringList(), filters, flags)) { d->q = this; } @@ -395,7 +394,7 @@ QDirIterator::QDirIterator(const QString &path, QDir::Filters filters, IteratorF \sa hasNext(), next(), IteratorFlags */ QDirIterator::QDirIterator(const QString &path, IteratorFlags flags) - : d(new QDirIteratorPrivate(path, QStringList(QLatin1String("*")), QDir::NoFilter, flags)) + : d(new QDirIteratorPrivate(path, QStringList(), QDir::NoFilter, flags)) { d->q = this; } -- cgit v0.12 From 023f285c3ac8ea71aa8d4662242b41fb82fb7896 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Jul 2009 12:56:52 +0200 Subject: QDirIterator refactoring Name filters and resulting regular expressions are stable, no need to regenerate the latter on each iteration. Reviewed-by: Olivier Goffart --- src/corelib/io/qdiriterator.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index f7df836..9dda4f6 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -119,6 +119,10 @@ public: const QDir::Filters filters; const QDirIterator::IteratorFlags iteratorFlags; +#ifndef QT_NO_REGEXP + QVector nameRegExps; +#endif + QStack fileEngineIterators; QFileInfo currentFileInfo; QFileInfo nextFileInfo; @@ -140,6 +144,15 @@ QDirIteratorPrivate::QDirIteratorPrivate(const QString &path, const QStringList , filters(QDir::NoFilter == filters ? QDir::AllEntries : filters) , iteratorFlags(flags) { +#ifndef QT_NO_REGEXP + nameRegExps.reserve(nameFilters.size()); + for (int i = 0; i < nameFilters.size(); ++i) + nameRegExps.append( + QRegExp(nameFilters.at(i), + (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive, + QRegExp::Wildcard)); +#endif + // Populate fields for hasNext() and next() pushDirectory(QFileInfo(path)); advance(); @@ -274,11 +287,11 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf // Pass all entries through name filters, except dirs if the AllDirs if (!nameFilters.isEmpty() && !((filters & QDir::AllDirs) && fi.isDir())) { bool matched = false; - for (int i = 0; i < nameFilters.size(); ++i) { - QRegExp regexp(nameFilters.at(i), - (filters & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive, - QRegExp::Wildcard); - if (regexp.exactMatch(fileName)) { + for (QVector::const_iterator iter = nameRegExps.constBegin(), + end = nameRegExps.constEnd(); + iter != end; ++iter) { + + if (iter->exactMatch(fileName)) { matched = true; break; } -- cgit v0.12 From 8e743bc5e4d697d3204a8d7d861afe81927af3ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Jul 2009 12:59:00 +0200 Subject: Don't hide errors in QDirIterator Empty filenames should only show up from bugs in file engine iterators's hasNext() function. We shouldn't try to hide those here. Reviewed-by: Olivier Goffart --- src/corelib/io/qdiriterator.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 9dda4f6..3bfea65 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -269,10 +269,7 @@ void QDirIteratorPrivate::checkAndPushDirectory(const QFileInfo &fileInfo) */ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInfo &fi) const { - if (fileName.isEmpty()) { - // invalid entry - return false; - } + Q_ASSERT(!fileName.isEmpty()); // filter . and ..? const int fileNameSize = fileName.size(); -- cgit v0.12 From e3821cbae6f961a0e3a44f0863a3fd3424b540ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Jul 2009 13:02:38 +0200 Subject: Off-by-one error in QResourceFileEngineIterator This was making the resource iterator return empty entries after listing resources. This showed up after QDirIterator stopped filtering empty entries. Reviewed-by: Olivier Goffart --- src/corelib/io/qresource_iterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qresource_iterator.cpp b/src/corelib/io/qresource_iterator.cpp index e97ac59..025fccf 100644 --- a/src/corelib/io/qresource_iterator.cpp +++ b/src/corelib/io/qresource_iterator.cpp @@ -79,7 +79,7 @@ bool QResourceFileEngineIterator::hasNext() const that->index = 0; } - return index <= entries.size(); + return index < entries.size(); } QString QResourceFileEngineIterator::currentFileName() const -- cgit v0.12 From 90a3286841255132c96a2481a76c8b80c0728750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Jul 2009 13:08:45 +0200 Subject: Bugfix/optimization in QResourceFileEngineIterator If the resource is valid, children should not be empty. If it happens to be, hasNext() should then return false. Setting the index to 0 ensures this and also that we don't keep trying the same thing over and over. Reviewed-by: Olivier Goffart --- src/corelib/io/qresource_iterator.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/corelib/io/qresource_iterator.cpp b/src/corelib/io/qresource_iterator.cpp index 025fccf..7e22600 100644 --- a/src/corelib/io/qresource_iterator.cpp +++ b/src/corelib/io/qresource_iterator.cpp @@ -75,8 +75,7 @@ bool QResourceFileEngineIterator::hasNext() const // Initialize and move to the next entry. QResourceFileEngineIterator *that = const_cast(this); that->entries = resource.children(); - if (!that->entries.isEmpty()) - that->index = 0; + that->index = 0; } return index < entries.size(); -- cgit v0.12 From 51f4d0c1926335977c2aa814746a61b194d2f9d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Jul 2009 13:39:12 +0200 Subject: Prefer mutable over const_cast. Reviewed-by: Simon Hausmann Reviewed-by: Frans Englich --- src/corelib/io/qresource_iterator.cpp | 5 ++--- src/corelib/io/qresource_iterator_p.h | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/corelib/io/qresource_iterator.cpp b/src/corelib/io/qresource_iterator.cpp index 7e22600..11f4acf 100644 --- a/src/corelib/io/qresource_iterator.cpp +++ b/src/corelib/io/qresource_iterator.cpp @@ -73,9 +73,8 @@ bool QResourceFileEngineIterator::hasNext() const return false; // Initialize and move to the next entry. - QResourceFileEngineIterator *that = const_cast(this); - that->entries = resource.children(); - that->index = 0; + entries = resource.children(); + index = 0; } return index < entries.size(); diff --git a/src/corelib/io/qresource_iterator_p.h b/src/corelib/io/qresource_iterator_p.h index b5e8382..5165157 100644 --- a/src/corelib/io/qresource_iterator_p.h +++ b/src/corelib/io/qresource_iterator_p.h @@ -71,8 +71,8 @@ public: QString currentFileName() const; private: - QStringList entries; - int index; + mutable QStringList entries; + mutable int index; }; QT_END_NAMESPACE -- cgit v0.12 From 1223a21a737e9fded46f2c761532bf535fb943b1 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 22 Jul 2009 14:33:19 +0200 Subject: Fix memory leak. The signal could be connected a huge number of times This is already fixed in master with Qt:UniqueConnection Task-number: 258381 --- src/gui/widgets/qtoolbarlayout.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/widgets/qtoolbarlayout.cpp b/src/gui/widgets/qtoolbarlayout.cpp index 0d1a4b3..e55b754 100644 --- a/src/gui/widgets/qtoolbarlayout.cpp +++ b/src/gui/widgets/qtoolbarlayout.cpp @@ -127,6 +127,8 @@ void QToolBarLayout::setUsePopupMenu(bool set) if (!dirty && ((popupMenu == 0) == set)) invalidate(); if (!set) { + QObject::disconnect(extension, SIGNAL(clicked(bool)), + this, SLOT(setExpanded(bool))); QObject::connect(extension, SIGNAL(clicked(bool)), this, SLOT(setExpanded(bool))); extension->setPopupMode(QToolButton::DelayedPopup); -- cgit v0.12 From 1a55f40b6223511d0eb388064597ab38a0d37627 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Wed, 22 Jul 2009 15:10:35 +0200 Subject: Make QStateMachine inherit QState This removes the need for a "root state" in the machine; or rather, the machine _is_ the root state. User code can now pass in a QStateMachine directly to the QState constructor, instead of machine->rootState(). This also means we could get rid of the "proxying" from the machine to the root state for things like properties (initialState et al), finished() signal and auto-reparenting of states (the ChildAdded event hack). A fun little side-effect of this change is that it's now possible to embed state machines within state machines. We can't think of a good use case yet where you would rather embed a stand-alone state machine (with its own event processing etc.) rather than having just a regular nested state, but it's neat and it works. Reviewed-by: Eskil Abrahamsen Blomfeldt --- examples/animation/appchooser/main.cpp | 2 +- examples/animation/moveblocks/main.cpp | 6 +- examples/animation/states/main.cpp | 7 +- examples/animation/stickman/lifecycle.cpp | 6 +- examples/animation/sub-attaq/boat.cpp | 10 +- examples/animation/sub-attaq/bomb.cpp | 4 +- examples/animation/sub-attaq/graphicsscene.cpp | 8 +- examples/animation/sub-attaq/states.cpp | 8 +- examples/animation/sub-attaq/submarine.cpp | 6 +- examples/animation/sub-attaq/torpedo.cpp | 4 +- examples/statemachine/factorial/main.cpp | 4 +- examples/statemachine/tankgame/mainwindow.cpp | 6 +- src/corelib/statemachine/qabstracttransition.cpp | 15 +- src/corelib/statemachine/qstate.cpp | 24 +- src/corelib/statemachine/qstatemachine.cpp | 255 ++++------- src/corelib/statemachine/qstatemachine.h | 22 +- src/corelib/statemachine/qstatemachine_p.h | 17 +- tests/auto/qstate/tst_qstate.cpp | 12 +- tests/auto/qstatemachine/tst_qstatemachine.cpp | 511 ++++++++++++----------- 19 files changed, 428 insertions(+), 499 deletions(-) diff --git a/examples/animation/appchooser/main.cpp b/examples/animation/appchooser/main.cpp index fe4be1f..97751b2 100644 --- a/examples/animation/appchooser/main.cpp +++ b/examples/animation/appchooser/main.cpp @@ -134,7 +134,7 @@ int main(int argc, char **argv) QStateMachine machine; machine.setGlobalRestorePolicy(QStateMachine::RestoreProperties); - QState *group = new QState(machine.rootState()); + QState *group = new QState(&machine); group->setObjectName("group"); QRect selectedRect(86, 86, 128, 128); diff --git a/examples/animation/moveblocks/main.cpp b/examples/animation/moveblocks/main.cpp index c43e841..97d3f81 100644 --- a/examples/animation/moveblocks/main.cpp +++ b/examples/animation/moveblocks/main.cpp @@ -108,8 +108,7 @@ class StateSwitcher : public QState Q_OBJECT public: StateSwitcher(QStateMachine *machine) - : QState(machine->rootState()), m_machine(machine), - m_stateCount(0), m_lastIndex(0) + : QState(machine), m_stateCount(0), m_lastIndex(0) { } //![10] @@ -120,7 +119,7 @@ public: while ((n = (qrand() % m_stateCount + 1)) == m_lastIndex) { } m_lastIndex = n; - m_machine->postEvent(new StateSwitchEvent(n)); + machine()->postEvent(new StateSwitchEvent(n)); } virtual void onExit(QEvent *) {} //![11] @@ -135,7 +134,6 @@ public: //![12] private: - QStateMachine *m_machine; int m_stateCount; int m_lastIndex; }; diff --git a/examples/animation/states/main.cpp b/examples/animation/states/main.cpp index b3c28f2..99e04c3 100644 --- a/examples/animation/states/main.cpp +++ b/examples/animation/states/main.cpp @@ -124,10 +124,9 @@ int main(int argc, char *argv[]) scene.addItem(p6); QStateMachine machine; - QState *root = machine.rootState(); - QState *state1 = new QState(root); - QState *state2 = new QState(root); - QState *state3 = new QState(root); + QState *state1 = new QState(&machine); + QState *state2 = new QState(&machine); + QState *state3 = new QState(&machine); machine.setInitialState(state1); // State 1 diff --git a/examples/animation/stickman/lifecycle.cpp b/examples/animation/stickman/lifecycle.cpp index 2a54c82..c761d87 100644 --- a/examples/animation/stickman/lifecycle.cpp +++ b/examples/animation/stickman/lifecycle.cpp @@ -108,11 +108,11 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) m_machine->addDefaultAnimation(m_animationGroup); //! [3] - m_alive = new QState(m_machine->rootState()); + m_alive = new QState(m_machine); m_alive->setObjectName("alive"); // Make it blink when lightning strikes before entering dead animation - QState *lightningBlink = new QState(m_machine->rootState()); + QState *lightningBlink = new QState(m_machine); lightningBlink->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::white); lightningBlink->assignProperty(m_stickMan, "penColor", Qt::black); lightningBlink->assignProperty(m_stickMan, "fillColor", Qt::white); @@ -126,7 +126,7 @@ LifeCycle::LifeCycle(StickMan *stickMan, GraphicsView *keyReceiver) QObject::connect(lightningBlink, SIGNAL(exited()), timer, SLOT(stop())); //! [5] - m_dead = new QState(m_machine->rootState()); + m_dead = new QState(m_machine); m_dead->assignProperty(m_stickMan->scene(), "backgroundBrush", Qt::black); m_dead->assignProperty(m_stickMan, "penColor", Qt::white); m_dead->assignProperty(m_stickMan, "fillColor", Qt::black); diff --git a/examples/animation/sub-attaq/boat.cpp b/examples/animation/sub-attaq/boat.cpp index d286be5..68e646e 100644 --- a/examples/animation/sub-attaq/boat.cpp +++ b/examples/animation/sub-attaq/boat.cpp @@ -142,14 +142,14 @@ Boat::Boat(QGraphicsItem * parent, Qt::WindowFlags wFlags) //We setup the state machien of the boat machine = new QStateMachine(this); - QState *moving = new QState(machine->rootState()); + QState *moving = new QState(machine); StopState *stopState = new StopState(this, moving); machine->setInitialState(moving); moving->setInitialState(stopState); MoveStateRight *moveStateRight = new MoveStateRight(this, moving); MoveStateLeft *moveStateLeft = new MoveStateLeft(this, moving); - LaunchStateRight *launchStateRight = new LaunchStateRight(this, machine->rootState()); - LaunchStateLeft *launchStateLeft = new LaunchStateLeft(this, machine->rootState()); + LaunchStateRight *launchStateRight = new LaunchStateRight(this, machine); + LaunchStateLeft *launchStateLeft = new LaunchStateLeft(this, machine); //then setup the transitions for the rightMove state KeyStopTransition *leftStopRight = new KeyStopTransition(this, QEvent::KeyPress, Qt::Key_Left); @@ -216,10 +216,10 @@ Boat::Boat(QGraphicsItem * parent, Qt::WindowFlags wFlags) launchStateLeft->addTransition(historyState); launchStateRight->addTransition(historyState); - QFinalState *final = new QFinalState(machine->rootState()); + QFinalState *final = new QFinalState(machine); //This state play the destroyed animation - QAnimationState *destroyedState = new QAnimationState(machine->rootState()); + QAnimationState *destroyedState = new QAnimationState(machine); destroyedState->setAnimation(destroyAnimation); //Play a nice animation when the boat is destroyed diff --git a/examples/animation/sub-attaq/bomb.cpp b/examples/animation/sub-attaq/bomb.cpp index 454970a..e92a723 100644 --- a/examples/animation/sub-attaq/bomb.cpp +++ b/examples/animation/sub-attaq/bomb.cpp @@ -85,11 +85,11 @@ void Bomb::launch(Bomb::Direction direction) QStateMachine *machine = new QStateMachine(this); //This state is when the launch animation is playing - QAnimationState *launched = new QAnimationState(machine->rootState()); + QAnimationState *launched = new QAnimationState(machine); launched->setAnimation(launchAnimation); //End - QFinalState *final = new QFinalState(machine->rootState()); + QFinalState *final = new QFinalState(machine); machine->setInitialState(launched); diff --git a/examples/animation/sub-attaq/graphicsscene.cpp b/examples/animation/sub-attaq/graphicsscene.cpp index bd37ce2..fcbc1b3 100644 --- a/examples/animation/sub-attaq/graphicsscene.cpp +++ b/examples/animation/sub-attaq/graphicsscene.cpp @@ -230,17 +230,17 @@ void GraphicsScene::setupScene(const QList &actions) QStateMachine *machine = new QStateMachine(this); //This state is when the player is playing - PlayState *gameState = new PlayState(this,machine->rootState()); + PlayState *gameState = new PlayState(this,machine); //Final state - QFinalState *final = new QFinalState(machine->rootState()); + QFinalState *final = new QFinalState(machine); //Animation when the player enter in the game - QAnimationState *lettersMovingState = new QAnimationState(machine->rootState()); + QAnimationState *lettersMovingState = new QAnimationState(machine); lettersMovingState->setAnimation(lettersGroupMoving); //Animation when the welcome screen disappear - QAnimationState *lettersFadingState = new QAnimationState(machine->rootState()); + QAnimationState *lettersFadingState = new QAnimationState(machine); lettersFadingState->setAnimation(lettersGroupFading); //if new game then we fade out the welcome screen and start playing diff --git a/examples/animation/sub-attaq/states.cpp b/examples/animation/sub-attaq/states.cpp index 81fd2de..d63737f 100644 --- a/examples/animation/sub-attaq/states.cpp +++ b/examples/animation/sub-attaq/states.cpp @@ -83,7 +83,7 @@ void PlayState::onEntry(QEvent *) machine = new QStateMachine(this); //This state is when player is playing - LevelState *levelState = new LevelState(scene, this, machine->rootState()); + LevelState *levelState = new LevelState(scene, this, machine); //This state is when the player is actually playing but the game is not paused QState *playingState = new QState(levelState); @@ -105,10 +105,10 @@ void PlayState::onEntry(QEvent *) pauseState->addTransition(pressPpause); //This state is when player have lost - LostState *lostState = new LostState(scene, this, machine->rootState()); + LostState *lostState = new LostState(scene, this, machine); //This state is when player have won - WinState *winState = new WinState(scene, this, machine->rootState()); + WinState *winState = new WinState(scene, this, machine); //The boat has been destroyed then the game is finished levelState->addTransition(scene->boat, SIGNAL(boatExecutionFinished()),lostState); @@ -136,7 +136,7 @@ void PlayState::onEntry(QEvent *) machine->setInitialState(levelState); //Final state - QFinalState *final = new QFinalState(machine->rootState()); + QFinalState *final = new QFinalState(machine); //This transition is triggered when the player press space after completing a level CustomSpaceTransition *spaceTransition = new CustomSpaceTransition(scene->views().at(0), this, QEvent::KeyPress, Qt::Key_Space); diff --git a/examples/animation/sub-attaq/submarine.cpp b/examples/animation/sub-attaq/submarine.cpp index 04b7916..78a9539 100644 --- a/examples/animation/sub-attaq/submarine.cpp +++ b/examples/animation/sub-attaq/submarine.cpp @@ -115,7 +115,7 @@ SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * QStateMachine *machine = new QStateMachine(this); //This state is when the boat is moving/rotating - QState *moving = new QState(machine->rootState()); + QState *moving = new QState(machine); //This state is when the boat is moving from left to right MovementState *movement = new MovementState(this, moving); @@ -132,7 +132,7 @@ SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * machine->setInitialState(moving); //End - QFinalState *final = new QFinalState(machine->rootState()); + QFinalState *final = new QFinalState(machine); //If the moving animation is finished we move to the return state movement->addTransition(movement, SIGNAL(animationFinished()), rotation); @@ -141,7 +141,7 @@ SubMarine::SubMarine(int type, const QString &name, int points, QGraphicsItem * rotation->addTransition(rotation, SIGNAL(animationFinished()), movement); //This state play the destroyed animation - QAnimationState *destroyedState = new QAnimationState(machine->rootState()); + QAnimationState *destroyedState = new QAnimationState(machine); destroyedState->setAnimation(setupDestroyAnimation(this)); //Play a nice animation when the submarine is destroyed diff --git a/examples/animation/sub-attaq/torpedo.cpp b/examples/animation/sub-attaq/torpedo.cpp index 5ef237a..fe79488 100644 --- a/examples/animation/sub-attaq/torpedo.cpp +++ b/examples/animation/sub-attaq/torpedo.cpp @@ -74,11 +74,11 @@ void Torpedo::launch() QStateMachine *machine = new QStateMachine(this); //This state is when the launch animation is playing - QAnimationState *launched = new QAnimationState(machine->rootState()); + QAnimationState *launched = new QAnimationState(machine); launched->setAnimation(launchAnimation); //End - QFinalState *final = new QFinalState(machine->rootState()); + QFinalState *final = new QFinalState(machine); machine->setInitialState(launched); diff --git a/examples/statemachine/factorial/main.cpp b/examples/statemachine/factorial/main.cpp index 18a9521..5050347 100644 --- a/examples/statemachine/factorial/main.cpp +++ b/examples/statemachine/factorial/main.cpp @@ -151,14 +151,14 @@ int main(int argc, char **argv) //! [3] //! [4] - QState *compute = new QState(machine.rootState()); + QState *compute = new QState(&machine); compute->assignProperty(&factorial, "fac", 1); compute->assignProperty(&factorial, "x", 6); compute->addTransition(new FactorialLoopTransition(&factorial)); //! [4] //! [5] - QFinalState *done = new QFinalState(machine.rootState()); + QFinalState *done = new QFinalState(&machine); FactorialDoneTransition *doneTransition = new FactorialDoneTransition(&factorial); doneTransition->setTargetState(done); compute->addTransition(doneTransition); diff --git a/examples/statemachine/tankgame/mainwindow.cpp b/examples/statemachine/tankgame/mainwindow.cpp index 68a8d68..596cdfe 100644 --- a/examples/statemachine/tankgame/mainwindow.cpp +++ b/examples/statemachine/tankgame/mainwindow.cpp @@ -160,7 +160,7 @@ void MainWindow::init() connect(quitAction, SIGNAL(triggered()), this, SLOT(close())); m_machine = new QStateMachine(this); - QState *stoppedState = new QState(m_machine->rootState()); + QState *stoppedState = new QState(m_machine); stoppedState->setObjectName("stoppedState"); stoppedState->assignProperty(runGameAction, "enabled", true); stoppedState->assignProperty(stopGameAction, "enabled", false); @@ -188,14 +188,14 @@ void MainWindow::init() stoppedState->setInitialState(hs); //! [0] - m_runningState = new QState(QState::ParallelStates, m_machine->rootState()); + m_runningState = new QState(QState::ParallelStates, m_machine); //! [0] m_runningState->setObjectName("runningState"); m_runningState->assignProperty(addTankAction, "enabled", false); m_runningState->assignProperty(runGameAction, "enabled", false); m_runningState->assignProperty(stopGameAction, "enabled", true); - QState *gameOverState = new QState(m_machine->rootState()); + QState *gameOverState = new QState(m_machine); gameOverState->setObjectName("gameOverState"); gameOverState->assignProperty(stopGameAction, "enabled", false); connect(gameOverState, SIGNAL(entered()), this, SLOT(gameOver())); diff --git a/src/corelib/statemachine/qabstracttransition.cpp b/src/corelib/statemachine/qabstracttransition.cpp index 670aa7d..0004d3e 100644 --- a/src/corelib/statemachine/qabstracttransition.cpp +++ b/src/corelib/statemachine/qabstracttransition.cpp @@ -115,13 +115,10 @@ QAbstractTransitionPrivate *QAbstractTransitionPrivate::get(QAbstractTransition QStateMachine *QAbstractTransitionPrivate::machine() const { - QObject *par = parent; - while (par != 0) { - if (QStateMachine *mach = qobject_cast(par)) - return mach; - par = par->parent(); - } - return 0; + QState *source = sourceState(); + if (!source) + return 0; + return source->machine(); } bool QAbstractTransitionPrivate::callEventTest(QEvent *e) @@ -256,10 +253,6 @@ void QAbstractTransition::setTargetStates(const QList &targets) qWarning("QAbstractTransition::setTargetStates: target state(s) cannot be null"); return; } - if (target->machine() != 0 && target->machine()->rootState() == target) { - qWarning("QAbstractTransition::setTargetStates: root state cannot be target of transition"); - return; - } } d->targetStates.clear(); diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index 83dd869..f74edc3 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -71,7 +71,7 @@ QT_BEGIN_NAMESPACE The assignProperty() function is used for defining property assignments that should be performed when a state is entered. - Top-level states must be passed QStateMachine::rootState() as their parent + Top-level states must be passed a QStateMachine object as their parent state, or added to a state machine using QStateMachine::addState(). \section1 States with Child States @@ -242,7 +242,7 @@ void QState::assignProperty(QObject *object, const char *name, /*! Returns this state's error state. - \sa QStateMachine::errorState(), QStateMachine::setErrorState() + \sa QStateMachine::error() */ QAbstractState *QState::errorState() const { @@ -256,19 +256,17 @@ QAbstractState *QState::errorState() const state recursively. If no error state is set for the state itself or any of its ancestors, an error will cause the machine to stop executing and an error will be printed to the console. - - \sa QStateMachine::setErrorState(), QStateMachine::errorState() */ void QState::setErrorState(QAbstractState *state) { Q_D(QState); - if (state != 0 && state->machine() != machine()) { - qWarning("QState::setErrorState: error state cannot belong " - "to a different state machine"); + if (state != 0 && qobject_cast(state)) { + qWarning("QStateMachine::setErrorState: root state cannot be error state"); return; } - if (state != 0 && state->machine() != 0 && state->machine()->rootState() == state) { - qWarning("QStateMachine::setErrorState: root state cannot be error state"); + if (state != 0 && (!state->machine() || ((state->machine() != machine()) && !qobject_cast(this)))) { + qWarning("QState::setErrorState: error state cannot belong " + "to a different state machine"); return; } @@ -288,12 +286,7 @@ QAbstractTransition *QState::addTransition(QAbstractTransition *transition) return 0; } - // machine() will always be non-null for root state - if (machine() != 0 && machine()->rootState() == this) { - qWarning("QState::addTransition: cannot add transition from root state"); - return 0; - } - + transition->setParent(this); const QList > &targets = QAbstractTransitionPrivate::get(transition)->targetStates; for (int i = 0; i < targets.size(); ++i) { QAbstractState *t = targets.at(i); @@ -308,7 +301,6 @@ QAbstractTransition *QState::addTransition(QAbstractTransition *transition) return 0; } } - transition->setParent(this); if (machine() != 0 && machine()->configuration().contains(this)) QStateMachinePrivate::get(machine())->registerTransitions(this); return transition; diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index a00e7e1..5402b04 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -102,14 +102,9 @@ QT_BEGIN_NAMESPACE Framework}{overview} gives several state graphs and the code to build them. - The rootState() is the parent of all top-level states in the - machine; it is used, for instance, when the state graph is - deleted. It is created by the machine. - - Use the addState() function to add a state to the state machine. - All top-level states are added to the root state. States are - removed with the removeState() function. Removing states while the - machine is running is discouraged. + Use the addState() function to add a top-level state to the state machine. + States are removed with the removeState() function. Removing states while + the machine is running is discouraged. Before the machine can be started, the \l{initialState}{initial state} must be set. The initial state is the state that the @@ -179,26 +174,6 @@ This is */ /*! - \property QStateMachine::rootState - - \brief the root state of this state machine -*/ - -/*! - \property QStateMachine::initialState - - \brief the initial state of this state machine - - The initial state must be one of the rootState()'s child states. -*/ - -/*! - \property QStateMachine::errorState - - \brief the error state of this state machine -*/ - -/*! \property QStateMachine::errorString \brief the error string of this state machine @@ -235,7 +210,6 @@ QStateMachinePrivate::QStateMachinePrivate() stop = false; error = QStateMachine::NoError; globalRestorePolicy = QStateMachine::DoNotRestoreProperties; - rootState = 0; signalEventGenerator = 0; #ifndef QT_NO_ANIMATION animationsEnabled = true; @@ -255,6 +229,11 @@ QStateMachinePrivate *QStateMachinePrivate::get(QStateMachine *q) return 0; } +QState *QStateMachinePrivate::rootState() const +{ + return const_cast(q_func()); +} + static QEvent *cloneEvent(QEvent *e) { switch (e->type()) { @@ -302,7 +281,9 @@ bool QStateMachinePrivate::stateEntryLessThan(QAbstractState *s1, QAbstractState } else if (isDescendantOf(s2, s1)) { return true; } else { - QState *lca = findLCA(QList() << s1 << s2); + Q_ASSERT(s1->machine() != 0); + QStateMachinePrivate *mach = QStateMachinePrivate::get(s1->machine()); + QState *lca = mach->findLCA(QList() << s1 << s2); Q_ASSERT(lca != 0); return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2)); } @@ -318,17 +299,19 @@ bool QStateMachinePrivate::stateExitLessThan(QAbstractState *s1, QAbstractState } else if (isDescendantOf(s2, s1)) { return false; } else { - QState *lca = findLCA(QList() << s1 << s2); + Q_ASSERT(s1->machine() != 0); + QStateMachinePrivate *mach = QStateMachinePrivate::get(s1->machine()); + QState *lca = mach->findLCA(QList() << s1 << s2); Q_ASSERT(lca != 0); return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2)); } } -QState *QStateMachinePrivate::findLCA(const QList &states) +QState *QStateMachinePrivate::findLCA(const QList &states) const { if (states.isEmpty()) return 0; - QList ancestors = properAncestors(states.at(0), 0); + QList ancestors = properAncestors(states.at(0), rootState()->parentState()); for (int i = 0; i < ancestors.size(); ++i) { QState *anc = ancestors.at(i); bool ok = true; @@ -376,7 +359,7 @@ QSet QStateMachinePrivate::selectTransitions(QEvent *event continue; if (isPreempted(state, enabledTransitions)) continue; - QList lst = properAncestors(state, 0); + QList lst = properAncestors(state, rootState()->parentState()); if (QState *grp = qobject_cast(state)) lst.prepend(grp); bool found = false; @@ -557,11 +540,13 @@ QList QStateMachinePrivate::enterStates(QEvent *event, const QL if (isFinal(s)) { QState *parent = s->parentState(); if (parent) { - QState *grandparent = parent->parentState(); + if (parent != rootState()) { #ifdef QSTATEMACHINE_DEBUG - qDebug() << q << ": emitting finished signal for" << parent; + qDebug() << q << ": emitting finished signal for" << parent; #endif - QStatePrivate::get(parent)->emitFinished(); + QStatePrivate::get(parent)->emitFinished(); + } + QState *grandparent = parent->parentState(); if (grandparent && isParallel(grandparent)) { bool allChildStatesFinal = true; QList childStates = QStatePrivate::get(grandparent)->childStates(); @@ -572,7 +557,7 @@ QList QStateMachinePrivate::enterStates(QEvent *event, const QL break; } } - if (allChildStatesFinal) { + if (allChildStatesFinal && (grandparent != rootState())) { #ifdef QSTATEMACHINE_DEBUG qDebug() << q << ": emitting finished signal for" << grandparent; #endif @@ -585,7 +570,7 @@ QList QStateMachinePrivate::enterStates(QEvent *event, const QL { QSet::const_iterator it; for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) { - if (isFinal(*it) && (*it)->parentState() == rootState) { + if (isFinal(*it) && (*it)->parentState() == rootState()) { processing = false; stopProcessingReason = Finished; break; @@ -630,6 +615,11 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, } } } else { + if (s == rootState()) { + // Error has already been set by exitStates(). + Q_ASSERT(error != QStateMachine::NoError); + return; + } statesToEnter.insert(s); if (isParallel(s)) { QState *grp = qobject_cast(s); @@ -643,6 +633,7 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, QState *grp = qobject_cast(s); QAbstractState *initial = grp->initialState(); if (initial != 0) { + Q_ASSERT(initial->machine() == q_func()); addStatesToEnter(initial, grp, statesToEnter, statesForDefaultEntry); } else { setError(QStateMachine::NoInitialStateError, grp); @@ -873,20 +864,26 @@ bool QStateMachinePrivate::isParallel(const QAbstractState *s) return ss && (QStatePrivate::get(ss)->childMode == QState::ParallelStates); } -bool QStateMachinePrivate::isCompound(const QAbstractState *s) +bool QStateMachinePrivate::isCompound(const QAbstractState *s) const { const QState *group = qobject_cast(s); if (!group) return false; + bool isMachine = (qobject_cast(group) != 0); + // Don't treat the machine as compound if it's a sub-state of this machine + if (isMachine && (group != rootState())) + return false; return (!isParallel(group) && !QStatePrivate::get(group)->childStates().isEmpty()) - || (qobject_cast(group->parent()) != 0); + || isMachine; } -bool QStateMachinePrivate::isAtomic(const QAbstractState *s) +bool QStateMachinePrivate::isAtomic(const QAbstractState *s) const { const QState *ss = qobject_cast(s); return (ss && QStatePrivate::get(ss)->childStates().isEmpty()) - || isFinal(s); + || isFinal(s) + // Treat the machine as atomic if it's a sub-state of this machine + || (ss && (qobject_cast(ss) != 0) && (ss != rootState())); } @@ -1034,7 +1031,7 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta if (currentContext == currentErrorState) currentErrorState = 0; - Q_ASSERT(currentErrorState != rootState); + Q_ASSERT(currentErrorState != rootState()); if (currentErrorState != 0) { QState *lca = findLCA(QList() << currentErrorState << currentContext); @@ -1141,11 +1138,8 @@ void QStateMachinePrivate::_q_start() { Q_Q(QStateMachine); Q_ASSERT(state == Starting); - if (!rootState) { - state = NotRunning; - return; - } - QAbstractState *initial = rootState->initialState(); + Q_ASSERT(rootState() != 0); + QAbstractState *initial = rootState()->initialState(); configuration.clear(); qDeleteAll(internalEventQueue); internalEventQueue.clear(); @@ -1159,7 +1153,7 @@ void QStateMachinePrivate::_q_start() processingScheduled = true; // we call _q_process() below emit q->started(); - StartState *start = new StartState(rootState); + StartState *start = new StartState(rootState()); QAbstractTransition *initialTransition = new InitialTransition(initial); start->addTransition(initialTransition); QList transitions; @@ -1371,15 +1365,22 @@ void QStateMachinePrivate::unregisterSignalTransition(QSignalTransition *transit void QStateMachinePrivate::unregisterAllTransitions() { + Q_Q(QStateMachine); { - QList transitions = qFindChildren(rootState); - for (int i = 0; i < transitions.size(); ++i) - unregisterSignalTransition(transitions.at(i)); + QList transitions = qFindChildren(rootState()); + for (int i = 0; i < transitions.size(); ++i) { + QSignalTransition *t = transitions.at(i); + if (t->machine() == q) + unregisterSignalTransition(t); + } } { - QList transitions = qFindChildren(rootState); - for (int i = 0; i < transitions.size(); ++i) - unregisterEventTransition(transitions.at(i)); + QList transitions = qFindChildren(rootState()); + for (int i = 0; i < transitions.size(); ++i) { + QEventTransition *t = transitions.at(i); + if (t->machine() == q) + unregisterEventTransition(t); + } } } @@ -1457,16 +1458,20 @@ void QStateMachinePrivate::handleTransitionSignal(const QObject *sender, int sig Constructs a new state machine with the given \a parent. */ QStateMachine::QStateMachine(QObject *parent) - : QObject(*new QStateMachinePrivate, parent) + : QState(*new QStateMachinePrivate, /*parentState=*/0) { + // Can't pass the parent to the QState constructor, as it expects a QState + // But this works as expected regardless of whether parent is a QState or not + setParent(parent); } /*! \internal */ QStateMachine::QStateMachine(QStateMachinePrivate &dd, QObject *parent) - : QObject(dd, parent) + : QState(dd, /*parentState=*/0) { + setParent(parent); } /*! @@ -1476,69 +1481,6 @@ QStateMachine::~QStateMachine() { } -namespace { - -class RootState : public QState -{ -public: - RootState(QState *parent) - : QState(parent) - { - } - - void onEntry(QEvent *) {} - void onExit(QEvent *) {} -}; - -} // namespace - -/*! - Returns this state machine's root state. -*/ -QState *QStateMachine::rootState() const -{ - Q_D(const QStateMachine); - if (!d->rootState) { - const_cast(d)->rootState = new RootState(0); - d->rootState->setParent(const_cast(this)); - } - return d->rootState; -} - -/*! - Returns the error state of the state machine's root state. - - \sa QState::errorState() -*/ -QAbstractState *QStateMachine::errorState() const -{ - return rootState()->errorState(); -} - -/*! - Sets the error state of this state machine's root state to be \a state. When a running state - machine encounters an error which puts it in an undefined state, it will enter an error state - based on the context of the error that occurred. It will enter this state regardless of what - is currently in the event queue. - - If the erroneous state has an error state set, this will be entered by the machine. If no error - state has been set, the state machine will search the parent hierarchy recursively for an - error state. The error state of the root state can thus be seen as a global error state that - applies for all states for which a more specific error state has not been set. - - Before entering the error state, the state machine will set the error code returned by error() and - error message returned by errorString(). - - If there is no error state available for the erroneous state, the state machine will print a - warning message on the console and stop executing. - - \sa QState::setErrorState(), rootState() -*/ -void QStateMachine::setErrorState(QAbstractState *state) -{ - rootState()->setErrorState(state); -} - /*! \enum QStateMachine::Error This enum type defines errors that can occur in the state machine at run time. When the state @@ -1640,39 +1582,13 @@ void QStateMachine::setGlobalRestorePolicy(QStateMachine::RestorePolicy restoreP } /*! - Returns this state machine's initial state, or 0 if no initial state has - been set. -*/ -QAbstractState *QStateMachine::initialState() const -{ - Q_D(const QStateMachine); - if (!d->rootState) - return 0; - return d->rootState->initialState(); -} - -/*! - Sets this state machine's initial \a state. -*/ -void QStateMachine::setInitialState(QAbstractState *state) -{ - Q_D(QStateMachine); - if (!d->rootState) { - if (!state) - return; - rootState()->setInitialState(state); - } - d->rootState->setInitialState(state); -} - -/*! Adds the given \a state to this state machine. The state becomes a top-level - state (i.e. a child of the rootState()). + state. If the state is already in a different machine, it will first be removed from its old machine, and then added to this machine. - \sa removeState(), rootState(), setInitialState() + \sa removeState(), setInitialState() */ void QStateMachine::addState(QAbstractState *state) { @@ -1684,7 +1600,7 @@ void QStateMachine::addState(QAbstractState *state) qWarning("QStateMachine::addState: state has already been added to this machine"); return; } - state->setParent(rootState()); + state->setParent(this); } /*! @@ -1730,7 +1646,7 @@ void QStateMachine::start() { Q_D(QStateMachine); - if (rootState()->initialState() == 0) { + if (initialState() == 0) { qWarning("QStateMachine::start: No initial state set for machine. Refusing to start."); return; } @@ -1821,7 +1737,7 @@ void QStateMachine::postInternalEvent(QEvent *event) Returns the maximal consistent set of states (including parallel and final states) that this state machine is currently in. If a state \c s is in the configuration, it is always the case that the parent of \c s is also in - c. Note, however, that the rootState() is not an explicit member of the + c. Note, however, that the machine itself is not an explicit member of the configuration. */ QSet QStateMachine::configuration() const @@ -1840,15 +1756,6 @@ QSet QStateMachine::configuration() const */ /*! - \fn QStateMachine::finished() - - This signal is emitted when the state machine has reached a top-level final - state (QFinalState). - - \sa QStateMachine::started() -*/ - -/*! \fn QStateMachine::stopped() This signal is emitted when the state machine has stopped. @@ -1872,14 +1779,6 @@ bool QStateMachine::event(QEvent *e) d->scheduleProcess(); return true; } - } else if (e->type() == QEvent::ChildAdded) { - QChildEvent *ce = static_cast(e); - if (QAbstractState *state = qobject_cast(ce->child())) { - if (state != rootState()) { - state->setParent(rootState()); - return true; - } - } } return QObject::event(e); } @@ -1949,6 +1848,24 @@ void QStateMachine::endMicrostep(QEvent *event) Q_UNUSED(event); } +/*! + \reimp +*/ +void QStateMachine::onEntry(QEvent *event) +{ + start(); + QState::onEntry(event); +} + +/*! + \reimp +*/ +void QStateMachine::onExit(QEvent *event) +{ + stop(); + QState::onExit(event); +} + #ifndef QT_NO_ANIMATION /*! diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h index 30d0e3a..230d852 100644 --- a/src/corelib/statemachine/qstatemachine.h +++ b/src/corelib/statemachine/qstatemachine.h @@ -42,7 +42,7 @@ #ifndef QSTATEMACHINE_H #define QSTATEMACHINE_H -#include +#include #include #include @@ -57,18 +57,12 @@ QT_MODULE(Core) #ifndef QT_NO_STATEMACHINE class QEvent; -class QAbstractState; -class QState; class QStateMachinePrivate; class QAbstractAnimation; -class QAbstractState; -class Q_CORE_EXPORT QStateMachine : public QObject +class Q_CORE_EXPORT QStateMachine : public QState { Q_OBJECT - Q_PROPERTY(QState* rootState READ rootState) - Q_PROPERTY(QAbstractState* initialState READ initialState WRITE setInitialState) - Q_PROPERTY(QAbstractState* errorState READ errorState WRITE setErrorState) Q_PROPERTY(QString errorString READ errorString) Q_PROPERTY(RestorePolicy globalRestorePolicy READ globalRestorePolicy WRITE setGlobalRestorePolicy) Q_ENUMS(RestorePolicy) @@ -94,14 +88,6 @@ public: void addState(QAbstractState *state); void removeState(QAbstractState *state); - QState *rootState() const; - - QAbstractState *initialState() const; - void setInitialState(QAbstractState *state); - - QAbstractState *errorState() const; - void setErrorState(QAbstractState *state); - Error error() const; QString errorString() const; void clearError(); @@ -135,9 +121,11 @@ public Q_SLOTS: Q_SIGNALS: void started(); void stopped(); - void finished(); protected: + void onEntry(QEvent *event); + void onExit(QEvent *event); + void postInternalEvent(QEvent *event); virtual void beginSelectTransitions(QEvent *event); diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 1335b93..21e405d 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -53,7 +53,8 @@ // We mean it. // -#include +#include "private/qstate_p.h" + #include #include #include @@ -61,9 +62,6 @@ #include #include -#include "qstate.h" -#include "private/qstate_p.h" - QT_BEGIN_NAMESPACE class QEvent; @@ -81,7 +79,7 @@ class QAbstractAnimation; #endif class QStateMachine; -class QStateMachinePrivate : public QObjectPrivate +class QStateMachinePrivate : public QStatePrivate { Q_DECLARE_PUBLIC(QStateMachine) public: @@ -101,7 +99,7 @@ public: static QStateMachinePrivate *get(QStateMachine *q); - static QState *findLCA(const QList &states); + QState *findLCA(const QList &states) const; static bool stateEntryLessThan(QAbstractState *s1, QAbstractState *s2); static bool stateExitLessThan(QAbstractState *s1, QAbstractState *s2); @@ -116,6 +114,8 @@ public: void _q_animationFinished(); #endif + QState *rootState() const; + void microstep(QEvent *event, const QList &transitionList); bool isPreempted(const QAbstractState *s, const QSet &transitions) const; QSet selectTransitions(QEvent *event) const; @@ -133,8 +133,8 @@ public: bool isInFinalState(QAbstractState *s) const; static bool isFinal(const QAbstractState *s); static bool isParallel(const QAbstractState *s); - static bool isCompound(const QAbstractState *s); - static bool isAtomic(const QAbstractState *s); + bool isCompound(const QAbstractState *s) const; + bool isAtomic(const QAbstractState *s) const; static bool isDescendantOf(const QAbstractState *s, const QAbstractState *other); static QList properAncestors(const QAbstractState *s, const QState *upperBound); @@ -164,7 +164,6 @@ public: bool processingScheduled; bool stop; StopProcessingReason stopProcessingReason; - QState *rootState; QSet configuration; QList internalEventQueue; QList externalEventQueue; diff --git a/tests/auto/qstate/tst_qstate.cpp b/tests/auto/qstate/tst_qstate.cpp index ab87767..78b9853 100644 --- a/tests/auto/qstate/tst_qstate.cpp +++ b/tests/auto/qstate/tst_qstate.cpp @@ -60,10 +60,10 @@ tst_QState::~tst_QState() void tst_QState::test() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); QCOMPARE(s1->machine(), &machine); - QCOMPARE(s1->parentState(), machine.rootState()); + QCOMPARE(s1->parentState(), &machine); QCOMPARE(s1->initialState(), (QState*)0); QVERIFY(s1->childStates().isEmpty()); QVERIFY(s1->transitions().isEmpty()); @@ -218,7 +218,7 @@ void tst_QState::assignProperty() QObject *object = new QObject(); object->setProperty("fooBar", 10); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(object, "fooBar", 20); machine.setInitialState(s1); @@ -235,7 +235,7 @@ void tst_QState::assignPropertyTwice() QObject *object = new QObject(); object->setProperty("fooBar", 10); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(object, "fooBar", 20); s1->assignProperty(object, "fooBar", 30); @@ -271,9 +271,9 @@ void tst_QState::historyInitialState() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); QHistoryState *h1 = new QHistoryState(s2); s2->setInitialState(h1); diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp index 44fc998..7f4d9f5 100644 --- a/tests/auto/qstatemachine/tst_qstatemachine.cpp +++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp @@ -190,6 +190,8 @@ private slots: // void overrideDefaultSourceAnimationWithSpecific(); // void overrideDefaultTargetAnimationWithSpecific(); // void overrideDefaultTargetAnimationWithSource(); + + void nestedStateMachines(); }; tst_QStateMachine::tst_QStateMachine() @@ -259,13 +261,17 @@ private: void tst_QStateMachine::transitionToRootState() { QStateMachine machine; + machine.setObjectName("machine"); QState *initialState = new QState(); + initialState->setObjectName("initial"); machine.addState(initialState); machine.setInitialState(initialState); - QTest::ignoreMessage(QtWarningMsg, "QAbstractTransition::setTargetStates: root state cannot be target of transition"); - initialState->addTransition(new EventTransition(QEvent::User, machine.rootState())); + QAbstractTransition *trans = initialState->addTransition(new EventTransition(QEvent::User, &machine)); + QVERIFY(trans != 0); + QCOMPARE(trans->sourceState(), initialState); + QCOMPARE(trans->targetState(), &machine); machine.start(); QCoreApplication::processEvents(); @@ -274,22 +280,21 @@ void tst_QStateMachine::transitionToRootState() QVERIFY(machine.configuration().contains(initialState)); machine.postEvent(new QEvent(QEvent::User)); + QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: No common ancestor for targets and source of transition from state 'initial'"); QCoreApplication::processEvents(); - - QCOMPARE(machine.configuration().count(), 1); - QVERIFY(machine.configuration().contains(initialState)); + QVERIFY(machine.configuration().isEmpty()); + QVERIFY(!machine.isRunning()); } void tst_QStateMachine::transitionFromRootState() { QStateMachine machine; - QState *root = machine.rootState(); + QState *root = &machine; QState *s1 = new QState(root); EventTransition *trans = new EventTransition(QEvent::User, s1); - QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition from root state"); - root->addTransition(trans); - QCOMPARE(trans->sourceState(), (QState*)0); - delete trans; + QCOMPARE(root->addTransition(trans), trans); + QCOMPARE(trans->sourceState(), root); + QCOMPARE(trans->targetState(), s1); } void tst_QStateMachine::transitionEntersParent() @@ -671,7 +676,7 @@ void tst_QStateMachine::errorStateIsRootState() { QStateMachine machine; QTest::ignoreMessage(QtWarningMsg, "QStateMachine::setErrorState: root state cannot be error state"); - machine.setErrorState(machine.rootState()); + machine.setErrorState(&machine); QState *initialState = new QState(); initialState->setObjectName("initialState"); @@ -772,7 +777,7 @@ void tst_QStateMachine::errorStateEntersParentFirst() void tst_QStateMachine::customErrorStateIsNull() { QStateMachine machine; - machine.rootState()->setErrorState(0); + machine.setErrorState(0); QState *initialState = new QState(); machine.addState(initialState); @@ -798,9 +803,9 @@ void tst_QStateMachine::customErrorStateIsNull() void tst_QStateMachine::clearError() { QStateMachine machine; - machine.setErrorState(new QState(machine.rootState())); // avoid warnings + machine.setErrorState(new QState(&machine)); // avoid warnings - QState *brokenState = new QState(machine.rootState()); + QState *brokenState = new QState(&machine); brokenState->setObjectName("brokenState"); machine.setInitialState(brokenState); new QState(brokenState); @@ -822,13 +827,13 @@ void tst_QStateMachine::historyStateAsInitialState() { QStateMachine machine; - QHistoryState *hs = new QHistoryState(machine.rootState()); + QHistoryState *hs = new QHistoryState(&machine); machine.setInitialState(hs); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); hs->setDefaultState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); QHistoryState *s2h = new QHistoryState(s2); s2->setInitialState(s2h); @@ -856,11 +861,11 @@ void tst_QStateMachine::historyStateHasNowhereToGo() { QStateMachine machine; - QState *initialState = new QState(machine.rootState()); + QState *initialState = new QState(&machine); machine.setInitialState(initialState); - machine.setErrorState(new QState(machine.rootState())); // avoid warnings + machine.setErrorState(new QState(&machine)); // avoid warnings - QState *brokenState = new QState(machine.rootState()); + QState *brokenState = new QState(&machine); brokenState->setObjectName("brokenState"); brokenState->setInitialState(new QState(brokenState)); @@ -890,14 +895,14 @@ void tst_QStateMachine::brokenStateIsNeverEntered() entryController->setProperty("childStateEntered", false); entryController->setProperty("errorStateEntered", false); - QState *initialState = new QState(machine.rootState()); + QState *initialState = new QState(&machine); machine.setInitialState(initialState); - QState *errorState = new QState(machine.rootState()); + QState *errorState = new QState(&machine); errorState->assignProperty(entryController, "errorStateEntered", true); machine.setErrorState(errorState); - QState *brokenState = new QState(machine.rootState()); + QState *brokenState = new QState(&machine); brokenState->assignProperty(entryController, "brokenStateEntered", true); brokenState->setObjectName("brokenState"); @@ -921,7 +926,7 @@ void tst_QStateMachine::transitionToStateNotInGraph() { QStateMachine machine; - QState *initialState = new QState(machine.rootState()); + QState *initialState = new QState(&machine); initialState->setObjectName("initialState"); machine.setInitialState(initialState); @@ -946,7 +951,7 @@ void tst_QStateMachine::customErrorStateNotInGraph() machine.setErrorState(&errorState); QCOMPARE(machine.errorState(), reinterpret_cast(0)); - QState *initialBrokenState = new QState(machine.rootState()); + QState *initialBrokenState = new QState(&machine); initialBrokenState->setObjectName("initialBrokenState"); machine.setInitialState(initialBrokenState); new QState(initialBrokenState); @@ -1012,25 +1017,22 @@ void tst_QStateMachine::restoreProperties() void tst_QStateMachine::rootState() { QStateMachine machine; - QVERIFY(machine.rootState() != 0); - QVERIFY(qobject_cast(machine.rootState()) != 0); - QCOMPARE(qobject_cast(machine.rootState())->parentState(), (QState*)0); - QCOMPARE(machine.rootState()->parent(), (QObject*)&machine); - QCOMPARE(machine.rootState()->machine(), &machine); + QCOMPARE(qobject_cast(machine.parentState()), (QState*)0); + QCOMPARE(machine.machine(), (QStateMachine*)0); - QState *s1 = new QState(machine.rootState()); - QCOMPARE(s1->parentState(), machine.rootState()); + QState *s1 = new QState(&machine); + QCOMPARE(s1->parentState(), &machine); QState *s2 = new QState(); s2->setParent(&machine); - QCOMPARE(s2->parentState(), machine.rootState()); + QCOMPARE(s2->parentState(), &machine); } void tst_QStateMachine::addAndRemoveState() { #ifdef QT_BUILD_INTERNAL QStateMachine machine; - QStatePrivate *root_d = QStatePrivate::get(machine.rootState()); + QStatePrivate *root_d = QStatePrivate::get(&machine); QCOMPARE(root_d->childStates().size(), 0); QTest::ignoreMessage(QtWarningMsg, "QStateMachine::addState: cannot add null state"); @@ -1041,7 +1043,7 @@ void tst_QStateMachine::addAndRemoveState() QCOMPARE(s1->machine(), (QStateMachine*)0); machine.addState(s1); QCOMPARE(s1->machine(), &machine); - QCOMPARE(s1->parentState(), machine.rootState()); + QCOMPARE(s1->parentState(), &machine); QCOMPARE(root_d->childStates().size(), 1); QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s1); @@ -1051,7 +1053,7 @@ void tst_QStateMachine::addAndRemoveState() QState *s2 = new QState(); QCOMPARE(s2->parentState(), (QState*)0); machine.addState(s2); - QCOMPARE(s2->parentState(), machine.rootState()); + QCOMPARE(s2->parentState(), &machine); QCOMPARE(root_d->childStates().size(), 2); QCOMPARE(root_d->childStates().at(0), (QAbstractState*)s1); QCOMPARE(root_d->childStates().at(1), (QAbstractState*)s2); @@ -1076,13 +1078,13 @@ void tst_QStateMachine::addAndRemoveState() { QString warning; warning.sprintf("QStateMachine::removeState: state %p's machine (%p) is different from this machine (%p)", - machine2.rootState(), &machine2, &machine); + &machine2, (void*)0, &machine); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - machine.removeState(machine2.rootState()); + machine.removeState(&machine2); } // ### check this behavior - machine.addState(machine2.rootState()); - QCOMPARE(machine2.rootState()->parent(), (QObject*)machine.rootState()); + machine.addState(&machine2); + QCOMPARE(machine2.parent(), (QObject*)&machine); } delete s1; @@ -1098,7 +1100,7 @@ void tst_QStateMachine::stateEntryAndExit() { QStateMachine machine; - TestState *s1 = new TestState(machine.rootState()); + TestState *s1 = new TestState(&machine); QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); s1->addTransition((QAbstractState*)0); QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add null transition"); @@ -1106,8 +1108,8 @@ void tst_QStateMachine::stateEntryAndExit() QTest::ignoreMessage(QtWarningMsg, "QState::removeTransition: cannot remove null transition"); s1->removeTransition((QAbstractTransition*)0); - TestState *s2 = new TestState(machine.rootState()); - QFinalState *s3 = new QFinalState(machine.rootState()); + TestState *s2 = new TestState(&machine); + QFinalState *s3 = new QFinalState(&machine); TestTransition *t = new TestTransition(s2); QCOMPARE(t->machine(), (QStateMachine*)0); @@ -1156,9 +1158,9 @@ void tst_QStateMachine::stateEntryAndExit() QCOMPARE(machine.initialState(), (QAbstractState*)s1); { QString warning; - warning.sprintf("QState::setInitialState: state %p is not a child of this state (%p)", machine.rootState(), machine.rootState()); + warning.sprintf("QState::setInitialState: state %p is not a child of this state (%p)", &machine, &machine); QTest::ignoreMessage(QtWarningMsg, qPrintable(warning)); - machine.setInitialState(machine.rootState()); + machine.setInitialState(&machine); QCOMPARE(machine.initialState(), (QAbstractState*)s1); } QVERIFY(machine.configuration().isEmpty()); @@ -1205,11 +1207,11 @@ void tst_QStateMachine::stateEntryAndExit() { QStateMachine machine; - TestState *s1 = new TestState(machine.rootState()); + TestState *s1 = new TestState(&machine); TestState *s11 = new TestState(s1); TestState *s12 = new TestState(s1); - TestState *s2 = new TestState(machine.rootState()); - QFinalState *s3 = new QFinalState(machine.rootState()); + TestState *s2 = new TestState(&machine); + QFinalState *s3 = new QFinalState(&machine); s1->setInitialState(s11); TestTransition *t1 = new TestTransition(s12); s11->addTransition(t1); @@ -1268,13 +1270,13 @@ void tst_QStateMachine::stateEntryAndExit() void tst_QStateMachine::assignProperty() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); QTest::ignoreMessage(QtWarningMsg, "QState::assignProperty: cannot assign property 'foo' of null object"); s1->assignProperty(0, "foo", QVariant()); s1->assignProperty(s1, "objectName", "s1"); - QFinalState *s2 = new QFinalState(machine.rootState()); + QFinalState *s2 = new QFinalState(&machine); s1->addTransition(s2); machine.setInitialState(s1); machine.start(); @@ -1320,9 +1322,9 @@ void tst_QStateMachine::assignPropertyWithAnimation() QObject obj; obj.setProperty("foo", 321); obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(&obj, "foo", 123); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 789); QAbstractTransition *trans = s1->addTransition(s2); @@ -1342,7 +1344,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() trans->addAnimation(&anim); QCOMPARE(trans->animations().size(), 1); QCOMPARE(trans->animations().at(0), (QAbstractAnimation*)&anim); - QFinalState *s3 = new QFinalState(machine.rootState()); + QFinalState *s3 = new QFinalState(&machine); s2->addTransition(s2, SIGNAL(polished()), s3); machine.setInitialState(s1); @@ -1358,9 +1360,9 @@ void tst_QStateMachine::assignPropertyWithAnimation() QObject obj; obj.setProperty("foo", 321); obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(&obj, "foo", 123); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 789); QAbstractTransition *trans = s1->addTransition(s2); @@ -1370,7 +1372,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() QPropertyAnimation anim2(&obj, "bar"); anim2.setDuration(150); trans->addAnimation(&anim2); - QFinalState *s3 = new QFinalState(machine.rootState()); + QFinalState *s3 = new QFinalState(&machine); s2->addTransition(s2, SIGNAL(polished()), s3); machine.setInitialState(s1); @@ -1386,10 +1388,10 @@ void tst_QStateMachine::assignPropertyWithAnimation() QObject obj; obj.setProperty("foo", 321); obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(&obj, "foo", 123); s1->assignProperty(&obj, "bar", 321); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(&obj, "foo", 456); s2->assignProperty(&obj, "bar", 654); s2->assignProperty(&obj, "baz", 789); @@ -1398,7 +1400,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() group.addAnimation(new QPropertyAnimation(&obj, "foo")); group.addAnimation(new QPropertyAnimation(&obj, "bar")); trans->addAnimation(&group); - QFinalState *s3 = new QFinalState(machine.rootState()); + QFinalState *s3 = new QFinalState(&machine); s2->addTransition(s2, SIGNAL(polished()), s3); machine.setInitialState(s1); @@ -1415,7 +1417,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() QObject obj; obj.setProperty("foo", 321); obj.setProperty("bar", 654); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); QCOMPARE(s1->childMode(), QState::ExclusiveStates); s1->setChildMode(QState::ParallelStates); QCOMPARE(s1->childMode(), QState::ParallelStates); @@ -1425,7 +1427,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() s1->setObjectName("s1"); s1->assignProperty(&obj, "foo", 123); s1->assignProperty(&obj, "bar", 456); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->setObjectName("s2"); s2->assignProperty(&obj, "foo", 321); QState *s21 = new QState(s2); @@ -1447,7 +1449,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() s21->addTransition(s21, SIGNAL(polished()), s22); - QFinalState *s3 = new QFinalState(machine.rootState()); + QFinalState *s3 = new QFinalState(&machine); s22->addTransition(s2, SIGNAL(polished()), s3); machine.setInitialState(s1); @@ -1464,7 +1466,7 @@ void tst_QStateMachine::assignPropertyWithAnimation() QObject obj; obj.setProperty("foo", 321); obj.setProperty("bar", 654); - QState *group = new QState(machine.rootState()); + QState *group = new QState(&machine); QState *s1 = new QState(group); group->setInitialState(s1); s1->assignProperty(&obj, "foo", 123); @@ -1590,12 +1592,12 @@ void tst_QStateMachine::postEvent() void tst_QStateMachine::stateFinished() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); QState *s1_1 = new QState(s1); QFinalState *s1_2 = new QFinalState(s1); s1_1->addTransition(s1_2); s1->setInitialState(s1_1); - QFinalState *s2 = new QFinalState(machine.rootState()); + QFinalState *s2 = new QFinalState(&machine); s1->addTransition(s1, SIGNAL(finished()), s2); machine.setInitialState(s1); QSignalSpy finishedSpy(&machine, SIGNAL(finished())); @@ -1645,7 +1647,7 @@ void tst_QStateMachine::parallelStates() void tst_QStateMachine::parallelRootState() { QStateMachine machine; - QState *root = machine.rootState(); + QState *root = &machine; QCOMPARE(root->childMode(), QState::ExclusiveStates); root->setChildMode(QState::ParallelStates); QCOMPARE(root->childMode(), QState::ParallelStates); @@ -1668,7 +1670,7 @@ void tst_QStateMachine::parallelRootState() void tst_QStateMachine::allSourceToTargetConfigurations() { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); + QState *s0 = new QState(&machine); s0->setObjectName("s0"); QState *s1 = new QState(s0); s1->setObjectName("s1"); @@ -1680,7 +1682,7 @@ void tst_QStateMachine::allSourceToTargetConfigurations() s21->setObjectName("s21"); QState *s211 = new QState(s21); s211->setObjectName("s211"); - QFinalState *f = new QFinalState(machine.rootState()); + QFinalState *f = new QFinalState(&machine); f->setObjectName("f"); s0->setInitialState(s1); @@ -1754,7 +1756,7 @@ void tst_QStateMachine::signalTransitions() { { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); + QState *s0 = new QState(&machine); QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: sender cannot be null"); QCOMPARE(s0->addTransition(0, SIGNAL(noSuchSignal()), 0), (QSignalTransition*)0); @@ -1765,7 +1767,7 @@ void tst_QStateMachine::signalTransitions() QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: cannot add transition to null state"); QCOMPARE(s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), 0), (QSignalTransition*)0); - QFinalState *s1 = new QFinalState(machine.rootState()); + QFinalState *s1 = new QFinalState(&machine); QTest::ignoreMessage(QtWarningMsg, "QState::addTransition: no such signal SignalEmitter::noSuchSignal()"); QCOMPARE(s0->addTransition(&emitter, SIGNAL(noSuchSignal()), s1), (QSignalTransition*)0); @@ -1816,8 +1818,8 @@ void tst_QStateMachine::signalTransitions() } { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); SignalEmitter emitter; QSignalTransition *trans = s0->addTransition(&emitter, "signalWithNoArg()", s1); QVERIFY(trans != 0); @@ -1844,8 +1846,8 @@ void tst_QStateMachine::signalTransitions() } { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); SignalEmitter emitter; TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithIntArg(int)), s1); s0->addTransition(trans); @@ -1863,8 +1865,8 @@ void tst_QStateMachine::signalTransitions() } { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); SignalEmitter emitter; TestSignalTransition *trans = new TestSignalTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s1); s0->addTransition(trans); @@ -1883,8 +1885,8 @@ void tst_QStateMachine::signalTransitions() } { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); TestSignalTransition *trans = new TestSignalTransition(); QCOMPARE(trans->senderObject(), (QObject*)0); @@ -1911,8 +1913,8 @@ void tst_QStateMachine::signalTransitions() { QStateMachine machine; SignalEmitter emitter; - QState *s0 = new QState(machine.rootState()); - QState *s1 = new QState(machine.rootState()); + QState *s0 = new QState(&machine); + QState *s1 = new QState(&machine); QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); QSignalTransition *t1 = s1->addTransition(&emitter, SIGNAL(signalWithNoArg()), s0); @@ -1956,12 +1958,12 @@ void tst_QStateMachine::signalTransitions() { QStateMachine machine; SignalEmitter emitter; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); s0->addTransition(&emitter, SIGNAL(signalWithNoArg()), s1); - QFinalState *s2 = new QFinalState(machine.rootState()); + QFinalState *s2 = new QFinalState(&machine); s0->addTransition(&emitter, SIGNAL(signalWithIntArg(int)), s2); - QFinalState *s3 = new QFinalState(machine.rootState()); + QFinalState *s3 = new QFinalState(&machine); s0->addTransition(&emitter, SIGNAL(signalWithStringArg(QString)), s3); QSignalSpy startedSpy(&machine, SIGNAL(started())); @@ -1993,8 +1995,8 @@ void tst_QStateMachine::signalTransitions() { QStateMachine machine; SignalEmitter emitter; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); QSignalTransition *t0 = s0->addTransition(&emitter, SIGNAL( signalWithNoArg( ) ), s1); QVERIFY(t0 != 0); QCOMPARE(t0->signal(), QByteArray(SIGNAL( signalWithNoArg( ) ))); @@ -2021,8 +2023,8 @@ void tst_QStateMachine::eventTransitions() QPushButton button; for (int x = 0; x < 2; ++x) { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); QMouseEventTransition *trans; if (x == 0) { @@ -2070,8 +2072,8 @@ void tst_QStateMachine::eventTransitions() } for (int x = 0; x < 3; ++x) { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); QEventTransition *trans; if (x == 0) { @@ -2105,8 +2107,8 @@ void tst_QStateMachine::eventTransitions() } { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); QMouseEventTransition *trans = new QMouseEventTransition(); QCOMPARE(trans->eventObject(), (QObject*)0); @@ -2131,8 +2133,8 @@ void tst_QStateMachine::eventTransitions() { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); QKeyEventTransition *trans = new QKeyEventTransition(&button, QEvent::KeyPress, Qt::Key_A); QCOMPARE(trans->eventType(), QEvent::KeyPress); @@ -2152,8 +2154,8 @@ void tst_QStateMachine::eventTransitions() } { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); QKeyEventTransition *trans = new QKeyEventTransition(); QCOMPARE(trans->eventObject(), (QObject*)0); @@ -2178,8 +2180,8 @@ void tst_QStateMachine::eventTransitions() // Multiple transitions for same (object,event) { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QState *s1 = new QState(machine.rootState()); + QState *s0 = new QState(&machine); + QState *s1 = new QState(&machine); QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress); t0->setTargetState(s1); s0->addTransition(t0); @@ -2226,9 +2228,9 @@ void tst_QStateMachine::eventTransitions() // multiple event transitions from same source { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); - QFinalState *s2 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); + QFinalState *s2 = new QFinalState(&machine); QEventTransition *t0 = new QEventTransition(&button, QEvent::MouseButtonPress); t0->setTargetState(s1); s0->addTransition(t0); @@ -2257,8 +2259,8 @@ void tst_QStateMachine::eventTransitions() // custom event { QStateMachine machine; - QState *s0 = new QState(machine.rootState()); - QFinalState *s1 = new QFinalState(machine.rootState()); + QState *s0 = new QState(&machine); + QFinalState *s1 = new QFinalState(&machine); QEventTransition *trans = new QEventTransition(&button, QEvent::Type(QEvent::User+1)); trans->setTargetState(s1); @@ -2276,7 +2278,7 @@ void tst_QStateMachine::historyStates() { for (int x = 0; x < 2; ++x) { QStateMachine machine; - QState *root = machine.rootState(); + QState *root = &machine; QState *s0 = new QState(root); QState *s00 = new QState(s0); QState *s01 = new QState(s0); @@ -2360,7 +2362,7 @@ void tst_QStateMachine::startAndStop() QCOMPARE(stoppedSpy.count(), 0); QCOMPARE(finishedSpy.count(), 0); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); machine.start(); QTRY_COMPARE(machine.isRunning(), true); @@ -2391,7 +2393,7 @@ void tst_QStateMachine::startAndStop() void tst_QStateMachine::targetStateWithNoParent() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->setObjectName("s1"); QState s2; s1->addTransition(&s2); @@ -2411,9 +2413,9 @@ void tst_QStateMachine::targetStateWithNoParent() void tst_QStateMachine::targetStateDeleted() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->setObjectName("s1"); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); QAbstractTransition *trans = s1->addTransition(s2); delete s2; QCOMPARE(trans->targetState(), (QAbstractState*)0); @@ -2428,13 +2430,13 @@ void tst_QStateMachine::defaultGlobalRestorePolicy() propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(propertyHolder, "a", 3); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(propertyHolder, "b", 4); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); s1->addTransition(new EventTransition(QEvent::User, s2)); s2->addTransition(new EventTransition(QEvent::User, s3)); @@ -2463,11 +2465,12 @@ void tst_QStateMachine::noInitialStateForInitialState() { QStateMachine machine; - QState *initialState = new QState(machine.rootState()); + QState *initialState = new QState(&machine); initialState->setObjectName("initialState"); machine.setInitialState(initialState); QState *childState = new QState(initialState); + (void)childState; QTest::ignoreMessage(QtWarningMsg, "Unrecoverable error detected in running state machine: " "Missing initial state in compound state 'initialState'"); @@ -2487,7 +2490,7 @@ void tst_QStateMachine::restorePolicyNotInherited() propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); - QState *parentState = new QState(machine.rootState()); + QState *parentState = new QState(&machine); parentState->setObjectName("parentState"); parentState->setRestorePolicy(QState::RestoreProperties); @@ -2536,13 +2539,13 @@ void tst_QStateMachine::globalRestorePolicySetToDoNotRestore() propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(propertyHolder, "a", 3); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(propertyHolder, "b", 4); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); s1->addTransition(new EventTransition(QEvent::User, s2)); s2->addTransition(new EventTransition(QEvent::User, s3)); @@ -2646,7 +2649,7 @@ void tst_QStateMachine::restorePolicyOnChildState() propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); - QState *parentState = new QState(machine.rootState()); + QState *parentState = new QState(&machine); parentState->setObjectName("parentState"); QState *s1 = new QState(parentState); @@ -2697,13 +2700,13 @@ void tst_QStateMachine::globalRestorePolicySetToRestore() propertyHolder->setProperty("a", 1); propertyHolder->setProperty("b", 2); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->assignProperty(propertyHolder, "a", 3); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(propertyHolder, "b", 4); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); s1->addTransition(new EventTransition(QEvent::User, s2)); s2->addTransition(new EventTransition(QEvent::User, s3)); @@ -2736,19 +2739,19 @@ void tst_QStateMachine::mixedRestoreProperties() QObject *propertyHolder = new QObject(); propertyHolder->setProperty("a", 1); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); s1->setRestorePolicy(QState::RestoreProperties); s1->assignProperty(propertyHolder, "a", 3); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(propertyHolder, "a", 4); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); - QState *s4 = new QState(machine.rootState()); + QState *s4 = new QState(&machine); s4->assignProperty(propertyHolder, "a", 5); - QState *s5 = new QState(machine.rootState()); + QState *s5 = new QState(&machine); s5->setRestorePolicy(QState::RestoreProperties); s5->assignProperty(propertyHolder, "a", 6); @@ -2800,8 +2803,8 @@ void tst_QStateMachine::mixedRestoreProperties() void tst_QStateMachine::transitionWithParent() { QStateMachine machine; - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); EventTransition *trans = new EventTransition(QEvent::User, s2, s1); QCOMPARE(trans->sourceState(), s1); QCOMPARE(trans->targetState(), (QAbstractState*)s2); @@ -2816,8 +2819,8 @@ void tst_QStateMachine::simpleAnimation() QObject *object = new QObject(&machine); object->setProperty("fooBar", 1.0); - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); s2->assignProperty(object, "fooBar", 2.0); EventTransition *et = new EventTransition(QEvent::User, s2); @@ -2825,7 +2828,7 @@ void tst_QStateMachine::simpleAnimation() et->addAnimation(animation); s1->addTransition(et); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); s2->addTransition(animation, SIGNAL(finished()), s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); @@ -2860,8 +2863,8 @@ void tst_QStateMachine::twoAnimations() object->setProperty("foo", 1.0); object->setProperty("bar", 3.0); - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); s2->assignProperty(object, "bar", 10.0); @@ -2878,7 +2881,7 @@ void tst_QStateMachine::twoAnimations() et->addAnimation(animationBar); s1->addTransition(et); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(s2, SIGNAL(polished()), s3); @@ -2903,23 +2906,23 @@ void tst_QStateMachine::twoAnimatedTransitions() QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 5.0); QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(fooAnimation, SIGNAL(finished()), s3); - QState *s4 = new QState(machine.rootState()); + QState *s4 = new QState(&machine); s4->assignProperty(object, "foo", 2.0); QPropertyAnimation *fooAnimation2 = new QPropertyAnimation(object, "foo", s4); s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation2); - QState *s5 = new QState(machine.rootState()); + QState *s5 = new QState(&machine); QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); s4->addTransition(fooAnimation2, SIGNAL(finished()), s5); @@ -2947,22 +2950,22 @@ void tst_QStateMachine::playAnimationTwice() QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 5.0); QPropertyAnimation *fooAnimation = new QPropertyAnimation(object, "foo", s2); s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(fooAnimation); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(fooAnimation, SIGNAL(finished()), s3); - QState *s4 = new QState(machine.rootState()); + QState *s4 = new QState(&machine); s4->assignProperty(object, "foo", 2.0); s3->addTransition(new EventTransition(QEvent::User, s4))->addAnimation(fooAnimation); - QState *s5 = new QState(machine.rootState()); + QState *s5 = new QState(&machine); QObject::connect(s5, SIGNAL(entered()), QApplication::instance(), SLOT(quit())); s4->addTransition(fooAnimation, SIGNAL(finished()), s5); @@ -2993,8 +2996,8 @@ void tst_QStateMachine::nestedTargetStateForAnimation() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); @@ -3021,7 +3024,7 @@ void tst_QStateMachine::nestedTargetStateForAnimation() connect(animation, SIGNAL(finished()), &counter, SLOT(slot())); at->addAnimation(animation); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); s2->addTransition(s2Child, SIGNAL(polished()), s3); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); @@ -3049,13 +3052,13 @@ void tst_QStateMachine::animatedGlobalRestoreProperty() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); - QState *s2 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); - QState *s4 = new QState(machine.rootState()); + QState *s4 = new QState(&machine); QObject::connect(s4, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3093,16 +3096,16 @@ void tst_QStateMachine::specificTargetValueOfAnimation() QObject *object = new QObject(&machine); object->setProperty("foo", 1.0); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); QPropertyAnimation *anim = new QPropertyAnimation(object, "foo"); anim->setEndValue(10.0); s1->addTransition(new EventTransition(QEvent::User, s2))->addAnimation(anim); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s2->addTransition(anim, SIGNAL(finished()), s3); @@ -3127,12 +3130,12 @@ void tst_QStateMachine::addDefaultAnimation() QObject *object = new QObject(); object->setProperty("foo", 1.0); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3164,12 +3167,12 @@ void tst_QStateMachine::addDefaultAnimationWithUnusedAnimation() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3245,13 +3248,13 @@ void tst_QStateMachine::overrideDefaultAnimationWithSpecific() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3287,12 +3290,12 @@ void tst_QStateMachine::addDefaultAnimationForSource() QObject *object = new QObject(); object->setProperty("foo", 1.0); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3319,12 +3322,12 @@ void tst_QStateMachine::addDefaultAnimationForTarget() QObject *object = new QObject(); object->setProperty("foo", 1.0); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3348,88 +3351,88 @@ void tst_QStateMachine::removeDefaultAnimationForSource() { QStateMachine machine; - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 0); QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); - machine.addDefaultAnimationForSourceState(machine.rootState(), anim); + machine.addDefaultAnimationForSourceState(&machine, anim); QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(&machine).contains(anim)); - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + machine.removeDefaultAnimationForTargetState(&machine, anim); QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(&machine).contains(anim)); - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + machine.removeDefaultAnimationForSourceState(&machine, anim); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 0); - machine.addDefaultAnimationForSourceState(machine.rootState(), anim); + machine.addDefaultAnimationForSourceState(&machine, anim); QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); - machine.addDefaultAnimationForSourceState(machine.rootState(), anim2); + machine.addDefaultAnimationForSourceState(&machine, anim2); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 2); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim)); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 2); + QVERIFY(machine.defaultAnimationsForSourceState(&machine).contains(anim)); + QVERIFY(machine.defaultAnimationsForSourceState(&machine).contains(anim2)); - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + machine.removeDefaultAnimationForSourceState(&machine, anim); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForSourceState(machine.rootState()).contains(anim2)); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 1); + QVERIFY(machine.defaultAnimationsForSourceState(&machine).contains(anim2)); - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim2); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); + machine.removeDefaultAnimationForSourceState(&machine, anim2); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 0); } void tst_QStateMachine::removeDefaultAnimationForTarget() { QStateMachine machine; - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 0); QPropertyAnimation *anim = new QPropertyAnimation(this, "foo"); - machine.addDefaultAnimationForTargetState(machine.rootState(), anim); + machine.addDefaultAnimationForTargetState(&machine, anim); QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(&machine).contains(anim)); - machine.removeDefaultAnimationForSourceState(machine.rootState(), anim); + machine.removeDefaultAnimationForSourceState(&machine, anim); QCOMPARE(machine.defaultAnimations().size(), 0); - QCOMPARE(machine.defaultAnimationsForSourceState(machine.rootState()).size(), 0); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); + QCOMPARE(machine.defaultAnimationsForSourceState(&machine).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(&machine).contains(anim)); - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + machine.removeDefaultAnimationForTargetState(&machine, anim); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 0); - machine.addDefaultAnimationForTargetState(machine.rootState(), anim); + machine.addDefaultAnimationForTargetState(&machine, anim); QPropertyAnimation *anim2 = new QPropertyAnimation(this, "foo"); - machine.addDefaultAnimationForTargetState(machine.rootState(), anim2); + machine.addDefaultAnimationForTargetState(&machine, anim2); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 2); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim)); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 2); + QVERIFY(machine.defaultAnimationsForTargetState(&machine).contains(anim)); + QVERIFY(machine.defaultAnimationsForTargetState(&machine).contains(anim2)); - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim); + machine.removeDefaultAnimationForTargetState(&machine, anim); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 1); - QVERIFY(machine.defaultAnimationsForTargetState(machine.rootState()).contains(anim2)); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 1); + QVERIFY(machine.defaultAnimationsForTargetState(&machine).contains(anim2)); - machine.removeDefaultAnimationForTargetState(machine.rootState(), anim2); - QCOMPARE(machine.defaultAnimationsForTargetState(machine.rootState()).size(), 0); + machine.removeDefaultAnimationForTargetState(&machine, anim2); + QCOMPARE(machine.defaultAnimationsForTargetState(&machine).size(), 0); } void tst_QStateMachine::overrideDefaultAnimationWithSource() @@ -3441,13 +3444,13 @@ void tst_QStateMachine::overrideDefaultAnimationWithSource() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3481,13 +3484,13 @@ void tst_QStateMachine::overrideDefaultAnimationWithTarget() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3522,13 +3525,13 @@ void tst_QStateMachine::overrideDefaultSourceAnimationWithSpecific() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3562,13 +3565,13 @@ void tst_QStateMachine::overrideDefaultTargetAnimationWithSpecific() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); QAbstractTransition *at = s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3602,13 +3605,13 @@ void tst_QStateMachine::overrideDefaultTargetAnimationWithSource() SlotCalledCounter counter; - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(object, "foo", 2.0); - QState *s3 = new QState(machine.rootState()); + QState *s3 = new QState(&machine); QObject::connect(s3, SIGNAL(entered()), QCoreApplication::instance(), SLOT(quit())); s1->addTransition(new EventTransition(QEvent::User, s2)); @@ -3644,10 +3647,10 @@ void tst_QStateMachine::parallelStateAssignmentsDone() propertyHolder->setProperty("bar", 456); propertyHolder->setProperty("zoot", 789); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + QState *parallelState = new QState(QState::ParallelStates, &machine); parallelState->assignProperty(propertyHolder, "foo", 321); QState *s2 = new QState(parallelState); @@ -3676,10 +3679,10 @@ void tst_QStateMachine::transitionsFromParallelStateWithNoChildren() { QStateMachine machine; - QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + QState *parallelState = new QState(QState::ParallelStates, &machine); machine.setInitialState(parallelState); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); parallelState->addTransition(new EventTransition(QEvent::User, s1)); machine.start(); @@ -3700,7 +3703,7 @@ void tst_QStateMachine::parallelStateTransition() { QStateMachine machine; - QState *parallelState = new QState(QState::ParallelStates, machine.rootState()); + QState *parallelState = new QState(QState::ParallelStates, &machine); machine.setInitialState(parallelState); QState *s1 = new QState(parallelState); @@ -3749,10 +3752,10 @@ void tst_QStateMachine::nestedRestoreProperties() propertyHolder->setProperty("foo", 1); propertyHolder->setProperty("bar", 2); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(propertyHolder, "foo", 3); QState *s21 = new QState(s2); @@ -3801,10 +3804,10 @@ void tst_QStateMachine::nestedRestoreProperties2() propertyHolder->setProperty("foo", 1); propertyHolder->setProperty("bar", 2); - QState *s1 = new QState(machine.rootState()); + QState *s1 = new QState(&machine); machine.setInitialState(s1); - QState *s2 = new QState(machine.rootState()); + QState *s2 = new QState(&machine); s2->assignProperty(propertyHolder, "foo", 3); QState *s21 = new QState(s2); @@ -3856,6 +3859,46 @@ void tst_QStateMachine::nestedRestoreProperties2() } +void tst_QStateMachine::nestedStateMachines() +{ + QStateMachine machine; + QState *group = new QState(&machine); + group->setChildMode(QState::ParallelStates); + QStateMachine *subMachines[3]; + for (int i = 0; i < 3; ++i) { + QState *subGroup = new QState(group); + QStateMachine *subMachine = new QStateMachine(subGroup); + { + QState *initial = new QState(subMachine); + QFinalState *done = new QFinalState(subMachine); + initial->addTransition(new EventTransition(QEvent::User, done)); + subMachine->setInitialState(initial); + } + QFinalState *subMachineDone = new QFinalState(subGroup); + subMachine->addTransition(subMachine, SIGNAL(finished()), subMachineDone); + subGroup->setInitialState(subMachine); + subMachines[i] = subMachine; + } + QFinalState *final = new QFinalState(&machine); + group->addTransition(group, SIGNAL(finished()), final); + machine.setInitialState(group); + + QSignalSpy startedSpy(&machine, SIGNAL(started())); + QSignalSpy finishedSpy(&machine, SIGNAL(finished())); + machine.start(); + QTRY_COMPARE(startedSpy.count(), 1); + QTRY_COMPARE(machine.configuration().count(), 1+2*3); + QVERIFY(machine.configuration().contains(group)); + for (int i = 0; i < 3; ++i) + QVERIFY(machine.configuration().contains(subMachines[i])); + + QCoreApplication::processEvents(); // starts the submachines + + for (int i = 0; i < 3; ++i) + subMachines[i]->postEvent(new QEvent(QEvent::User)); + + QTRY_COMPARE(finishedSpy.count(), 1); +} QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v0.12 From e2aa651aba89bcc409dd090466b04036277a9a7c Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 22 Jul 2009 15:59:58 +0200 Subject: Compile on embedded --- src/gui/styles/qcleanlooksstyle.cpp | 2 +- src/gui/styles/qgtkstyle.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index ccf81cb..8f88781 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -1746,7 +1746,7 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o int maxWidth = rect.width() - 4; int minWidth = 4; qreal progress = qMax(bar->progress, bar->minimum); // workaround for bug in QProgressBar - int progressBarWidth = (progress - bar->minimum) * qreal(maxWidth) / qMax(1.0, qreal(bar->maximum) - bar->minimum); + int progressBarWidth = (progress - bar->minimum) * qreal(maxWidth) / qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum); int width = indeterminate ? maxWidth : qMax(minWidth, progressBarWidth); bool reverse = (!vertical && (bar->direction == Qt::RightToLeft)) || vertical; diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 53f3db9..660b4c3 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -2076,7 +2076,7 @@ void QGtkStyle::drawControl(ControlElement element, if (vertical) rect = QRect(rect.left(), rect.top(), rect.height(), rect.width()); // flip width and height const int progressIndicatorPos = (bar->progress - qreal(bar->minimum)) * rect.width() / - qMax(1.0, qreal(bar->maximum) - bar->minimum); + qMax(qreal(1.0), qreal(bar->maximum) - bar->minimum); if (progressIndicatorPos >= 0 && progressIndicatorPos <= rect.width()) leftRect = QRect(rect.left(), rect.top(), progressIndicatorPos, rect.height()); if (vertical) -- cgit v0.12 From 9f176a9953e42ae08aaed5fa92ed55bbc8526142 Mon Sep 17 00:00:00 2001 From: Gunnar Sletta Date: Wed, 22 Jul 2009 16:26:28 +0200 Subject: Fix table borders in multiline tables when printing to PostScript. I'm not all to happy with this fix, but its the best that one can acheive given the current design. The problem is that QPdfBaseEngine sets a number of states as part of updateState(), but only when we are playing back through the alpha engine. These states are used in some draw functions, also when we are recording in the alpha engine. This leads to the states and their checks being out of sync. So to follow the existing pattern in the code we need to not touch d-> vars prior to a check to usesAlphaEngine. Reviewed-By: Eskil --- src/gui/painting/qpdf.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp index 2017fdd..8a991e3 100644 --- a/src/gui/painting/qpdf.cpp +++ b/src/gui/painting/qpdf.cpp @@ -964,8 +964,7 @@ QPdfBaseEngine::QPdfBaseEngine(QPdfBaseEnginePrivate &dd, PaintEngineFeatures f) void QPdfBaseEngine::drawPoints (const QPointF *points, int pointCount) { - Q_D(QPdfBaseEngine); - if (!points || !d->hasPen) + if (!points) return; QPainterPath p; @@ -995,6 +994,12 @@ void QPdfBaseEngine::drawRects (const QRectF *rects, int rectCount) return; Q_D(QPdfBaseEngine); + if (d->useAlphaEngine) { + QAlphaPaintEngine::drawRects(rects, rectCount); + if (!continueCall()) + return; + } + if (d->clipEnabled && d->allClipped) return; if (!d->hasPen && !d->hasBrush) -- cgit v0.12 From 3597a5b82610752cf95372a5a5f7b33afc8d30b9 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Tue, 21 Jul 2009 16:15:57 +0200 Subject: Use texture_from_pixmap on X11 & avoid copies The patch tries to use texture_from_pixmap extentions on glX to properly bind an X Pixmap to a texture in QGLContextPrivate::bindTexture(QPixmap,). Because GL & X have different coordinate systems, the pixmap will be inverted about the y-axis. The extension does however allow a GLX_Y_INVERTED_EXT attribute to be set which will bind the pixmap the correct way up. If the underlying driver doesn't support this, texture_from_pixmap can't be used for QGLContext::bindTexture, because that function expects the resulting texture to be the right way up. However, it can still be used internally by the paint engine for drawPixmap operations. For these cases, if the pixmap is inverted, the paint engine can simply invert the texture coords to compensate. This is why this patch also moves QGLTexture into qgl_p.h. QGLContextPrivate::bindTexture(QPixmap,) now returns a QGLTexture which the paint engine can inspect to see if it needs to invert the texture coords. Finally, it seems on some (probably all) drivers, deleting an X pixmap which has been bound to a texture before calling glFinish/swapBuffers renders garbage. Presumably this is because X deletes the pixmap behind the driver's back before it's had a chance to use it. To fix this, we reference all QPixmaps which have been bound to stop them being deleted and only deref them after we swap the buffer, when they can be safely deleted. Reviewed-By: Kim --- .../gl2paintengineex/qpaintengineex_opengl2.cpp | 22 +- src/opengl/qgl.cpp | 296 +++++++++++---------- src/opengl/qgl_p.h | 80 +++++- src/opengl/qgl_x11.cpp | 133 +++++++++ src/opengl/qgl_x11egl.cpp | 11 + src/opengl/qglpixmapfilter.cpp | 2 +- src/opengl/qpixmapdata_gl.cpp | 46 ++-- src/opengl/qpixmapdata_gl_p.h | 6 +- 8 files changed, 422 insertions(+), 174 deletions(-) diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 7e8a281..167eb64 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -74,6 +74,7 @@ #include #include #include +#include #include "qglgradientcache_p.h" #include "qglengineshadermanager_p.h" @@ -1054,14 +1055,18 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c QGLContext *ctx = d->ctx; glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - GLuint id = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true); + QGLTexture *texture = ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, true, true); + + GLfloat top = texture->yInverted ? (pixmap.height() - src.top()) : src.top(); + GLfloat bottom = texture->yInverted ? (pixmap.height() - src.bottom()) : src.bottom(); + QGLRect srcRect(src.left(), top, src.right(), bottom); bool isBitmap = pixmap.isQBitmap(); bool isOpaque = !isBitmap && !pixmap.hasAlphaChannel(); d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, - state()->renderHints & QPainter::SmoothPixmapTransform, id); - d->drawTexture(dest, src, pixmap.size(), isOpaque, isBitmap); + state()->renderHints & QPainter::SmoothPixmapTransform, texture->id); + d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap); } void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src, @@ -1073,7 +1078,8 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QGLContext *ctx = d->ctx; glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT); - GLuint id = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); + QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, true); + GLuint id = texture->id; d->updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, state()->renderHints & QPainter::SmoothPixmapTransform, id); @@ -1287,6 +1293,14 @@ bool QGL2PaintEngineEx::end() glUseProgram(0); d->transferMode(BrushDrawingMode); d->drawable.swapBuffers(); +#if defined(Q_WS_X11) + // On some (probably all) drivers, deleting an X pixmap which has been bound to a texture + // before calling glFinish/swapBuffers renders garbage. Presumably this is because X deletes + // the pixmap behind the driver's back before it's had a chance to use it. To fix this, we + // reference all QPixmaps which have been bound to stop them being deleted and only deref + // them here, after swapBuffers, where they can be safely deleted. + ctx->d_func()->boundPixmaps.clear(); +#endif d->drawable.doneCurrent(); d->ctx->d_ptr->active_engine = 0; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index f51b271..392e750 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -87,7 +87,6 @@ #include #include #include "qcolormap.h" -#include "qcache.h" #include "qfile.h" #include "qlibrary.h" @@ -1395,39 +1394,99 @@ int qt_next_power_of_two(int v) return v; } -class QGLTexture { -public: - QGLTexture(const QGLContext *ctx, GLuint tx_id, GLenum tx_target, bool _clean = false) - : context(ctx), id(tx_id), target(tx_target), clean(_clean) {} - ~QGLTexture() { - if (clean) { - QGLContext *current = const_cast(QGLContext::currentContext()); - QGLContext *ctx = const_cast(context); - bool switch_context = current && current != ctx && !qgl_share_reg()->checkSharing(current, ctx); - if (switch_context) - ctx->makeCurrent(); - glDeleteTextures(1, &id); - if (switch_context) - current->makeCurrent(); - } - } - - const QGLContext *context; - GLuint id; - GLenum target; - bool clean; -}; - -typedef QCache QGLTextureCache; -static int qt_tex_cache_limit = 64*1024; // cache ~64 MB worth of textures - this is not accurate though -static QGLTextureCache *qt_tex_cache = 0; - typedef void (*_qt_pixmap_cleanup_hook_64)(qint64); typedef void (*_qt_image_cleanup_hook_64)(qint64); extern Q_GUI_EXPORT _qt_pixmap_cleanup_hook_64 qt_pixmap_cleanup_hook_64; extern Q_GUI_EXPORT _qt_image_cleanup_hook_64 qt_image_cleanup_hook_64; +static QGLTextureCache *qt_gl_texture_cache = 0; + +QGLTextureCache::QGLTextureCache() + : m_cache(64*1024) // cache ~64 MB worth of textures - this is not accurate though +{ + Q_ASSERT(qt_gl_texture_cache == 0); + qt_gl_texture_cache = this; + qt_pixmap_cleanup_hook_64 = cleanupHook; + qt_image_cleanup_hook_64 = cleanupHook; +} + +QGLTextureCache::~QGLTextureCache() +{ + qt_gl_texture_cache = 0; + qt_pixmap_cleanup_hook_64 = 0; + qt_image_cleanup_hook_64 = 0; +} + +void QGLTextureCache::insert(QGLContext* ctx, qint64 key, QGLTexture* texture, int cost) +{ + if (m_cache.totalCost() + cost > m_cache.maxCost()) { + // the cache is full - make an attempt to remove something + const QList keys = m_cache.keys(); + int i = 0; + while (i < m_cache.count() + && (m_cache.totalCost() + cost > m_cache.maxCost())) { + QGLTexture *tex = m_cache.object(keys.at(i)); + if (tex->context == ctx) + m_cache.remove(keys.at(i)); + ++i; + } + } + m_cache.insert(key, texture, cost); +} + +bool QGLTextureCache::remove(QGLContext* ctx, GLuint textureId) +{ + QList keys = m_cache.keys(); + for (int i = 0; i < keys.size(); ++i) { + QGLTexture *tex = m_cache.object(keys.at(i)); + if (tex->id == textureId && tex->context == ctx) { + tex->clean = true; // forces a glDeleteTextures() call + m_cache.remove(keys.at(i)); + return true; + } + } + return false; +} + +void QGLTextureCache::removeContextTextures(QGLContext* ctx) +{ + QList keys = m_cache.keys(); + for (int i = 0; i < keys.size(); ++i) { + const qint64 &key = keys.at(i); + if (m_cache.object(key)->context == ctx) + m_cache.remove(key); + } +} + +QGLTextureCache* QGLTextureCache::instance() +{ + if (!qt_gl_texture_cache) + qt_gl_texture_cache = new QGLTextureCache; + + return qt_gl_texture_cache; +} + +/* + a hook that removes textures from the cache when a pixmap/image + is deref'ed +*/ +void QGLTextureCache::cleanupHook(qint64 cacheKey) +{ + // ### remove when the GL texture cache becomes thread-safe + if (qApp->thread() != QThread::currentThread()) + return; + QGLTexture *texture = instance()->getTexture(cacheKey); + if (texture && texture->clean) + instance()->remove(cacheKey); +} + +void QGLTextureCache::deleteIfEmpty() +{ + if (instance()->size() == 0) + delete instance(); +} + // DDS format structure struct DDSFormat { quint32 dwSize; @@ -1556,21 +1615,8 @@ QGLContext::~QGLContext() { Q_D(QGLContext); // remove any textures cached in this context - if (qt_tex_cache) { - QList keys = qt_tex_cache->keys(); - for (int i = 0; i < keys.size(); ++i) { - const qint64 &key = keys.at(i); - if (qt_tex_cache->object(key)->context == this) - qt_tex_cache->remove(key); - } - // ### thread safety - if (qt_tex_cache->size() == 0) { - qt_pixmap_cleanup_hook_64 = 0; - qt_image_cleanup_hook_64 = 0; - delete qt_tex_cache; - qt_tex_cache = 0; - } - } + QGLTextureCache::instance()->removeContextTextures(this); + QGLTextureCache::deleteIfEmpty(); // ### thread safety QGLSignalProxy::instance()->emitAboutToDestroyContext(this); reset(); @@ -1701,21 +1747,6 @@ GLuint QGLContext::bindTexture(const QString &fileName) return tx_id; } -/* - a hook that removes textures from the cache when a pixmap/image - is deref'ed -*/ -static void qt_gl_clean_cache(qint64 cacheKey) -{ - // ### remove when the GL texture cache becomes thread-safe - if (qApp->thread() != QThread::currentThread()) - return; - if (qt_tex_cache) { - QGLTexture *texture = qt_tex_cache->object(cacheKey); - if (texture && texture->clean) - qt_tex_cache->remove(cacheKey); - } -} static void convertToGLFormatHelper(QImage &dst, const QImage &img, GLenum texture_format) { @@ -1835,7 +1866,7 @@ QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_prem return result; } -GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, +QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key, bool clean) { Q_Q(QGLContext); @@ -1853,11 +1884,6 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint // the GL_BGRA format is only present in GL version >= 1.2 GLenum texture_format = (QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_1_2) ? GL_BGRA : GL_RGBA; - if (!qt_tex_cache) { - qt_tex_cache = new QGLTextureCache(qt_tex_cache_limit); - qt_pixmap_cleanup_hook_64 = qt_gl_clean_cache; - qt_image_cleanup_hook_64 = qt_gl_clean_cache; - } // Scale the pixmap if needed. GL textures needs to have the // dimensions 2^n+2(border) x 2^m+2(border), unless we're using GL @@ -1930,53 +1956,26 @@ GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint // this assumes the size of a texture is always smaller than the max cache size int cost = img.width()*img.height()*4/1024; - if (qt_tex_cache->totalCost() + cost > qt_tex_cache->maxCost()) { - // the cache is full - make an attempt to remove something - const QList keys = qt_tex_cache->keys(); - int i = 0; - while (i < qt_tex_cache->count() - && (qt_tex_cache->totalCost() + cost > qt_tex_cache->maxCost())) { - QGLTexture *tex = qt_tex_cache->object(keys.at(i)); - if (tex->context == q) - qt_tex_cache->remove(keys.at(i)); - ++i; - } - } - qt_tex_cache->insert(key, new QGLTexture(q, tx_id, target, clean), cost); - return tx_id; + QGLTexture *texture = new QGLTexture(q, tx_id, target, clean, false); + QGLTextureCache::instance()->insert(q, key, texture, cost); + return texture; } -bool QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target, GLuint *id) +QGLTexture *QGLContextPrivate::textureCacheLookup(const qint64 key, GLenum target) { Q_Q(QGLContext); - if (qt_tex_cache) { - QGLTexture *texture = qt_tex_cache->object(key); - if (texture && texture->target == target - && (texture->context == q || qgl_share_reg()->checkSharing(q, texture->context))) - { - *id = texture->id; - return true; - } + QGLTexture *texture = QGLTextureCache::instance()->getTexture(key); + if (texture && texture->target == target + && (texture->context == q || qgl_share_reg()->checkSharing(q, texture->context))) + { + return texture; } - return false; + return 0; } -/*! \internal */ -GLuint QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, bool clean) -{ - const qint64 key = image.cacheKey(); - GLuint id; - if (textureCacheLookup(key, target, &id)) { - glBindTexture(target, id); - return id; - } - GLuint cached = bindTexture(image, target, format, key, clean); - const_cast(image).data_ptr()->is_cached = (cached > 0); - return cached; -} /*! \internal */ -GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean) +QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean, bool canInvert) { Q_Q(QGLContext); QPixmapData *pd = pixmap.pixmapData(); @@ -1984,20 +1983,45 @@ GLuint QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, GLin if (target == GL_TEXTURE_2D && pd->classId() == QPixmapData::OpenGLClass) { const QGLPixmapData *data = static_cast(pd); - if (data->isValidContext(q)) - return data->bind(); + if (data->isValidContext(q)) { + data->bind(); + return data->texture(); + } } #endif const qint64 key = pixmap.cacheKey(); - GLuint id; - if (textureCacheLookup(key, target, &id)) { - glBindTexture(target, id); - return id; + QGLTexture *texture = textureCacheLookup(key, target); + if (texture) { + glBindTexture(target, texture->id); + return texture; + } + +#if defined(Q_WS_X11) + // Try to use texture_from_pixmap + if (pd->classId() == QPixmapData::X11Class) { + QPixmap *thatPixmap = const_cast(&pixmap); + texture = bindTextureFromNativePixmap(thatPixmap, key, canInvert); + if (texture) { + texture->clean = clean; + boundPixmaps.insert(thatPixmap->data_ptr(), QPixmap(pixmap)); + } } - GLuint cached = bindTexture(pixmap.toImage(), target, format, key, clean); - const_cast(pixmap).data_ptr()->is_cached = (cached > 0); - return cached; +#endif + + if (!texture) + texture = bindTexture(pixmap.toImage(), target, format, key, clean); + + // We should never return 0 as callers shouldn't need to null-check + static QGLTexture invalidTexture; + if (!texture) + texture = &invalidTexture; + + if (texture->id > 0) + const_cast(pixmap).data_ptr()->is_cached = true; + + Q_ASSERT(texture); + return texture; } /*! \internal */ @@ -2063,7 +2087,8 @@ int QGLContextPrivate::maxTextureSize() GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format) { Q_D(QGLContext); - return d->bindTexture(image, target, format, false); + QGLTexture *texture = d->bindTexture(image, target, format, false); + return texture->id; } #ifdef Q_MAC_COMPAT_GL_FUNCTIONS @@ -2082,7 +2107,8 @@ GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMa GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) { Q_D(QGLContext); - return d->bindTexture(pixmap, target, format, false); + QGLTexture *texture = d->bindTexture(pixmap, target, format, false, false); + return texture->id; } #ifdef Q_MAC_COMPAT_GL_FUNCTIONS @@ -2103,17 +2129,8 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, Q */ void QGLContext::deleteTexture(GLuint id) { - if (qt_tex_cache) { - QList keys = qt_tex_cache->keys(); - for (int i = 0; i < keys.size(); ++i) { - QGLTexture *tex = qt_tex_cache->object(keys.at(i)); - if (tex->id == id && tex->context == this) { - tex->clean = true; // forces a glDeleteTextures() call - qt_tex_cache->remove(keys.at(i)); - return; - } - } - } + if (QGLTextureCache::instance()->remove(this, id)) + return; // check the DDS cache if the texture wasn't found in the pixmap/image // cache @@ -2307,9 +2324,7 @@ void QGLContext::drawTexture(const QPointF &point, QMacCompatGLuint textureId, Q */ void QGLContext::setTextureCacheLimit(int size) { - qt_tex_cache_limit = size; - if (qt_tex_cache) - qt_tex_cache->setMaxCost(qt_tex_cache_limit); + QGLTextureCache::instance()->setMaxCost(size); } /*! @@ -2319,7 +2334,7 @@ void QGLContext::setTextureCacheLimit(int size) */ int QGLContext::textureCacheLimit() { - return qt_tex_cache_limit; + return QGLTextureCache::instance()->maxCost(); } @@ -4339,6 +4354,9 @@ void QGLExtensions::init_extensions() if (extensions.contains(QLatin1String("EXT_framebuffer_blit"))) glExtensions |= FramebufferBlit; + if (extensions.contains(QLatin1String("GL_ARB_texture_non_power_of_two"))) + glExtensions |= NPOTTextures; + QGLContext cx(QGLFormat::defaultFormat()); if (glExtensions & TextureCompression) { qt_glCompressedTexImage2DARB = (pfn_glCompressedTexImage2DARB) cx.getProcAddress(QLatin1String("glCompressedTexImage2DARB")); @@ -4546,32 +4564,34 @@ QGLFormat QGLDrawable::format() const GLuint QGLDrawable::bindTexture(const QImage &image, GLenum target, GLint format) { + QGLTexture *texture; if (widget) - return widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true); + texture = widget->d_func()->glcx->d_func()->bindTexture(image, target, format, true); else if (buffer) - return buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true); + texture = buffer->d_func()->qctx->d_func()->bindTexture(image, target, format, true); else if (fbo && QGLContext::currentContext()) - return const_cast(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true); + texture = const_cast(QGLContext::currentContext())->d_func()->bindTexture(image, target, format, true); #if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) else if (wsurf) - return wsurf->context()->d_func()->bindTexture(image, target, format, true); + texture = wsurf->context()->d_func()->bindTexture(image, target, format, true); #endif - return 0; + return texture->id; } GLuint QGLDrawable::bindTexture(const QPixmap &pixmap, GLenum target, GLint format) { + QGLTexture *texture; if (widget) - return widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true); + texture = widget->d_func()->glcx->d_func()->bindTexture(pixmap, target, format, true, true); else if (buffer) - return buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true); + texture = buffer->d_func()->qctx->d_func()->bindTexture(pixmap, target, format, true, true); else if (fbo && QGLContext::currentContext()) - return const_cast(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true); + texture = const_cast(QGLContext::currentContext())->d_func()->bindTexture(pixmap, target, format, true, true); #if defined(Q_WS_QWS) || (!defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL)) else if (wsurf) - return wsurf->context()->d_func()->bindTexture(pixmap, target, format, true); + texture = wsurf->context()->d_func()->bindTexture(pixmap, target, format, true, true); #endif - return 0; + return texture->id; } QColor QGLDrawable::backgroundColor() const diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index fda0257..01385f0 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -60,10 +60,7 @@ #include "QtCore/qthreadstorage.h" #include "QtCore/qhash.h" #include "private/qwidget_p.h" - -#if !defined(QT_OPENGL_ES_1) && !defined(QT_OPENGL_ES_1_CL) -#include "private/qpixmapdata_gl_p.h" -#endif +#include "qcache.h" #ifndef QT_OPENGL_ES_1_CL #define q_vertexType float @@ -203,17 +200,18 @@ struct QGLContextGroupResources QAtomicInt refs; }; +class QGLTexture; + class QGLContextPrivate { Q_DECLARE_PUBLIC(QGLContext) public: explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {groupResources = new QGLContextGroupResources;} ~QGLContextPrivate() {if (!groupResources->refs.deref()) delete groupResources;} - GLuint bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key, + QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key, bool clean = false); - GLuint bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean); - GLuint bindTexture(const QImage &image, GLenum target, GLint format, bool clean); - bool textureCacheLookup(const qint64 key, GLenum target, GLuint *id); + QGLTexture *bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean, bool canInvert = false); + QGLTexture *textureCacheLookup(const qint64 key, GLenum target); void init(QPaintDevice *dev, const QGLFormat &format); QImage convertToGLFormat(const QImage &image, bool force_premul, GLenum texture_format); int maxTextureSize(); @@ -241,6 +239,8 @@ public: void* pbuf; quint32 gpm; int screen; + QHash boundPixmaps; + QGLTexture *bindTextureFromNativePixmap(QPixmap *pm, const qint64 key, bool internal); #endif #if defined(Q_WS_MAC) bool update; @@ -300,6 +300,7 @@ class QGLPixelBuffer; class QGLFramebufferObject; class QWSGLWindowSurface; class QGLWindowSurface; +class QGLPixmapData; class QGLDrawable { public: QGLDrawable() : widget(0), buffer(0), fbo(0) @@ -360,7 +361,8 @@ public: PackedDepthStencil = 0x00000200, NVFloatBuffer = 0x00000400, PixelBufferObject = 0x00000800, - FramebufferBlit = 0x00001000 + FramebufferBlit = 0x00001000, + NPOTTextures = 0x00002000 }; Q_DECLARE_FLAGS(Extensions, Extension) @@ -397,6 +399,66 @@ private: extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg(); +class QGLTexture { +public: + QGLTexture(QGLContext *ctx = 0, GLuint tx_id = 0, GLenum tx_target = GL_TEXTURE_2D, + bool _clean = true, bool _yInverted = false) + : context(ctx), id(tx_id), target(tx_target), clean(_clean), yInverted(_yInverted) +#if defined(Q_WS_X11) + , boundPixmap(0) +#endif + {} + + ~QGLTexture() { + if (clean) { + QGLContext *current = const_cast(QGLContext::currentContext()); + QGLContext *ctx = const_cast(context); + bool switch_context = current && current != ctx && !qgl_share_reg()->checkSharing(current, ctx); + if (switch_context) + ctx->makeCurrent(); +#if defined(Q_WS_X11) + deleteBoundPixmap(); +#endif + glDeleteTextures(1, &id); + if (switch_context) + current->makeCurrent(); + } + } + + QGLContext *context; + GLuint id; + GLenum target; + bool clean; + bool yInverted; // NOTE: Y-Inverted textures are for internal use only! +#if defined(Q_WS_X11) + Qt::HANDLE boundPixmap; + void deleteBoundPixmap(); // in qgl_x11.cpp/qgl_x11egl.cpp +#endif +}; + +class QGLTextureCache { +public: + QGLTextureCache(); + ~QGLTextureCache(); + + void insert(QGLContext *ctx, qint64 key, QGLTexture *texture, int cost); + void remove(quint64 key) { m_cache.remove(key); } + bool remove(QGLContext *ctx, GLuint textureId); + void removeContextTextures(QGLContext *ctx); + int size() { return m_cache.size(); } + void setMaxCost(int newMax) { m_cache.setMaxCost(newMax); } + int maxCost() {return m_cache.maxCost(); } + QGLTexture* getTexture(quint64 key) { return m_cache.object(key); } + + static QGLTextureCache *instance(); + static void deleteIfEmpty(); + static void cleanupHook(qint64 cacheKey); + +private: + QCache m_cache; +}; + + #ifdef Q_WS_QWS extern QPaintEngine* qt_qgl_paint_engine(); diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 631625b..0399b48 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -52,6 +52,7 @@ #include "qdebug.h" #include #include +#include #ifdef Q_OS_HPUX // for GLXPBuffer #include @@ -1516,4 +1517,136 @@ void QGLExtensions::init() } } + +typedef void (*qt_glXBindTexImageEXT)(Display*, GLXDrawable, int, const int*); +typedef void (*qt_glXReleaseTexImageEXT)(Display*, GLXDrawable, int); +static qt_glXBindTexImageEXT glXBindTexImageEXT = 0; +static qt_glXReleaseTexImageEXT glXReleaseTexImageEXT = 0; +static bool qt_resolved_texture_from_pixmap = false; + +QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pm, const qint64 key, bool canInvert) +{ + Q_Q(QGLContext); + + if (pm->data_ptr()->classId() != QPixmapData::X11Class) + return 0; + QX11PixmapData *pixmapData = static_cast(pm->data_ptr()); + const QX11Info *x11Info = qt_x11Info(pm); + + + // Check to see if we have NPOT texture support + // TODO: Use GLX_TEXTURE_RECTANGLE_EXT texture target on systems without npot textures + if ( !(QGLExtensions::glExtensions & QGLExtensions::NPOTTextures) && + !(QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_2_0)) + return 0; + + if (!qt_resolved_texture_from_pixmap) { + qt_resolved_texture_from_pixmap = true; + + QString glxExt = QLatin1String(glXGetClientString(QX11Info::display(), GLX_EXTENSIONS)); + if (glxExt.contains(QLatin1String("GLX_EXT_texture_from_pixmap"))) { +#if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) + void *handle = dlopen(NULL, RTLD_LAZY); + if (handle) { + glXBindTexImageEXT = (qt_glXBindTexImageEXT) dlsym(handle, "glXBindTexImageEXT"); + glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) dlsym(handle, "glXReleaseTexImageEXT"); + dlclose(handle); + } + if (!glXBindTexImageEXT) +#endif + { + extern const QString qt_gl_library_name(); + QLibrary lib(qt_gl_library_name()); + glXBindTexImageEXT = (qt_glXBindTexImageEXT) lib.resolve("glXBindTexImageEXT"); + glXReleaseTexImageEXT = (qt_glXReleaseTexImageEXT) lib.resolve("glXReleaseTexImageEXT"); + } + } + } + + if (!glXBindTexImageEXT) + return 0; + +#if !defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX) + return 0; +#else + GLXFBConfig *configList = 0; + GLXFBConfig glxPixmapConfig; + int configCount = 0; + bool hasAlpha = pixmapData->hasAlphaChannel(); + + int configAttribs[] = { + hasAlpha ? GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, True, + GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT, + GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_2D_BIT_EXT, + // QGLContext::bindTexture() can't return an inverted texture, but QPainter::drawPixmap() can: + GLX_Y_INVERTED_EXT, canInvert ? GLX_DONT_CARE : False, + XNone +// GLX_BIND_TO_MIPMAP_TEXTURE_EXT, False, +// GLX_BIND_TO_TEXTURE_TARGETS_EXT, GLX_TEXTURE_1D_BIT_EXT or GLX_TEXTURE_2D_BIT_EXT or GLX_TEXTURE_RECTANGLE_BIT_EXT + }; + configList = glXChooseFBConfig(x11Info->display(), x11Info->screen(), configAttribs, &configCount); + if (!configList) + return 0; + glxPixmapConfig = configList[0]; + XFree(configList); + + GLXPixmap glxPixmap; + int pixmapAttribs[] = { + GLX_TEXTURE_FORMAT_EXT, hasAlpha ? GLX_TEXTURE_FORMAT_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT, + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_MIPMAP_TEXTURE_EXT, False, + XNone +// GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT or GLX_TEXTURE_FORMAT_RGB_EXT or GLX_TEXTURE_FORMAT_NONE_EXT, +// GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT or GLX_TEXTURE_RECTANGLE_EXT, +// GLX_MIPMAP_TEXTURE_EXT, True or False, + }; + + // Wrap the X Pixmap into a GLXPixmap: + glxPixmap = glXCreatePixmap(x11Info->display(), glxPixmapConfig, pixmapData->handle(), pixmapAttribs); + + if (!glxPixmap) + return 0; + + int yInverted; + glXGetFBConfigAttrib(x11Info->display(), glxPixmapConfig, GLX_Y_INVERTED_EXT, &yInverted); + + GLuint textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + glXBindTexImageEXT(x11Info->display(), glxPixmap, GLX_FRONT_LEFT_EXT, 0); + + glBindTexture(GL_TEXTURE_2D, textureId); + + QGLTexture *texture = new QGLTexture(q, textureId, GL_TEXTURE_2D, canInvert, yInverted); + texture->boundPixmap = glxPixmap; + + // We assume the cost of bound pixmaps is zero + QGLTextureCache::instance()->insert(q, key, texture, 0); + + return texture; +#endif //!defined(GLX_VERSION_1_3) || defined(Q_OS_HPUX) +} + +void QGLTexture::deleteBoundPixmap() +{ + if (boundPixmap) { + // Although glXReleaseTexImage is a glX call, it must be called while there + // is a current context - the context the pixmap was bound to a texture in. + // Otherwise the relese doesn't do anything and you get BadDrawable errors + // when you come to delete the context. + + QGLContext *oldContext = const_cast(QGLContext::currentContext()); + if (oldContext != context) + context->makeCurrent(); + glXReleaseTexImageEXT(QX11Info::display(), boundPixmap, GLX_FRONT_LEFT_EXT); + if (oldContext && oldContext != context) + oldContext->makeCurrent(); + + glXDestroyPixmap(QX11Info::display(), boundPixmap); + } + + boundPixmap = 0; +} + + QT_END_NAMESPACE diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 9db3a30..11131ea 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -469,4 +469,15 @@ void QGLWidgetPrivate::recreateEglSurface(bool force) } } +GLuint QGLContextPrivate::bindTextureFromNativePixmap(const QPixmap& pm, const qint64 key, bool canInvert) +{ + // TODO + return 0; +} + +void QGLTexture::deleteBoundPixmap() +{ + //TODO +} + QT_END_NAMESPACE diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 7514743..5a06763 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const { - const_cast(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, true); + const_cast(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, true, false); } void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF& source) const diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index fe3bb0c..e3ee2b2 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -97,7 +97,6 @@ static int qt_gl_pixmap_serial = 0; QGLPixmapData::QGLPixmapData(PixelType type) : QPixmapData(type, OpenGLClass) , m_renderFbo(0) - , m_textureId(0) , m_engine(0) , m_ctx(0) , m_dirty(false) @@ -113,9 +112,9 @@ QGLPixmapData::~QGLPixmapData() if (!shareWidget) return; - if (m_textureId) { + if (m_texture.id) { QGLShareContextScope ctx(shareWidget->context()); - glDeleteTextures(1, &m_textureId); + glDeleteTextures(1, &m_texture.id); } } @@ -148,10 +147,10 @@ void QGLPixmapData::resize(int width, int height) is_null = (w <= 0 || h <= 0); d = pixelType() == QPixmapData::PixmapType ? 32 : 1; - if (m_textureId) { + if (m_texture.id) { QGLShareContextScope ctx(qt_gl_share_widget()->context()); - glDeleteTextures(1, &m_textureId); - m_textureId = 0; + glDeleteTextures(1, &m_texture.id); + m_texture.id = 0; } m_source = QImage(); @@ -172,9 +171,9 @@ void QGLPixmapData::ensureCreated() const const GLenum format = qt_gl_preferredTextureFormat(); const GLenum target = GL_TEXTURE_2D; - if (!m_textureId) { - glGenTextures(1, &m_textureId); - glBindTexture(target, m_textureId); + if (!m_texture.id) { + glGenTextures(1, &m_texture.id); + glBindTexture(target, m_texture.id); GLenum format = m_hasAlpha ? GL_RGBA : GL_RGB; glTexImage2D(target, 0, format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); @@ -185,13 +184,15 @@ void QGLPixmapData::ensureCreated() const if (!m_source.isNull()) { const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, format); - glBindTexture(target, m_textureId); + glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, format, GL_UNSIGNED_BYTE, tx.bits()); if (useFramebufferObjects()) m_source = QImage(); } + + m_texture.clean = false; } QGLFramebufferObject *QGLPixmapData::fbo() const @@ -223,10 +224,10 @@ void QGLPixmapData::fromImage(const QImage &image, is_null = (w <= 0 || h <= 0); d = pixelType() == QPixmapData::PixmapType ? 32 : 1; - if (m_textureId) { + if (m_texture.id) { QGLShareContextScope ctx(qt_gl_share_widget()->context()); - glDeleteTextures(1, &m_textureId); - m_textureId = 0; + glDeleteTextures(1, &m_texture.id); + m_texture.id = 0; } } @@ -256,9 +257,9 @@ void QGLPixmapData::fill(const QColor &color) bool hasAlpha = color.alpha() != 255; if (hasAlpha && !m_hasAlpha) { - if (m_textureId) { - glDeleteTextures(1, &m_textureId); - m_textureId = 0; + if (m_texture.id) { + glDeleteTextures(1, &m_texture.id); + m_texture.id = 0; m_dirty = true; } m_hasAlpha = color.alpha() != 255; @@ -321,7 +322,7 @@ QImage QGLPixmapData::toImage() const } QGLShareContextScope ctx(qt_gl_share_widget()->context()); - glBindTexture(GL_TEXTURE_2D, m_textureId); + glBindTexture(GL_TEXTURE_2D, m_texture.id); return qt_gl_read_texture(QSize(w, h), true, true); } @@ -351,7 +352,7 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->fbo); glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, - GL_TEXTURE_2D, m_textureId, 0); + GL_TEXTURE_2D, m_texture.id, 0); const int x0 = 0; const int x1 = w; @@ -489,7 +490,7 @@ GLuint QGLPixmapData::bind(bool copyBack) const ensureCreated(); } - GLuint id = m_textureId; + GLuint id = m_texture.id; glBindTexture(GL_TEXTURE_2D, id); return id; } @@ -497,7 +498,12 @@ GLuint QGLPixmapData::bind(bool copyBack) const GLuint QGLPixmapData::textureId() const { ensureCreated(); - return m_textureId; + return m_texture.id; +} + +QGLTexture* QGLPixmapData::texture() const +{ + return &m_texture; } extern int qt_defaultDpiX(); diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h index a6aa22d..671f9a7 100644 --- a/src/opengl/qpixmapdata_gl_p.h +++ b/src/opengl/qpixmapdata_gl_p.h @@ -53,6 +53,7 @@ // We mean it. // +#include "qgl_p.h" #include "qgl.h" #include "private/qpixmapdata_p.h" @@ -80,10 +81,11 @@ public: void fill(const QColor &color); bool hasAlphaChannel() const; QImage toImage() const; - QPaintEngine* paintEngine() const; + QPaintEngine *paintEngine() const; GLuint bind(bool copyBack = true) const; GLuint textureId() const; + QGLTexture *texture() const; bool isValidContext(const QGLContext *ctx) const; @@ -116,10 +118,10 @@ private: QImage fillImage(const QColor &color) const; mutable QGLFramebufferObject *m_renderFbo; - mutable GLuint m_textureId; mutable QPaintEngine *m_engine; mutable QGLContext *m_ctx; mutable QImage m_source; + mutable QGLTexture m_texture; // the texture is not in sync with the source image mutable bool m_dirty; -- cgit v0.12 From 979a0f4e3625811997be40816adc2c5b53ec6da0 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Wed, 22 Jul 2009 16:52:53 +0200 Subject: QSslSocket autotest: adapt to new certificate on test server got a new certificate, which is self-signed now Reviewed-by: Thiago --- .../qsslsocket/certs/qt-test-server-cacert.pem | 35 ++++++++++------------ tests/auto/qsslsocket/tst_qsslsocket.cpp | 4 +-- 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/tests/auto/qsslsocket/certs/qt-test-server-cacert.pem b/tests/auto/qsslsocket/certs/qt-test-server-cacert.pem index 83adca2..25bd404 100644 --- a/tests/auto/qsslsocket/certs/qt-test-server-cacert.pem +++ b/tests/auto/qsslsocket/certs/qt-test-server-cacert.pem @@ -1,22 +1,17 @@ -----BEGIN CERTIFICATE----- -MIIDuDCCAyGgAwIBAgIJAM17QpZu2GP7MA0GCSqGSIb3DQEBBAUAMIGaMQ4wDAYD -VQQKEwVOb2tpYTEUMBIGA1UECxMLUXQgU29mdHdhcmUxIjAgBgkqhkiG9w0BCQEW -E25vYm9keUBub2RvbWFpbi5vcmcxDTALBgNVBAcTBE9zbG8xDTALBgNVBAgTBE9z -bG8xCzAJBgNVBAYTAk5PMSMwIQYDVQQDExpxdC10ZXN0LXNlcnZlci5xdC10ZXN0 -LW5ldDAeFw0wODEyMDIxNDQ3MjZaFw0xODExMzAxNDQ3MjZaMIGaMQ4wDAYDVQQK -EwVOb2tpYTEUMBIGA1UECxMLUXQgU29mdHdhcmUxIjAgBgkqhkiG9w0BCQEWE25v -Ym9keUBub2RvbWFpbi5vcmcxDTALBgNVBAcTBE9zbG8xDTALBgNVBAgTBE9zbG8x -CzAJBgNVBAYTAk5PMSMwIQYDVQQDExpxdC10ZXN0LXNlcnZlci5xdC10ZXN0LW5l -dDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAz7dQ0l6IYpwVUcvj0mQxvG80 -yzoRzYr+alh7HMmOFI6/xjBHD6zAEEmLBafY7M/xe8PGH7ds2l2BFJkz0OS+IJRX -8CdOoeFvmVyp+L84tzXk81NKnMQ3y8DiFc6aUkfnyybA0whIv/TlqNyrYeQUin+t -61dPf1vr0LAAm5HdeYECAwEAAaOCAQIwgf8wDAYDVR0TBAUwAwEB/zAdBgNVHQ4E -FgQUwhEr5xV4r0deMQd3XwFkFtwls20wgc8GA1UdIwSBxzCBxIAUwhEr5xV4r0de -MQd3XwFkFtwls22hgaCkgZ0wgZoxDjAMBgNVBAoTBU5va2lhMRQwEgYDVQQLEwtR -dCBTb2Z0d2FyZTEiMCAGCSqGSIb3DQEJARYTbm9ib2R5QG5vZG9tYWluLm9yZzEN -MAsGA1UEBxMET3NsbzENMAsGA1UECBMET3NsbzELMAkGA1UEBhMCTk8xIzAhBgNV -BAMTGnF0LXRlc3Qtc2VydmVyLnF0LXRlc3QtbmV0ggkAzXtClm7YY/swDQYJKoZI -hvcNAQEEBQADgYEAQ/8YDtHrUoEsu9j5J6GY8iuuT8jvs/W1se5vXzoITgld+vLM -RWzxz35Hwzy2n31MNmUagRyQsTNOvEtJTxPCP97eLLxxrHDAbRmY/PPcZfolfOQf -xKQYf9naBv2F9Bs0WcY9z0Dgdl27szTAN67vGddYx5HpU9UE8Or5hdFJI3I= +MIICrTCCAhYCCQCdDn5rci6VDjANBgkqhkiG9w0BAQQFADCBmjEOMAwGA1UEChMF +Tm9raWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2Jv +ZHlAbm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQsw +CQYDVQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQw +HhcNMDkwNzEwMDc0MTIzWhcNMTkwNzA4MDc0MTIzWjCBmjEOMAwGA1UEChMFTm9r +aWExFDASBgNVBAsTC1F0IFNvZnR3YXJlMSIwIAYJKoZIhvcNAQkBFhNub2JvZHlA +bm9kb21haW4ub3JnMQ0wCwYDVQQHEwRPc2xvMQ0wCwYDVQQIEwRPc2xvMQswCQYD +VQQGEwJOTzEjMCEGA1UEAxMacXQtdGVzdC1zZXJ2ZXIucXQtdGVzdC1uZXQwgZ8w +DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAM2q22/WNMmn8cC+5EEYGeICySLmp9W6 +Ay6eKHr0Xxp3X3epETuPfvAuxp7rOtkS18EMUegkUj8jw0IMEcbyHKFC/rTCaYOt +93CxGBXMIChiMPAsFeYzGa/D6xzAkfcRaJRQ+Ek3CDLXPnXfo7xpABXezYcPXAJr +gsgBfWrwHdxzAgMBAAEwDQYJKoZIhvcNAQEEBQADgYEAy7YOLCZABQy2Ygkchq1I ++TUpvMn+gLwAyW8TNErM1V4lNY2+K78RawzKx3SqM97ymCy4TD45EA3A2gmi32NI +xSKBNjFyzngUqsXBdcSasALiowlZCiJrGwlGX5qCkBlxXvJeUEbuJLPYVl5FBjXZ +6o00K4cSPCqtqUez7WSmDZU= -----END CERTIFICATE----- diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index bdfa9dd..6cc6c00 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -1388,9 +1388,7 @@ void tst_QSslSocket::verifyMode() QVERIFY(!socket.waitForEncrypted()); QList expectedErrors = QList() - << QSslError(QSslError::UnableToGetLocalIssuerCertificate, socket.peerCertificate()) - << QSslError(QSslError::CertificateUntrusted, socket.peerCertificate()) - << QSslError(QSslError::UnableToVerifyFirstCertificate, socket.peerCertificate()); + << QSslError(QSslError::SelfSignedCertificate, socket.peerCertificate()); QCOMPARE(socket.sslErrors(), expectedErrors); socket.abort(); -- cgit v0.12 From 9e5fa633913ef952ca4ef5312fe396bcfc885321 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 22 Jul 2009 17:12:17 +0200 Subject: Revert "Added a check that X11 timestamp goes forward only." In some cases we might get an invalid timestamp that is far away in the future, so remembering it will break all consequent X calls that require a timestamp because it just contains junk (for example clipboard will stop working). This happens with XIM+SCIM pair - whenever we start input method and type something to the widget, we get a XKeyPress event with a commited string, however the 'serial' and 'time' members of the XEvent structure are not initialized (according to valgrind) and contain junk. This reverts commit 2ed015b8a0ffad63f0f59b0e2255057f416895fb. Reviewed-By: Brad --- src/gui/kernel/qapplication_x11.cpp | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 163ceb6..abedfd6 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -3142,48 +3142,43 @@ int QApplication::x11ProcessEvent(XEvent* event) #ifdef ALIEN_DEBUG //qDebug() << "QApplication::x11ProcessEvent:" << event->type; #endif - Time time = 0, userTime = 0; switch (event->type) { case ButtonPress: pressed_window = event->xbutton.window; - userTime = event->xbutton.time; + X11->userTime = event->xbutton.time; // fallthrough intended case ButtonRelease: - time = event->xbutton.time; + X11->time = event->xbutton.time; break; case MotionNotify: - time = event->xmotion.time; + X11->time = event->xmotion.time; break; case XKeyPress: - userTime = event->xkey.time; + X11->userTime = event->xkey.time; // fallthrough intended case XKeyRelease: - time = event->xkey.time; + X11->time = event->xkey.time; break; case PropertyNotify: - time = event->xproperty.time; + X11->time = event->xproperty.time; break; case EnterNotify: case LeaveNotify: - time = event->xcrossing.time; + X11->time = event->xcrossing.time; break; case SelectionClear: - time = event->xselectionclear.time; + X11->time = event->xselectionclear.time; break; default: -#ifndef QT_NO_XFIXES - if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { - XFixesSelectionNotifyEvent *req = - reinterpret_cast(event); - time = req->selection_timestamp; - } -#endif break; } - if (time > X11->time) - X11->time = time; - if (userTime > X11->userTime) - X11->userTime = userTime; +#ifndef QT_NO_XFIXES + if (X11->use_xfixes && event->type == (X11->xfixes_eventbase + XFixesSelectionNotify)) { + XFixesSelectionNotifyEvent *req = + reinterpret_cast(event); + X11->time = req->selection_timestamp; + } +#endif QETWidget *widget = (QETWidget*)QWidget::find((WId)event->xany.window); -- cgit v0.12 From 7a208874ae5d69d2b70b08f03675ef8f0c843a7f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 22 Jul 2009 17:30:01 +0200 Subject: Fix handling of invalid object paths and signatures in release mode. I had this #ifdef __OPTIMIZE__ there so that the compiler would know not to generate unnecessary calls and a long jump table for the switch of the marshalling code. Turns out that in release mode, the checks I added to make sure we detect invalid object paths and signatures were never hit (we always treated them as pure strings). So use the signature- and object path-checking code in both release and debug mode. Task-number: reported via email (tst_qdbusmarshall failing) Reviewed-by: Peter Hartmann --- src/dbus/qdbusmarshaller.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index 7ada1ed..646f68a 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -388,16 +388,6 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) case DBUS_TYPE_DOUBLE: qIterAppend(&iterator, ba, *signature, arg.constData()); return true; - - case DBUS_TYPE_STRING: - case DBUS_TYPE_OBJECT_PATH: - case DBUS_TYPE_SIGNATURE: { - const QByteArray data = - reinterpret_cast(arg.constData())->toUtf8(); - const char *rawData = data.constData(); - qIterAppend(&iterator, ba, *signature, &rawData); - return true; - } #else case DBUS_TYPE_BYTE: append( qvariant_cast(arg) ); @@ -426,6 +416,8 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) case DBUS_TYPE_DOUBLE: append( arg.toDouble() ); return true; +#endif + case DBUS_TYPE_STRING: append( arg.toString() ); return true; @@ -435,7 +427,6 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) case DBUS_TYPE_SIGNATURE: append( qvariant_cast(arg) ); return true; -#endif // compound types: case DBUS_TYPE_VARIANT: -- cgit v0.12 From 8e05fd54935be488165abe6762e69aabb9adf232 Mon Sep 17 00:00:00 2001 From: Peter Hartmann Date: Thu, 2 Jul 2009 11:32:49 +0200 Subject: QNetworkReply: add possibility to ignore specific SSL errors the same method was also added to QSslSocket. previously, it was only possible to ignore all SSL errors; now, it is also possible to only ignore specific SSL errors, given by a QList of QSslErrors. Moreover, it is possible to call this newly added method right after connecting, not just when we get the SSL error. Reviewed-by: Thiago Task-number: 257322 --- .../code/src_network_access_qnetworkreply.cpp | 10 +++ .../snippets/code/src_network_ssl_qsslsocket.cpp | 11 +++ src/network/access/qhttpnetworkconnection.cpp | 24 +++++- src/network/access/qhttpnetworkconnection_p.h | 6 +- src/network/access/qhttpnetworkreply.cpp | 7 ++ src/network/access/qhttpnetworkreply_p.h | 1 + src/network/access/qnetworkaccessbackend.cpp | 6 ++ src/network/access/qnetworkaccessbackend_p.h | 1 + .../access/qnetworkaccessdebugpipebackend.cpp | 1 + src/network/access/qnetworkaccesshttpbackend.cpp | 18 ++++- src/network/access/qnetworkaccesshttpbackend_p.h | 4 +- src/network/access/qnetworkreply.cpp | 34 ++++++++- src/network/access/qnetworkreply.h | 1 + src/network/access/qnetworkreplyimpl.cpp | 6 ++ src/network/access/qnetworkreplyimpl_p.h | 1 + src/network/ssl/qsslsocket.cpp | 36 ++++++++- src/network/ssl/qsslsocket.h | 1 + src/network/ssl/qsslsocket_openssl.cpp | 22 +++++- src/network/ssl/qsslsocket_p.h | 3 +- tests/auto/qnetworkreply/tst_qnetworkreply.cpp | 88 +++++++++++++++++++++- tests/auto/qsslsocket/tst_qsslsocket.cpp | 84 ++++++++++++++++++++- 21 files changed, 348 insertions(+), 17 deletions(-) create mode 100644 doc/src/snippets/code/src_network_access_qnetworkreply.cpp diff --git a/doc/src/snippets/code/src_network_access_qnetworkreply.cpp b/doc/src/snippets/code/src_network_access_qnetworkreply.cpp new file mode 100644 index 0000000..78b388b --- /dev/null +++ b/doc/src/snippets/code/src_network_access_qnetworkreply.cpp @@ -0,0 +1,10 @@ +//! [0] +QList cert = QSslCertificate::fromPath(QLatin1String("server-certificate.pem")); +QSslError error(QSslError::SelfSignedCertificate, cert.at(0)); +QList expectedSslErrors; +expectedSslErrors.append(error); + +QNetworkReply *reply = manager.get(QNetworkRequest(QUrl("https://server.tld/index.html"))); +reply->ignoreSslErrors(expectedSslErrors); +// here connect signals etc. +//! [0] diff --git a/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp b/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp index afffbab..7845e9b 100644 --- a/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp +++ b/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp @@ -54,3 +54,14 @@ socket->connectToHostEncrypted("imap", 993); if (socket->waitForEncrypted(1000)) qDebug("Encrypted!"); //! [5] + +//! [6] +QList cert = QSslCertificate::fromPath(QLatin1String("server-certificate.pem")); +QSslError error(QSslError::SelfSignedCertificate, cert.at(0)); +QList expectedSslErrors; +expectedSslErrors.append(error); + +QSslSocket socket; +socket.ignoreSslErrors(expectedSslErrors); +socket.connectToHostEncrypted("server.tld", 443); +//! [6] diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index c661596..c824fac 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -340,8 +340,9 @@ bool QHttpNetworkConnectionPrivate::ensureConnection(QAbstractSocket *socket) #ifndef QT_NO_OPENSSL QSslSocket *sslSocket = qobject_cast(socket); sslSocket->connectToHostEncrypted(connectHost, connectPort); - if (channels[index].ignoreSSLErrors) + if (channels[index].ignoreAllSslErrors) sslSocket->ignoreSslErrors(); + sslSocket->ignoreSslErrors(channels[index].ignoreSslErrorsList); #else emitReplyError(socket, channels[index].reply, QNetworkReply::ProtocolUnknownError); #endif @@ -1448,15 +1449,32 @@ void QHttpNetworkConnection::ignoreSslErrors(int channel) if (channel == -1) { // ignore for all channels for (int i = 0; i < d->channelCount; ++i) { static_cast(d->channels[i].socket)->ignoreSslErrors(); - d->channels[i].ignoreSSLErrors = true; + d->channels[i].ignoreAllSslErrors = true; } } else { static_cast(d->channels[channel].socket)->ignoreSslErrors(); - d->channels[channel].ignoreSSLErrors = true; + d->channels[channel].ignoreAllSslErrors = true; } } +void QHttpNetworkConnection::ignoreSslErrors(const QList &errors, int channel) +{ + Q_D(QHttpNetworkConnection); + if (!d->encrypt) + return; + + if (channel == -1) { // ignore for all channels + for (int i = 0; i < d->channelCount; ++i) { + static_cast(d->channels[i].socket)->ignoreSslErrors(errors); + d->channels[i].ignoreSslErrorsList = errors; + } + + } else { + static_cast(d->channels[channel].socket)->ignoreSslErrors(errors); + d->channels[channel].ignoreSslErrorsList = errors; + } +} #endif //QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 842a2f4..52a73a7 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -117,6 +117,7 @@ public: #ifndef QT_NO_OPENSSL void setSslConfiguration(const QSslConfiguration &config); void ignoreSslErrors(int channel = -1); + void ignoreSslErrors(const QList &errors, int channel = -1); Q_SIGNALS: void sslErrors(const QList &errors); @@ -241,13 +242,14 @@ public: QAuthenticator authenticator; QAuthenticator proxyAuthenticator; #ifndef QT_NO_OPENSSL - bool ignoreSSLErrors; + bool ignoreAllSslErrors; + QList ignoreSslErrorsList; #endif Channel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), lastStatus(0), pendingEncrypt(false), reconnectAttempts(2), authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) #ifndef QT_NO_OPENSSL - , ignoreSSLErrors(false) + , ignoreAllSslErrors(false) #endif {} }; diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index 2fe0d78..a623999 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -712,6 +712,13 @@ void QHttpNetworkReply::ignoreSslErrors() d->connection->ignoreSslErrors(); } +void QHttpNetworkReply::ignoreSslErrors(const QList &errors) +{ + Q_D(QHttpNetworkReply); + if (d->connection) + d->connection->ignoreSslErrors(errors); +} + #endif //QT_NO_OPENSSL diff --git a/src/network/access/qhttpnetworkreply_p.h b/src/network/access/qhttpnetworkreply_p.h index fbbee12..575e824 100644 --- a/src/network/access/qhttpnetworkreply_p.h +++ b/src/network/access/qhttpnetworkreply_p.h @@ -131,6 +131,7 @@ public: QSslConfiguration sslConfiguration() const; void setSslConfiguration(const QSslConfiguration &config); void ignoreSslErrors(); + void ignoreSslErrors(const QList &errors); Q_SIGNALS: void sslErrors(const QList &errors); diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 9e17b54..caaa38e 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -165,6 +165,12 @@ void QNetworkAccessBackend::ignoreSslErrors() // do nothing } +void QNetworkAccessBackend::ignoreSslErrors(const QList &errors) +{ + Q_UNUSED(errors); + // do nothing +} + void QNetworkAccessBackend::fetchSslConfiguration(QSslConfiguration &) const { // do nothing diff --git a/src/network/access/qnetworkaccessbackend_p.h b/src/network/access/qnetworkaccessbackend_p.h index 553b795..27da5bc 100644 --- a/src/network/access/qnetworkaccessbackend_p.h +++ b/src/network/access/qnetworkaccessbackend_p.h @@ -118,6 +118,7 @@ public: virtual void downstreamReadyWrite(); virtual void copyFinished(QIODevice *); virtual void ignoreSslErrors(); + virtual void ignoreSslErrors(const QList &errors); virtual void fetchSslConfiguration(QSslConfiguration &configuration) const; virtual void setSslConfiguration(const QSslConfiguration &configuration); diff --git a/src/network/access/qnetworkaccessdebugpipebackend.cpp b/src/network/access/qnetworkaccessdebugpipebackend.cpp index 2b3c128..394e196 100644 --- a/src/network/access/qnetworkaccessdebugpipebackend.cpp +++ b/src/network/access/qnetworkaccessdebugpipebackend.cpp @@ -280,6 +280,7 @@ void QNetworkAccessDebugPipeBackend::socketConnected() bool QNetworkAccessDebugPipeBackend::waitForDownstreamReadyRead(int ms) { + Q_UNUSED(ms); qCritical("QNetworkAccess: Debug pipe backend does not support waitForReadyRead()"); return false; } diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 9c36026..5c85735 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -294,7 +294,7 @@ public: QNetworkAccessHttpBackend::QNetworkAccessHttpBackend() : QNetworkAccessBackend(), httpReply(0), http(0), uploadDevice(0) #ifndef QT_NO_OPENSSL - , pendingSslConfiguration(0), pendingIgnoreSslErrors(false) + , pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false) #endif { } @@ -521,8 +521,9 @@ void QNetworkAccessHttpBackend::postRequest() #ifndef QT_NO_OPENSSL if (pendingSslConfiguration) httpReply->setSslConfiguration(*pendingSslConfiguration); - if (pendingIgnoreSslErrors) + if (pendingIgnoreAllSslErrors) httpReply->ignoreSslErrors(); + httpReply->ignoreSslErrors(pendingIgnoreSslErrorsList); #endif connect(httpReply, SIGNAL(readyRead()), SLOT(replyReadyRead())); @@ -883,7 +884,18 @@ void QNetworkAccessHttpBackend::ignoreSslErrors() if (httpReply) httpReply->ignoreSslErrors(); else - pendingIgnoreSslErrors = true; + pendingIgnoreAllSslErrors = true; +} + +void QNetworkAccessHttpBackend::ignoreSslErrors(const QList &errors) +{ + if (httpReply) { + httpReply->ignoreSslErrors(errors); + } else { + // the pending list is set if QNetworkReply::ignoreSslErrors(const QList &errors) + // is called before QNetworkAccessManager::get() (or post(), etc.) + pendingIgnoreSslErrorsList = errors; + } } void QNetworkAccessHttpBackend::fetchSslConfiguration(QSslConfiguration &config) const diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h index dec69d0..968f4a5 100644 --- a/src/network/access/qnetworkaccesshttpbackend_p.h +++ b/src/network/access/qnetworkaccesshttpbackend_p.h @@ -85,6 +85,7 @@ public: virtual void copyFinished(QIODevice *); #ifndef QT_NO_OPENSSL virtual void ignoreSslErrors(); + virtual void ignoreSslErrors(const QList &errors); virtual void fetchSslConfiguration(QSslConfiguration &configuration) const; virtual void setSslConfiguration(const QSslConfiguration &configuration); @@ -112,7 +113,8 @@ private: #ifndef QT_NO_OPENSSL QSslConfiguration *pendingSslConfiguration; - bool pendingIgnoreSslErrors; + bool pendingIgnoreAllSslErrors; + QList pendingIgnoreSslErrorsList; #endif void disconnectFromHttp(); diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index e807d29..3abf927 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -584,6 +584,38 @@ void QNetworkReply::setSslConfiguration(const QSslConfiguration &config) qt_metacall(QMetaObject::InvokeMetaMethod, id, arr); } } + +/*! + \overload + \since 4.6 + + If this function is called, the SSL errors given in \a errors + will be ignored. + + Note that you can set the expected certificate in the SSL error: + If, for instance, you want to issue a request to a server that uses + a self-signed certificate, consider the following snippet: + + \snippet doc/src/snippets/code/src_network_access_qnetworkreply.cpp 0 + + Multiple calls to this function will replace the list of errors that + were passed in previous calls. + You can clear the list of errors you want to ignore by calling this + function with an empty list. + + \sa sslConfiguration(), sslErrors(), QSslSocket::ignoreSslErrors() +*/ +void QNetworkReply::ignoreSslErrors(const QList &errors) +{ + // do this cryptic trick, because we could not add a virtual method to this class later on + // since that breaks binary compatibility + int id = metaObject()->indexOfMethod("ignoreSslErrorsImplementation(QList)"); + if (id != -1) { + QList copy(errors); + void *arr[] = { 0, © }; + qt_metacall(QMetaObject::InvokeMetaMethod, id, arr); + } +} #endif /*! @@ -598,7 +630,7 @@ void QNetworkReply::setSslConfiguration(const QSslConfiguration &config) sslErrors() signal, which indicates which errors were found. - \sa sslConfiguration(), sslErrors() + \sa sslConfiguration(), sslErrors(), QSslSocket::ignoreSslErrors() */ void QNetworkReply::ignoreSslErrors() { diff --git a/src/network/access/qnetworkreply.h b/src/network/access/qnetworkreply.h index 30e89f1..679ab71 100644 --- a/src/network/access/qnetworkreply.h +++ b/src/network/access/qnetworkreply.h @@ -134,6 +134,7 @@ public: #ifndef QT_NO_OPENSSL QSslConfiguration sslConfiguration() const; void setSslConfiguration(const QSslConfiguration &configuration); + void ignoreSslErrors(const QList &errors); #endif public Q_SLOTS: diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 1d4f70e..de7f8b4 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -659,6 +659,12 @@ void QNetworkReplyImpl::ignoreSslErrors() d->backend->ignoreSslErrors(); } +void QNetworkReplyImpl::ignoreSslErrorsImplementation(const QList &errors) +{ + Q_D(QNetworkReplyImpl); + if (d->backend) + d->backend->ignoreSslErrors(errors); +} #endif // QT_NO_OPENSSL /*! diff --git a/src/network/access/qnetworkreplyimpl_p.h b/src/network/access/qnetworkreplyimpl_p.h index 83a8aca..fba8d34 100644 --- a/src/network/access/qnetworkreplyimpl_p.h +++ b/src/network/access/qnetworkreplyimpl_p.h @@ -89,6 +89,7 @@ public: Q_INVOKABLE QSslConfiguration sslConfigurationImplementation() const; Q_INVOKABLE void setSslConfigurationImplementation(const QSslConfiguration &configuration); virtual void ignoreSslErrors(); + Q_INVOKABLE virtual void ignoreSslErrorsImplementation(const QList &errors); #endif Q_DECLARE_PRIVATE(QNetworkReplyImpl) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index fc297e4..df0afe3 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -356,7 +356,7 @@ QSslSocket::~QSslSocket() want to ignore the errors and continue connecting, you must call ignoreSslErrors(), either from inside a slot function connected to the sslErrors() signal, or prior to entering encrypted mode. If - ignoreSslErrors is not called, the connection is dropped, signal + ignoreSslErrors() is not called, the connection is dropped, signal disconnected() is emitted, and QSslSocket returns to the UnconnectedState. @@ -1592,7 +1592,33 @@ void QSslSocket::startServerEncryption() void QSslSocket::ignoreSslErrors() { Q_D(QSslSocket); - d->ignoreSslErrors = true; + d->ignoreAllSslErrors = true; +} + +/*! + \overload + \since 4.6 + + This method tells QSslSocket to ignore only the errors given in \a + errors. + + Note that you can set the expected certificate in the SSL error: + If, for instance, you want to connect to a server that uses + a self-signed certificate, consider the following snippet: + + \snippet doc/src/snippets/code/src_network_ssl_qsslsocket.cpp 6 + + Multiple calls to this function will replace the list of errors that + were passed in previous calls. + You can clear the list of errors you want to ignore by calling this + function with an empty list. + + \sa sslErrors() +*/ +void QSslSocket::ignoreSslErrors(const QList &errors) +{ + Q_D(QSslSocket); + d->ignoreErrorsList = errors; } /*! @@ -1732,7 +1758,11 @@ void QSslSocketPrivate::init() mode = QSslSocket::UnencryptedMode; autoStartHandshake = false; connectionEncrypted = false; - ignoreSslErrors = false; + ignoreAllSslErrors = false; + + // we don't want to clear the ignoreErrorsList, so + // that it is possible setting it before connecting +// ignoreErrorsList.clear(); readBuffer.clear(); writeBuffer.clear(); diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h index 785a083..cab0667 100644 --- a/src/network/ssl/qsslsocket.h +++ b/src/network/ssl/qsslsocket.h @@ -169,6 +169,7 @@ public: QList sslErrors() const; static bool supportsSsl(); + void ignoreSslErrors(const QList &errors); public Q_SLOTS: void startClientEncryption(); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index ea62a4d..130494e 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -839,7 +839,27 @@ bool QSslSocketBackendPrivate::startHandshake() if (!errors.isEmpty()) { sslErrors = errors; emit q->sslErrors(errors); - if (doVerifyPeer && !ignoreSslErrors) { + + bool doEmitSslError; + if (!ignoreErrorsList.empty()) { + // check whether the errors we got are all in the list of expected errors + // (applies only if the method QSslSocket::ignoreSslErrors(const QList &errors) + // was called) + doEmitSslError = false; + for (int a = 0; a < errors.count(); a++) { + if (!ignoreErrorsList.contains(errors.at(a))) { + doEmitSslError = true; + break; + } + } + } else { + // if QSslSocket::ignoreSslErrors(const QList &errors) was not called and + // we get an SSL error, emit a signal unless we ignored all errors (by calling + // QSslSocket::ignoreSslErrors() ) + doEmitSslError = !ignoreAllSslErrors; + } + // check whether we need to emit an SSL handshake error + if (doVerifyPeer && doEmitSslError) { q->setErrorString(sslErrors.first().errorString()); q->setSocketError(QAbstractSocket::SslHandshakeFailedError); emit q->error(QAbstractSocket::SslHandshakeFailedError); diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h index dc8e4f5..8fd2154 100644 --- a/src/network/ssl/qsslsocket_p.h +++ b/src/network/ssl/qsslsocket_p.h @@ -79,7 +79,8 @@ public: QSslSocket::SslMode mode; bool autoStartHandshake; bool connectionEncrypted; - bool ignoreSslErrors; + bool ignoreAllSslErrors; + QList ignoreErrorsList; bool* readyReadEmittedPointer; QRingBuffer readBuffer; diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index b67c727..788be1e 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -114,6 +114,7 @@ class tst_QNetworkReply: public QObject MyCookieJar *cookieJar; #ifndef QT_NO_OPENSSL QSslConfiguration storedSslConfiguration; + QList storedExpectedSslErrors; #endif public: @@ -126,9 +127,11 @@ public Q_SLOTS: void gotError(); void authenticationRequired(QNetworkReply*,QAuthenticator*); void proxyAuthenticationRequired(const QNetworkProxy &,QAuthenticator*); + #ifndef QT_NO_OPENSSL void sslErrors(QNetworkReply*,const QList &); void storeSslConfiguration(); + void ignoreSslErrorListSlot(QNetworkReply *reply, const QList &); #endif protected Q_SLOTS: @@ -247,6 +250,13 @@ private Q_SLOTS: void httpConnectionCount(); void httpDownloadPerformance_data(); void httpDownloadPerformance(); + +#ifndef QT_NO_OPENSSL + void ignoreSslErrorsList_data(); + void ignoreSslErrorsList(); + void ignoreSslErrorsListWithSlot_data(); + void ignoreSslErrorsListWithSlot(); +#endif }; QT_BEGIN_NAMESPACE @@ -3540,7 +3550,7 @@ void tst_QNetworkReply::httpProxyCommands_data() << QUrl("http://0.0.0.0:4443/http-request") << QByteArray("HTTP/1.0 200 OK\r\nProxy-Connection: close\r\nContent-Length: 1\r\n\r\n1") << "GET http://0.0.0.0:4443/http-request HTTP/1."; -#ifndef QT_NO_SSL +#ifndef QT_NO_OPENSSL QTest::newRow("https") << QUrl("https://0.0.0.0:4443/https-request") << QByteArray("HTTP/1.0 200 Connection Established\r\n\r\n") @@ -3832,5 +3842,81 @@ void tst_QNetworkReply::httpDownloadPerformance() delete reply; } +#ifndef QT_NO_OPENSSL +void tst_QNetworkReply::ignoreSslErrorsList_data() +{ + QTest::addColumn("url"); + QTest::addColumn >("expectedSslErrors"); + QTest::addColumn("expectedNetworkError"); + + QList expectedSslErrors; + // apparently, because of some weird behaviour of SRCDIR, the file name below needs to start with a slash + QList certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "/../qsslsocket/certs/qt-test-server-cacert.pem")); + QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0)); + QSslError wrongError(QSslError::SelfSignedCertificate); + + QTest::newRow("SSL-failure-empty-list") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::SslHandshakeFailedError; + expectedSslErrors.append(wrongError); + QTest::newRow("SSL-failure-wrong-error") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::SslHandshakeFailedError; + expectedSslErrors.append(rightError); + QTest::newRow("allErrorsInExpectedList1") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::NoError; + expectedSslErrors.removeAll(wrongError); + QTest::newRow("allErrorsInExpectedList2") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::NoError; + expectedSslErrors.removeAll(rightError); + QTest::newRow("SSL-failure-empty-list-again") << "https://" + QtNetworkSettings::serverName() + "/index.html" << expectedSslErrors << QNetworkReply::SslHandshakeFailedError; +} + +void tst_QNetworkReply::ignoreSslErrorsList() +{ + QFETCH(QString, url); + QNetworkRequest request(url); + QNetworkReply *reply = manager.get(request); + + QFETCH(QList, expectedSslErrors); + reply->ignoreSslErrors(expectedSslErrors); + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QFETCH(QNetworkReply::NetworkError, expectedNetworkError); + QCOMPARE(reply->error(), expectedNetworkError); +} + +void tst_QNetworkReply::ignoreSslErrorsListWithSlot_data() +{ + ignoreSslErrorsList_data(); +} + +// this is not a test, just a slot called in the test below +void tst_QNetworkReply::ignoreSslErrorListSlot(QNetworkReply *reply, const QList &) +{ + reply->ignoreSslErrors(storedExpectedSslErrors); +} + +// do the same as in ignoreSslErrorsList, but ignore the errors in the slot +void tst_QNetworkReply::ignoreSslErrorsListWithSlot() +{ + QFETCH(QString, url); + QNetworkRequest request(url); + QNetworkReply *reply = manager.get(request); + + QFETCH(QList, expectedSslErrors); + // store the errors to ignore them later in the slot connected below + storedExpectedSslErrors = expectedSslErrors; + connect(&manager, SIGNAL(sslErrors(QNetworkReply *, const QList &)), + this, SLOT(ignoreSslErrorListSlot(QNetworkReply *, const QList &))); + + + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QVERIFY(!QTestEventLoop::instance().timeout()); + + QFETCH(QNetworkReply::NetworkError, expectedNetworkError); + QCOMPARE(reply->error(), expectedNetworkError); +} + +#endif // QT_NO_OPENSSL + QTEST_MAIN(tst_QNetworkReply) #include "tst_qnetworkreply.moc" diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index bc9d1ca..23eee29 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -173,6 +173,10 @@ private slots: void disconnectFromHostWhenConnecting(); void disconnectFromHostWhenConnected(); void resetProxy(); + void ignoreSslErrorsList_data(); + void ignoreSslErrorsList(); + void ignoreSslErrorsListWithSlot_data(); + void ignoreSslErrorsListWithSlot(); static void exitLoop() { @@ -194,9 +198,11 @@ protected slots: if (errors.size() == 1 && errors.first().error() == QSslError::CertificateUntrusted) socket->ignoreSslErrors(); } + void ignoreErrorListSlot(const QList &errors); private: QSslSocket *socket; + QList storedExpectedSslErrors; #endif // QT_NO_OPENSSL private: static int loopLevel; @@ -609,7 +615,7 @@ void tst_QSslSocket::connectToHostEncryptedWithVerificationPeerName() QSslSocketPtr socket = newSocket(); this->socket = socket; - socket->addCaCertificates(QLatin1String("certs/qt-test-server-cacert.pem")); + socket->addCaCertificates(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")); #ifdef QSSLSOCKET_CERTUNTRUSTED_WORKAROUND connect(&socket, SIGNAL(sslErrors(QList)), this, SLOT(untrustedWorkaroundSlot(QList))); @@ -1537,6 +1543,82 @@ void tst_QSslSocket::resetProxy() QVERIFY2(socket2.waitForConnected(10000), qPrintable(socket.errorString())); } +void tst_QSslSocket::ignoreSslErrorsList_data() +{ + QTest::addColumn >("expectedSslErrors"); + QTest::addColumn("expectedSslErrorSignalCount"); + + // construct the list of errors that we will get with the SSL handshake and that we will ignore + QList expectedSslErrors; + // fromPath gives us a list of certs, but it actually only contains one + QList certs = QSslCertificate::fromPath(QLatin1String(SRCDIR "certs/qt-test-server-cacert.pem")); + QSslError rightError(QSslError::SelfSignedCertificate, certs.at(0)); + QSslError wrongError(QSslError::SelfSignedCertificate); + + + QTest::newRow("SSL-failure-empty-list") << expectedSslErrors << 1; + expectedSslErrors.append(wrongError); + QTest::newRow("SSL-failure-wrong-error") << expectedSslErrors << 1; + expectedSslErrors.append(rightError); + QTest::newRow("allErrorsInExpectedList1") << expectedSslErrors << 0; + expectedSslErrors.removeAll(wrongError); + QTest::newRow("allErrorsInExpectedList2") << expectedSslErrors << 0; + expectedSslErrors.removeAll(rightError); + QTest::newRow("SSL-failure-empty-list-again") << expectedSslErrors << 1; +} + +void tst_QSslSocket::ignoreSslErrorsList() +{ + QSslSocket socket; + connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + +// this->socket = &socket; + QSslCertificate cert; + + QFETCH(QList, expectedSslErrors); + socket.ignoreSslErrors(expectedSslErrors); + + QFETCH(int, expectedSslErrorSignalCount); + QSignalSpy sslErrorsSpy(&socket, SIGNAL(error(QAbstractSocket::SocketError))); + + socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + + bool expectEncryptionSuccess = (expectedSslErrorSignalCount == 0); + QCOMPARE(socket.waitForEncrypted(10000), expectEncryptionSuccess); + QCOMPARE(sslErrorsSpy.count(), expectedSslErrorSignalCount); +} + +void tst_QSslSocket::ignoreSslErrorsListWithSlot_data() +{ + ignoreSslErrorsList_data(); +} + +// this is not a test, just a slot called in the test below +void tst_QSslSocket::ignoreErrorListSlot(const QList &) +{ + socket->ignoreSslErrors(storedExpectedSslErrors); +} + +void tst_QSslSocket::ignoreSslErrorsListWithSlot() +{ + QSslSocket socket; + this->socket = &socket; + + QFETCH(QList, expectedSslErrors); + // store the errors to ignore them later in the slot connected below + storedExpectedSslErrors = expectedSslErrors; + connect(&socket, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), + this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); + connect(&socket, SIGNAL(sslErrors(const QList &)), + this, SLOT(ignoreErrorListSlot(const QList &))); + socket.connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + + QFETCH(int, expectedSslErrorSignalCount); + bool expectEncryptionSuccess = (expectedSslErrorSignalCount == 0); + QCOMPARE(socket.waitForEncrypted(10000), expectEncryptionSuccess); +} + #endif // QT_NO_OPENSSL QTEST_MAIN(tst_QSslSocket) -- cgit v0.12 From f81fcf7ea92e3d2a2291cca9b4908f5303dab00d Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 22 Jul 2009 18:26:30 +0200 Subject: fix linker error for the cetest tool Reviewed-by: TrustMe --- tools/qtestlib/wince/cetest/bootstrapped.pri | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/qtestlib/wince/cetest/bootstrapped.pri b/tools/qtestlib/wince/cetest/bootstrapped.pri index 39f24c2..a31374e 100644 --- a/tools/qtestlib/wince/cetest/bootstrapped.pri +++ b/tools/qtestlib/wince/cetest/bootstrapped.pri @@ -35,4 +35,5 @@ SOURCES += \ $$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qbitarray.cpp \ $$QT_SOURCE_TREE/src/corelib/kernel/qmetatype.cpp \ - $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp + $$QT_SOURCE_TREE/src/corelib/kernel/qvariant.cpp \ + $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec.cpp -- cgit v0.12 From d1eca480acd39c478957e39243ff61b55c0113b4 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Wed, 22 Jul 2009 18:28:18 +0200 Subject: Fix autotest compile failure --- tests/auto/qtoolbar/tst_qtoolbar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/auto/qtoolbar/tst_qtoolbar.cpp b/tests/auto/qtoolbar/tst_qtoolbar.cpp index 002ea04..856a935 100644 --- a/tests/auto/qtoolbar/tst_qtoolbar.cpp +++ b/tests/auto/qtoolbar/tst_qtoolbar.cpp @@ -797,8 +797,8 @@ void tst_QToolBar::toolButtonStyle() QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonTextUnderIcon); QCOMPARE(spy.count(), 0); - tb.setToolButtonStyle(Qt::ToolButtonSystemDefault); - QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonSystemDefault); + tb.setToolButtonStyle(Qt::ToolButtonFollowStyle); + QCOMPARE(tb.toolButtonStyle(), Qt::ToolButtonFollowStyle); QCOMPARE(spy.count(), 1); } -- cgit v0.12 From 8768bcfa0000bc216a7f722cd82ac6b06b85a70d Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 22 Jul 2009 17:38:12 +0200 Subject: Plug a texture leak when deleting QPixmaps without a current context ~QGLTexture wouldn't make the texture's context current if the current context was zero, meaning the texture would leak. This also means deleteBoundPixmap doesn't need to make the context currnet anymore (as it's only called from ~QGLTexture). Reviewed-By: Kim --- src/opengl/qgl_p.h | 11 ++++++++--- src/opengl/qgl_x11.cpp | 14 +------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 01385f0..2ee3e1d 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -402,7 +402,7 @@ extern Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg(); class QGLTexture { public: QGLTexture(QGLContext *ctx = 0, GLuint tx_id = 0, GLenum tx_target = GL_TEXTURE_2D, - bool _clean = true, bool _yInverted = false) + bool _clean = false, bool _yInverted = false) : context(ctx), id(tx_id), target(tx_target), clean(_clean), yInverted(_yInverted) #if defined(Q_WS_X11) , boundPixmap(0) @@ -413,14 +413,19 @@ public: if (clean) { QGLContext *current = const_cast(QGLContext::currentContext()); QGLContext *ctx = const_cast(context); - bool switch_context = current && current != ctx && !qgl_share_reg()->checkSharing(current, ctx); + Q_ASSERT(ctx); + bool switch_context = current != ctx && !qgl_share_reg()->checkSharing(current, ctx); if (switch_context) ctx->makeCurrent(); #if defined(Q_WS_X11) + // Although glXReleaseTexImage is a glX call, it must be called while there + // is a current context - the context the pixmap was bound to a texture in. + // Otherwise the release doesn't do anything and you get BadDrawable errors + // when you come to delete the context. deleteBoundPixmap(); #endif glDeleteTextures(1, &id); - if (switch_context) + if (switch_context && current) current->makeCurrent(); } } diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 0399b48..d8af4d5 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -1630,22 +1630,10 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pm, const qi void QGLTexture::deleteBoundPixmap() { if (boundPixmap) { - // Although glXReleaseTexImage is a glX call, it must be called while there - // is a current context - the context the pixmap was bound to a texture in. - // Otherwise the relese doesn't do anything and you get BadDrawable errors - // when you come to delete the context. - - QGLContext *oldContext = const_cast(QGLContext::currentContext()); - if (oldContext != context) - context->makeCurrent(); glXReleaseTexImageEXT(QX11Info::display(), boundPixmap, GLX_FRONT_LEFT_EXT); - if (oldContext && oldContext != context) - oldContext->makeCurrent(); - glXDestroyPixmap(QX11Info::display(), boundPixmap); + boundPixmap = 0; } - - boundPixmap = 0; } -- cgit v0.12 From 5796404298446038878da065c32429a0e31e9506 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Wed, 22 Jul 2009 18:43:06 +0200 Subject: Fix build on Mac The texture_from_pixmap patch removed a bindTexture overload from QGLContextPrivate which is actually needed by all architectures. It was just it's use in the mac compat methods which broke the build and highlighted the issue. Reviewed-By: Trustme --- src/opengl/qgl.cpp | 35 +++++++++++++++++++++++++++-------- src/opengl/qgl_p.h | 1 + 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 392e750..edda6b6 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1866,6 +1866,27 @@ QImage QGLContextPrivate::convertToGLFormat(const QImage &image, bool force_prem return result; } +/*! \internal */ +QGLTexture *QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, bool clean) +{ + const qint64 key = image.cacheKey(); + QGLTexture *texture = textureCacheLookup(key, target); + if (texture) { + glBindTexture(target, texture->id); + return texture; + } + + if (!texture) + texture = bindTexture(image, target, format, key, clean); + // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null + Q_ASSERT(texture); + + if (texture->id > 0) + const_cast(image).data_ptr()->is_cached = true; + + return texture; +} + QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key, bool clean) { @@ -2011,16 +2032,12 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, if (!texture) texture = bindTexture(pixmap.toImage(), target, format, key, clean); - - // We should never return 0 as callers shouldn't need to null-check - static QGLTexture invalidTexture; - if (!texture) - texture = &invalidTexture; + // NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null + Q_ASSERT(texture); if (texture->id > 0) const_cast(pixmap).data_ptr()->is_cached = true; - Q_ASSERT(texture); return texture; } @@ -2096,7 +2113,8 @@ GLuint QGLContext::bindTexture(const QImage &image, GLenum target, GLint format) GLuint QGLContext::bindTexture(const QImage &image, QMacCompatGLenum target, QMacCompatGLint format) { Q_D(QGLContext); - return d->bindTexture(image, GLenum(target), GLint(format), false); + QGLTexture *texture = d->bindTexture(image, GLenum(target), GLint(format), false); + return texture->id; } #endif @@ -2116,7 +2134,8 @@ GLuint QGLContext::bindTexture(const QPixmap &pixmap, GLenum target, GLint forma GLuint QGLContext::bindTexture(const QPixmap &pixmap, QMacCompatGLenum target, QMacCompatGLint format) { Q_D(QGLContext); - return d->bindTexture(pixmap, GLenum(target), GLint(format), false); + QGLTexture *texture = d->bindTexture(pixmap, GLenum(target), GLint(format), false, false); + return texture->id; } #endif diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 2ee3e1d..85dae0d 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -208,6 +208,7 @@ class QGLContextPrivate public: explicit QGLContextPrivate(QGLContext *context) : internal_context(false), q_ptr(context) {groupResources = new QGLContextGroupResources;} ~QGLContextPrivate() {if (!groupResources->refs.deref()) delete groupResources;} + QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format, bool clean); QGLTexture *bindTexture(const QImage &image, GLenum target, GLint format, const qint64 key, bool clean = false); QGLTexture *bindTexture(const QPixmap &pixmap, GLenum target, GLint format, bool clean, bool canInvert = false); -- cgit v0.12 From fa854a8ed0eaefa3a65c6b3b66e98ba5bdc6d6c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 22 Jul 2009 20:06:37 +0200 Subject: Fix potential deadlock in QAbstractFileEngine There's a possibility for deadlocking with user code in QAbstractFileEngine. Changing the QMutex there to a QReadWriteLock should reduce the possibilities for this happening. Also reduced the scope of the lock in QAbstractFileEngine. Reviewed-by: Thiago Macieira --- src/corelib/io/qabstractfileengine.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index 93097bc..9eb3305 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -42,7 +42,7 @@ #include "qabstractfileengine.h" #include "private/qabstractfileengine_p.h" #include "qdatetime.h" -#include "qmutex.h" +#include "qreadwritelock.h" #include "qvariant.h" // built-in handlers #include "qfsfileengine.h" @@ -98,14 +98,14 @@ QT_BEGIN_NAMESPACE All application-wide handlers are stored in this list. The mutex must be acquired to ensure thread safety. */ -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, fileEngineHandlerMutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, fileEngineHandlerMutex, (QReadWriteLock::Recursive)) static bool qt_abstractfileenginehandlerlist_shutDown = false; class QAbstractFileEngineHandlerList : public QList { public: ~QAbstractFileEngineHandlerList() { - QMutexLocker locker(fileEngineHandlerMutex()); + QWriteLocker locker(fileEngineHandlerMutex()); qt_abstractfileenginehandlerlist_shutDown = true; } }; @@ -122,7 +122,7 @@ Q_GLOBAL_STATIC(QAbstractFileEngineHandlerList, fileEngineHandlers) */ QAbstractFileEngineHandler::QAbstractFileEngineHandler() { - QMutexLocker locker(fileEngineHandlerMutex()); + QWriteLocker locker(fileEngineHandlerMutex()); fileEngineHandlers()->prepend(this); } @@ -132,7 +132,7 @@ QAbstractFileEngineHandler::QAbstractFileEngineHandler() */ QAbstractFileEngineHandler::~QAbstractFileEngineHandler() { - QMutexLocker locker(fileEngineHandlerMutex()); + QWriteLocker locker(fileEngineHandlerMutex()); // Remove this handler from the handler list only if the list is valid. if (!qt_abstractfileenginehandlerlist_shutDown) fileEngineHandlers()->removeAll(this); @@ -166,12 +166,14 @@ QAbstractFileEngineHandler::~QAbstractFileEngineHandler() */ QAbstractFileEngine *QAbstractFileEngine::create(const QString &fileName) { - QMutexLocker locker(fileEngineHandlerMutex()); + { + QReadLocker locker(fileEngineHandlerMutex()); - // check for registered handlers that can load the file - for (int i = 0; i < fileEngineHandlers()->size(); i++) { - if (QAbstractFileEngine *ret = fileEngineHandlers()->at(i)->create(fileName)) - return ret; + // check for registered handlers that can load the file + for (int i = 0; i < fileEngineHandlers()->size(); i++) { + if (QAbstractFileEngine *ret = fileEngineHandlers()->at(i)->create(fileName)) + return ret; + } } #ifdef QT_BUILD_CORE_LIB -- cgit v0.12 From 9e54faf9eae05f66b6772ef25cc63ce52babf7cd Mon Sep 17 00:00:00 2001 From: Kavindra Devi Palaraja Date: Wed, 22 Jul 2009 21:02:48 +0200 Subject: Doc - Clarified that Graphics View does not support the inverted y-axis coordinate system MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task: 258259 Reviewed-By: João Abecasis --- doc/src/graphicsview.qdoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/src/graphicsview.qdoc b/doc/src/graphicsview.qdoc index 4c408cd..f42c0d4 100644 --- a/doc/src/graphicsview.qdoc +++ b/doc/src/graphicsview.qdoc @@ -201,6 +201,9 @@ using an untransformed view, one unit on the scene is represented by one pixel on the screen. + \note The inverted Y-axis coordinate system (where \c y grows upwards) + is unsupported as Graphics Views uses Qt's coordinate system. + There are three effective coordinate systems in play in Graphics View: Item coordinates, scene coordinates, and view coordinates. To simplify your implementation, Graphics View provides convenience functions that -- cgit v0.12 From ed7b578fa09155458be48a419f29cc709129984a Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 14:39:35 -0700 Subject: Compile The dummy implementaion of QReadWriteLock wasn't source compatible with the real implementation and this lead to compilation errors in qabstractfileengine.cpp which now has a global static QReadWriteLock that takes a Recursive argument. Reviewed-by: Noam Rosenthal --- src/corelib/thread/qreadwritelock.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/corelib/thread/qreadwritelock.h b/src/corelib/thread/qreadwritelock.h index 51d42b5..4742bea 100644 --- a/src/corelib/thread/qreadwritelock.h +++ b/src/corelib/thread/qreadwritelock.h @@ -190,7 +190,8 @@ inline QWriteLocker::QWriteLocker(QReadWriteLock *areadWriteLock) class Q_CORE_EXPORT QReadWriteLock { public: - inline explicit QReadWriteLock() { } + enum RecursionMode { NonRecursive, Recursive }; + inline explicit QReadWriteLock(RecursionMode = NonRecursive) { } inline ~QReadWriteLock() { } static inline void lockForRead() { } -- cgit v0.12 From b11f173a57128416ce314796e7b0320ad7c05bf7 Mon Sep 17 00:00:00 2001 From: Anders Bakken Date: Wed, 22 Jul 2009 15:07:38 -0700 Subject: Compile in release mode for DFB version > 0.9 Something went wrong with the integrate from 4.5 to master. Reviewed-by: TrustMe --- src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 67cad6f..0928643 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -744,7 +744,12 @@ QPixmapData *QDirectFBScreenPrivate::createPixmapData(QPixmapData::PixelType typ return new QDirectFBPixmapData(type); } -#ifndef QT_NO_DEBUG +#ifdef QT_NO_DEBUG +struct FlagDescription; +static const FlagDescription *accelerationDescriptions = 0; +static const FlagDescription *blitDescriptions = 0; +static const FlagDescription *drawDescriptions = 0; +#else struct FlagDescription { const char *name; uint flag; -- cgit v0.12 From c42f7058dfd7ea551b2d3bca5651b0c802c91259 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 23 Jul 2009 10:58:55 +1000 Subject: Add the math3d types to QVariant Reviewed-by: Sarah Smith --- src/corelib/kernel/qmetatype.cpp | 20 +++++ src/corelib/kernel/qmetatype.h | 14 +++- src/corelib/kernel/qvariant.cpp | 7 +- src/corelib/kernel/qvariant.h | 7 +- src/gui/kernel/qguivariant.cpp | 161 ++++++++++++++++++++++++++++++++++++++- src/gui/math3d/qmatrix4x4.cpp | 47 +++++++++++- src/gui/math3d/qmatrix4x4.h | 9 ++- src/gui/math3d/qquaternion.cpp | 45 +++++++++++ src/gui/math3d/qquaternion.h | 9 ++- src/gui/math3d/qvector2d.cpp | 42 +++++++++- src/gui/math3d/qvector2d.h | 9 ++- src/gui/math3d/qvector3d.cpp | 45 ++++++++++- src/gui/math3d/qvector3d.h | 9 ++- src/gui/math3d/qvector4d.cpp | 47 +++++++++++- src/gui/math3d/qvector4d.h | 9 ++- 15 files changed, 452 insertions(+), 28 deletions(-) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 6d9daec..bd27ec2 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -171,6 +171,11 @@ QT_BEGIN_NAMESPACE \value QBitmap QBitmap \value QMatrix QMatrix \value QTransform QTransform + \value QMatrix4x4 QMatrix4x4 + \value QVector2D QVector2D + \value QVector3D QVector3D + \value QVector4D QVector4D + \value QQuaternion QQuaternion \value User Base value for user types @@ -272,6 +277,11 @@ static const struct { const char * typeName; int type; } types[] = { {"QTextFormat", QMetaType::QTextFormat}, {"QMatrix", QMetaType::QMatrix}, {"QTransform", QMetaType::QTransform}, + {"QMatrix4x4", QMetaType::QMatrix4x4}, + {"QVector2D", QMetaType::QVector2D}, + {"QVector3D", QMetaType::QVector3D}, + {"QVector4D", QMetaType::QVector4D}, + {"QQuaternion", QMetaType::QQuaternion}, /* All Metatype builtins */ {"void*", QMetaType::VoidStar}, @@ -670,6 +680,11 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data) case QMetaType::QTextFormat: case QMetaType::QMatrix: case QMetaType::QTransform: + case QMetaType::QMatrix4x4: + case QMetaType::QVector2D: + case QMetaType::QVector3D: + case QMetaType::QVector4D: + case QMetaType::QQuaternion: if (!qMetaTypeGuiHelper) return false; qMetaTypeGuiHelper[type - FirstGuiType].saveOp(stream, data); @@ -862,6 +877,11 @@ bool QMetaType::load(QDataStream &stream, int type, void *data) case QMetaType::QTextFormat: case QMetaType::QMatrix: case QMetaType::QTransform: + case QMetaType::QMatrix4x4: + case QMetaType::QVector2D: + case QMetaType::QVector3D: + case QMetaType::QVector4D: + case QMetaType::QQuaternion: if (!qMetaTypeGuiHelper) return false; qMetaTypeGuiHelper[type - FirstGuiType].loadOp(stream, data); diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index 497c014..052312c 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -79,7 +79,9 @@ public: QIcon = 69, QImage = 70, QPolygon = 71, QRegion = 72, QBitmap = 73, QCursor = 74, QSizePolicy = 75, QKeySequence = 76, QPen = 77, QTextLength = 78, QTextFormat = 79, QMatrix = 80, QTransform = 81, - LastGuiType = 81 /* QTransform */, + QMatrix4x4 = 82, QVector2D = 83, QVector3D = 84, QVector4D = 85, + QQuaternion = 86, + LastGuiType = 86 /* QQuaternion */, FirstCoreExtType = 128 /* VoidStar */, VoidStar = 128, Long = 129, Short = 130, Char = 131, ULong = 132, @@ -292,6 +294,11 @@ class QTextLength; class QTextFormat; class QMatrix; class QTransform; +class QMatrix4x4; +class QVector2D; +class QVector3D; +class QVector4D; +class QQuaternion; QT_END_NAMESPACE @@ -354,6 +361,11 @@ Q_DECLARE_BUILTIN_METATYPE(QTextLength, QTextLength) Q_DECLARE_BUILTIN_METATYPE(QTextFormat, QTextFormat) Q_DECLARE_BUILTIN_METATYPE(QMatrix, QMatrix) Q_DECLARE_BUILTIN_METATYPE(QTransform, QTransform) +Q_DECLARE_BUILTIN_METATYPE(QMatrix4x4, QMatrix4x4) +Q_DECLARE_BUILTIN_METATYPE(QVector2D, QVector2D) +Q_DECLARE_BUILTIN_METATYPE(QVector3D, QVector3D) +Q_DECLARE_BUILTIN_METATYPE(QVector4D, QVector4D) +Q_DECLARE_BUILTIN_METATYPE(QQuaternion, QQuaternion) QT_END_HEADER diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index 2ef9de4..2b5ea0a 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -1264,6 +1264,7 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler; \value Map a QVariantMap \value Matrix a QMatrix \value Transform a QTransform + \value Matrix4x4 a QMatrix4x4 \value Palette a QPalette \value Pen a QPen \value Pixmap a QPixmap @@ -1271,6 +1272,7 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler; \value PointArray a QPointArray \value PointF a QPointF \value Polygon a QPolygon + \value Quaternion a QQuaternion \value Rect a QRect \value RectF a QRectF \value RegExp a QRegExp @@ -1286,6 +1288,9 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler; \value UInt a \l uint \value ULongLong a \l qulonglong \value Url a QUrl + \value Vector2D a QVector2D + \value Vector3D a QVector3D + \value Vector4D a QVector4D \value UserType Base value for user-defined types. @@ -1677,7 +1682,7 @@ QVariant::QVariant(Qt::GlobalColor color) { create(62, &color); } Note that return values in the ranges QVariant::Char through QVariant::RegExp and QVariant::Font through QVariant::Transform correspond to the values in the ranges QMetaType::QChar through - QMetaType::QRegExp and QMetaType::QFont through QMetaType::QTransform. + QMetaType::QRegExp and QMetaType::QFont through QMetaType::QQuaternion. Pay particular attention when working with char and QChar variants. Note that there is no QVariant constructor specifically diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h index e923844..a68939d 100644 --- a/src/corelib/kernel/qvariant.h +++ b/src/corelib/kernel/qvariant.h @@ -154,7 +154,12 @@ class Q_CORE_EXPORT QVariant TextFormat = 79, Matrix = 80, Transform = 81, - LastGuiType = Transform, + Matrix4x4 = 82, + Vector2D = 83, + Vector3D = 84, + Vector4D = 85, + Quaternion = 86, + LastGuiType = Quaternion, UserType = 127, #ifdef QT3_SUPPORT diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp index 01df47d..ab69cdf 100644 --- a/src/gui/kernel/qguivariant.cpp +++ b/src/gui/kernel/qguivariant.cpp @@ -60,6 +60,11 @@ #include "qregion.h" #include "qsizepolicy.h" #include "qtextformat.h" +#include "qmatrix4x4.h" +#include "qvector2d.h" +#include "qvector3d.h" +#include "qvector4d.h" +#include "qquaternion.h" #include "private/qvariant_p.h" @@ -148,6 +153,31 @@ static void construct(QVariant::Private *x, const void *copy) v_construct(x, &color); break; } +#ifndef QT_NO_MATRIX4X4 + case QVariant::Matrix4x4: + v_construct(x, copy); + break; +#endif +#ifndef QT_NO_VECTOR2D + case QVariant::Vector2D: + v_construct(x, copy); + break; +#endif +#ifndef QT_NO_VECTOR3D + case QVariant::Vector3D: + v_construct(x, copy); + break; +#endif +#ifndef QT_NO_VECTOR4D + case QVariant::Vector4D: + v_construct(x, copy); + break; +#endif +#ifndef QT_NO_QUATERNION + case QVariant::Quaternion: + v_construct(x, copy); + break; +#endif default: qcoreVariantHandler()->construct(x, copy); return; @@ -221,6 +251,31 @@ static void clear(QVariant::Private *d) case QVariant::Pen: v_clear(d); break; +#ifndef QT_NO_MATRIX4X4 + case QVariant::Matrix4x4: + v_clear(d); + break; +#endif +#ifndef QT_NO_VECTOR2D + case QVariant::Vector2D: + v_clear(d); + break; +#endif +#ifndef QT_NO_VECTOR3D + case QVariant::Vector3D: + v_clear(d); + break; +#endif +#ifndef QT_NO_VECTOR4D + case QVariant::Vector4D: + v_clear(d); + break; +#endif +#ifndef QT_NO_QUATERNION + case QVariant::Quaternion: + v_clear(d); + break; +#endif default: qcoreVariantHandler()->clear(d); return; @@ -266,7 +321,26 @@ static bool isNull(const QVariant::Private *d) case QVariant::KeySequence: #endif case QVariant::Pen: +#ifndef QT_NO_MATRIX4X4 + case QVariant::Matrix4x4: +#endif break; +#ifndef QT_NO_VECTOR2D + case QVariant::Vector2D: + return v_cast(d)->isNull(); +#endif +#ifndef QT_NO_VECTOR3D + case QVariant::Vector3D: + return v_cast(d)->isNull(); +#endif +#ifndef QT_NO_VECTOR4D + case QVariant::Vector4D: + return v_cast(d)->isNull(); +#endif +#ifndef QT_NO_QUATERNION + case QVariant::Quaternion: + return v_cast(d)->isNull(); +#endif default: return qcoreVariantHandler()->isNull(d); } @@ -326,6 +400,26 @@ static bool compare(const QVariant::Private *a, const QVariant::Private *b) #endif case QVariant::Pen: return *v_cast(a) == *v_cast(b); +#ifndef QT_NO_MATRIX4X4 + case QVariant::Matrix4x4: + return *v_cast(a) == *v_cast(b); +#endif +#ifndef QT_NO_VECTOR2D + case QVariant::Vector2D: + return *v_cast(a) == *v_cast(b); +#endif +#ifndef QT_NO_VECTOR3D + case QVariant::Vector3D: + return *v_cast(a) == *v_cast(b); +#endif +#ifndef QT_NO_VECTOR4D + case QVariant::Vector4D: + return *v_cast(a) == *v_cast(b); +#endif +#ifndef QT_NO_QUATERNION + case QVariant::Quaternion: + return *v_cast(a) == *v_cast(b); +#endif default: break; } @@ -513,6 +607,31 @@ static void streamDebug(QDebug dbg, const QVariant &v) case QVariant::Pen: dbg.nospace() << qvariant_cast(v); break; +#ifndef QT_NO_MATRIX4X4 + case QVariant::Matrix4x4: + dbg.nospace() << qvariant_cast(v); + break; +#endif +#ifndef QT_NO_VECTOR2D + case QVariant::Vector2D: + dbg.nospace() << qvariant_cast(v); + break; +#endif +#ifndef QT_NO_VECTOR3D + case QVariant::Vector3D: + dbg.nospace() << qvariant_cast(v); + break; +#endif +#ifndef QT_NO_VECTOR4D + case QVariant::Vector4D: + dbg.nospace() << qvariant_cast(v); + break; +#endif +#ifndef QT_NO_QUATERNION + case QVariant::Quaternion: + dbg.nospace() << qvariant_cast(v); + break; +#endif default: qcoreVariantHandler()->debugStream(dbg, v); break; @@ -596,6 +715,21 @@ Q_DECL_METATYPE_HELPER(QTextLength) Q_DECL_METATYPE_HELPER(QTextFormat) Q_DECL_METATYPE_HELPER(QMatrix) Q_DECL_METATYPE_HELPER(QTransform) +#ifndef QT_NO_MATRIX4X4 +Q_DECL_METATYPE_HELPER(QMatrix4x4) +#endif +#ifndef QT_NO_VECTOR2D +Q_DECL_METATYPE_HELPER(QVector2D) +#endif +#ifndef QT_NO_VECTOR3D +Q_DECL_METATYPE_HELPER(QVector3D) +#endif +#ifndef QT_NO_VECTOR4D +Q_DECL_METATYPE_HELPER(QVector4D) +#endif +#ifndef QT_NO_QUATERNION +Q_DECL_METATYPE_HELPER(QQuaternion) +#endif #ifdef QT_NO_DATASTREAM # define Q_IMPL_METATYPE_HELPER(TYPE) \ @@ -645,7 +779,32 @@ static const QMetaTypeGuiHelper qVariantGuiHelper[] = { Q_IMPL_METATYPE_HELPER(QTextLength), Q_IMPL_METATYPE_HELPER(QTextFormat), Q_IMPL_METATYPE_HELPER(QMatrix), - Q_IMPL_METATYPE_HELPER(QTransform) + Q_IMPL_METATYPE_HELPER(QTransform), +#ifndef QT_NO_MATRIX4X4 + Q_IMPL_METATYPE_HELPER(QMatrix4x4), +#else + {0, 0, 0, 0}, +#endif +#ifndef QT_NO_VECTOR2D + Q_IMPL_METATYPE_HELPER(QVector2D), +#else + {0, 0, 0, 0}, +#endif +#ifndef QT_NO_VECTOR3D + Q_IMPL_METATYPE_HELPER(QVector3D), +#else + {0, 0, 0, 0}, +#endif +#ifndef QT_NO_VECTOR4D + Q_IMPL_METATYPE_HELPER(QVector4D), +#else + {0, 0, 0, 0}, +#endif +#ifndef QT_NO_QUATERNION + Q_IMPL_METATYPE_HELPER(QQuaternion) +#else + {0, 0, 0, 0} +#endif }; static const QVariant::Handler *qt_guivariant_last_handler = 0; diff --git a/src/gui/math3d/qmatrix4x4.cpp b/src/gui/math3d/qmatrix4x4.cpp index 88f58c8..b4c54a0 100644 --- a/src/gui/math3d/qmatrix4x4.cpp +++ b/src/gui/math3d/qmatrix4x4.cpp @@ -1794,6 +1794,51 @@ QDebug operator<<(QDebug dbg, const QMatrix4x4 &m) #endif -#endif +#ifndef QT_NO_DATASTREAM + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix) + \relates QMatrix4x4 + + Writes the given \a matrix to the given \a stream and returns a + reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator<<(QDataStream &stream, const QMatrix4x4 &matrix) +{ + for (int row = 0; row < 4; ++row) + for (int col = 0; col < 4; ++col) + stream << double(matrix(row, col)); + return stream; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix) + \relates QMatrix4x4 + + Reads a 4x4 matrix from the given \a stream into the given \a matrix + and returns a reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator>>(QDataStream &stream, QMatrix4x4 &matrix) +{ + double x; + for (int row = 0; row < 4; ++row) { + for (int col = 0; col < 4; ++col) { + stream >> x; + matrix(row, col) = float(x); + } + } + matrix.inferSpecialType(); + return stream; +} + +#endif // QT_NO_DATASTREAM + +#endif // QT_NO_MATRIX4X4 QT_END_NAMESPACE diff --git a/src/gui/math3d/qmatrix4x4.h b/src/gui/math3d/qmatrix4x4.h index d63de70..f7246bb 100644 --- a/src/gui/math3d/qmatrix4x4.h +++ b/src/gui/math3d/qmatrix4x4.h @@ -960,6 +960,11 @@ inline float *QMatrix4x4::data() Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QMatrix4x4 &m); #endif +#ifndef QT_NO_DATASTREAM +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QMatrix4x4 &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QMatrix4x4 &); +#endif + template QMatrix4x4 qGenericMatrixToMatrix4x4(const QGenericMatrix& matrix) { @@ -989,10 +994,6 @@ QGenericMatrix qGenericMatrixFromMatrix4x4(const QMatrix4x4& QT_END_NAMESPACE -#ifndef QT_NO_MATRIX4X4 -Q_DECLARE_METATYPE(QMatrix4x4) -#endif - QT_END_HEADER #endif diff --git a/src/gui/math3d/qquaternion.cpp b/src/gui/math3d/qquaternion.cpp index d9d4160..841a4c0 100644 --- a/src/gui/math3d/qquaternion.cpp +++ b/src/gui/math3d/qquaternion.cpp @@ -571,6 +571,51 @@ QDebug operator<<(QDebug dbg, const QQuaternion &q) #endif +#ifndef QT_NO_DATASTREAM + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion) + \relates QQuaternion + + Writes the given \a quaternion to the given \a stream and returns a + reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator<<(QDataStream &stream, const QQuaternion &quaternion) +{ + stream << double(quaternion.scalar()) << double(quaternion.x()) + << double(quaternion.y()) << double(quaternion.z()); + return stream; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QQuaternion &quaternion) + \relates QQuaternion + + Reads a quaternion from the given \a stream into the given \a quaternion + and returns a reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator>>(QDataStream &stream, QQuaternion &quaternion) +{ + double scalar, x, y, z; + stream >> scalar; + stream >> x; + stream >> y; + stream >> z; + quaternion.setScalar(qreal(scalar)); + quaternion.setX(qreal(x)); + quaternion.setY(qreal(y)); + quaternion.setZ(qreal(z)); + return stream; +} + +#endif // QT_NO_DATASTREAM + #endif QT_END_NAMESPACE diff --git a/src/gui/math3d/qquaternion.h b/src/gui/math3d/qquaternion.h index 6b24a04..55c871d 100644 --- a/src/gui/math3d/qquaternion.h +++ b/src/gui/math3d/qquaternion.h @@ -324,14 +324,15 @@ inline QVector4D QQuaternion::toVector4D() const Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QQuaternion &q); #endif +#ifndef QT_NO_DATASTREAM +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QQuaternion &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QQuaternion &); #endif -QT_END_NAMESPACE - -#ifndef QT_NO_QUATERNION -Q_DECLARE_METATYPE(QQuaternion) #endif +QT_END_NAMESPACE + QT_END_HEADER #endif diff --git a/src/gui/math3d/qvector2d.cpp b/src/gui/math3d/qvector2d.cpp index b492aa8..28f6b7a 100644 --- a/src/gui/math3d/qvector2d.cpp +++ b/src/gui/math3d/qvector2d.cpp @@ -410,6 +410,46 @@ QDebug operator<<(QDebug dbg, const QVector2D &vector) #endif -#endif +#ifndef QT_NO_DATASTREAM + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QVector2D &vector) + \relates QVector2D + + Writes the given \a vector to the given \a stream and returns a + reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator<<(QDataStream &stream, const QVector2D &vector) +{ + stream << double(vector.x()) << double(vector.y()); + return stream; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QVector2D &vector) + \relates QVector2D + + Reads a 2D vector from the given \a stream into the given \a vector + and returns a reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator>>(QDataStream &stream, QVector2D &vector) +{ + double x, y; + stream >> x; + stream >> y; + vector.setX(qreal(x)); + vector.setY(qreal(y)); + return stream; +} + +#endif // QT_NO_DATASTREAM + +#endif // QT_NO_VECTOR2D QT_END_NAMESPACE diff --git a/src/gui/math3d/qvector2d.h b/src/gui/math3d/qvector2d.h index bb62afe..d473c2f 100644 --- a/src/gui/math3d/qvector2d.h +++ b/src/gui/math3d/qvector2d.h @@ -243,14 +243,15 @@ inline QPointF QVector2D::toPointF() const Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QVector2D &vector); #endif +#ifndef QT_NO_DATASTREAM +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QVector2D &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector2D &); #endif -QT_END_NAMESPACE - -#ifndef QT_NO_VECTOR2D -Q_DECLARE_METATYPE(QVector2D) #endif +QT_END_NAMESPACE + QT_END_HEADER #endif diff --git a/src/gui/math3d/qvector3d.cpp b/src/gui/math3d/qvector3d.cpp index 95550cd..881f47c 100644 --- a/src/gui/math3d/qvector3d.cpp +++ b/src/gui/math3d/qvector3d.cpp @@ -558,6 +558,49 @@ QDebug operator<<(QDebug dbg, const QVector3D &vector) #endif -#endif +#ifndef QT_NO_DATASTREAM + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QVector3D &vector) + \relates QVector3D + + Writes the given \a vector to the given \a stream and returns a + reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator<<(QDataStream &stream, const QVector3D &vector) +{ + stream << double(vector.x()) << double(vector.y()) + << double(vector.z()); + return stream; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QVector3D &vector) + \relates QVector3D + + Reads a 3D vector from the given \a stream into the given \a vector + and returns a reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator>>(QDataStream &stream, QVector3D &vector) +{ + double x, y, z; + stream >> x; + stream >> y; + stream >> z; + vector.setX(qreal(x)); + vector.setY(qreal(y)); + vector.setZ(qreal(z)); + return stream; +} + +#endif // QT_NO_DATASTREAM + +#endif // QT_NO_VECTOR3D QT_END_NAMESPACE diff --git a/src/gui/math3d/qvector3d.h b/src/gui/math3d/qvector3d.h index 873b388..7494dcf 100644 --- a/src/gui/math3d/qvector3d.h +++ b/src/gui/math3d/qvector3d.h @@ -271,14 +271,15 @@ inline QPointF QVector3D::toPointF() const Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QVector3D &vector); #endif +#ifndef QT_NO_DATASTREAM +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QVector3D &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector3D &); #endif -QT_END_NAMESPACE - -#ifndef QT_NO_VECTOR3D -Q_DECLARE_METATYPE(QVector3D) #endif +QT_END_NAMESPACE + QT_END_HEADER #endif diff --git a/src/gui/math3d/qvector4d.cpp b/src/gui/math3d/qvector4d.cpp index 1f7d921..1a84db6 100644 --- a/src/gui/math3d/qvector4d.cpp +++ b/src/gui/math3d/qvector4d.cpp @@ -509,6 +509,51 @@ QDebug operator<<(QDebug dbg, const QVector4D &vector) #endif -#endif +#ifndef QT_NO_DATASTREAM + +/*! + \fn QDataStream &operator<<(QDataStream &stream, const QVector4D &vector) + \relates QVector4D + + Writes the given \a vector to the given \a stream and returns a + reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator<<(QDataStream &stream, const QVector4D &vector) +{ + stream << double(vector.x()) << double(vector.y()) + << double(vector.z()) << double(vector.w()); + return stream; +} + +/*! + \fn QDataStream &operator>>(QDataStream &stream, QVector4D &vector) + \relates QVector4D + + Reads a 4D vector from the given \a stream into the given \a vector + and returns a reference to the stream. + + \sa {Format of the QDataStream Operators} +*/ + +QDataStream &operator>>(QDataStream &stream, QVector4D &vector) +{ + double x, y, z, w; + stream >> x; + stream >> y; + stream >> z; + stream >> w; + vector.setX(qreal(x)); + vector.setY(qreal(y)); + vector.setZ(qreal(z)); + vector.setW(qreal(w)); + return stream; +} + +#endif // QT_NO_DATASTREAM + +#endif // QT_NO_VECTOR4D QT_END_NAMESPACE diff --git a/src/gui/math3d/qvector4d.h b/src/gui/math3d/qvector4d.h index dcfd87a..cd61496 100644 --- a/src/gui/math3d/qvector4d.h +++ b/src/gui/math3d/qvector4d.h @@ -276,14 +276,15 @@ inline QPointF QVector4D::toPointF() const Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QVector4D &vector); #endif +#ifndef QT_NO_DATASTREAM +Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QVector4D &); +Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QVector4D &); #endif -QT_END_NAMESPACE - -#ifndef QT_NO_VECTOR4D -Q_DECLARE_METATYPE(QVector4D) #endif +QT_END_NAMESPACE + QT_END_HEADER #endif -- cgit v0.12 From 708150e3a88fdc5f7c3d1998f2b5132cea264a71 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 23 Jul 2009 08:35:03 +0200 Subject: Add texture_from_pixmap defines for systems without them This fixes the build on older Solaris machines which don't have the GLX_EXT_texture_from_pixmap defines in glxext.h. Reviewed-By: Trustme --- src/opengl/qgl_x11.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index d8af4d5..43bdec7 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -82,6 +82,25 @@ extern const QX11Info *qt_x11Info(const QPaintDevice *pd); #define GLX_SAMPLES_ARB 100001 #endif +#ifndef GLX_EXT_texture_from_pixmap +#define GLX_TEXTURE_2D_BIT_EXT 0x00000002 +#define GLX_TEXTURE_RECTANGLE_BIT_EXT 0x00000004 +#define GLX_BIND_TO_TEXTURE_RGB_EXT 0x20D0 +#define GLX_BIND_TO_TEXTURE_RGBA_EXT 0x20D1 +#define GLX_BIND_TO_MIPMAP_TEXTURE_EXT 0x20D2 +#define GLX_BIND_TO_TEXTURE_TARGETS_EXT 0x20D3 +#define GLX_Y_INVERTED_EXT 0x20D4 +#define GLX_TEXTURE_FORMAT_EXT 0x20D5 +#define GLX_TEXTURE_TARGET_EXT 0x20D6 +#define GLX_MIPMAP_TEXTURE_EXT 0x20D7 +#define GLX_TEXTURE_FORMAT_NONE_EXT 0x20D8 +#define GLX_TEXTURE_FORMAT_RGB_EXT 0x20D9 +#define GLX_TEXTURE_FORMAT_RGBA_EXT 0x20DA +#define GLX_TEXTURE_2D_EXT 0x20DC +#define GLX_TEXTURE_RECTANGLE_EXT 0x20DD +#define GLX_FRONT_LEFT_EXT 0x20DE +#endif + /* The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext() and GLX (not Windows). If the application can't find any sharable -- cgit v0.12 From 3f630677d415d4a67938fa6cf64754c80aa30ba0 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Wed, 22 Jul 2009 09:19:12 +0200 Subject: Add QGraphicsItem::focusProxy(), focus proxy support. Following QWidget's behavior, you can not assign any item in the same scene as a focus proxy for another item. Also supports nested focus proxies. You can only assign items in the same scene as focus proxies. Autotests are included. Reviewed-By: mbm --- src/gui/graphicsview/qgraphicsitem.cpp | 76 ++++++++++++++-- src/gui/graphicsview/qgraphicsitem.h | 3 + src/gui/graphicsview/qgraphicsitem_p.h | 2 + src/gui/graphicsview/qgraphicsscene.cpp | 106 +++++++++++++--------- src/gui/graphicsview/qgraphicsscene_p.h | 2 + tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 120 +++++++++++++++++++++++++ 6 files changed, 261 insertions(+), 48 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index ae2a2c3..4e3677a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2455,6 +2455,8 @@ void QGraphicsItem::setHandlesChildEvents(bool enabled) */ bool QGraphicsItem::hasFocus() const { + if (d_ptr->focusProxy) + return d_ptr->focusProxy->hasFocus(); return (d_ptr->scene && d_ptr->scene->focusItem() == this); } @@ -2480,12 +2482,16 @@ void QGraphicsItem::setFocus(Qt::FocusReason focusReason) { if (!d_ptr->scene || !isEnabled() || hasFocus() || !(d_ptr->flags & ItemIsFocusable)) return; - if (isVisible()) { + QGraphicsItem *item = this; + QGraphicsItem *f; + while ((f = item->d_ptr->focusProxy)) + item = f; + if (item->isVisible()) { // Visible items immediately gain focus from scene. - d_ptr->scene->setFocusItem(this, focusReason); - } else if (d_ptr->isWidget) { + d_ptr->scene->d_func()->setFocusItemHelper(item, focusReason); + } else if (item->d_ptr->isWidget) { // Just set up subfocus. - static_cast(this)->d_func()->setFocusWidget(); + static_cast(item)->d_func()->setFocusWidget(); } } @@ -2508,13 +2514,73 @@ void QGraphicsItem::clearFocus() // Invisible widget items with focus must explicitly clear subfocus. static_cast(this)->d_func()->clearFocusWidget(); } - if (d_ptr->scene->focusItem() == this) { + if (hasFocus()) { // If this item has the scene's input focus, clear it. d_ptr->scene->setFocusItem(0); } } /*! + \since 4.6 + + Returns this item's focus proxy, or 0 if the item + does not have any focus proxy. + + \sa setFocusProxy() +*/ +QGraphicsItem *QGraphicsItem::focusProxy() const +{ + return d_ptr->focusProxy; +} + +/*! + \since 4.6 + + Sets the item's focus proxy to \a item. + + If an item has a focus proxy, the focus proxy will receive + input focus when the item gains input focus. The item itself + will still have focus (i.e., hasFocus() will return true), + but only the focus proxy will receive the keyboard input. + + A focus proxy can itself have a focus proxy, and so on. In + such case, keyboard input will be handled by the outermost + focus proxy. + + \sa focusProxy() +*/ +void QGraphicsItem::setFocusProxy(QGraphicsItem *item) +{ + if (item == d_ptr->focusProxy) + return; + if (item == this) { + qWarning("QGraphicsItem::setFocusProxy: cannot assign self as focus proxy"); + return; + } + if (item) { + if (item->d_ptr->scene != d_ptr->scene) { + qWarning("QGraphicsItem::setFocusProxy: focus proxy must be in same scene"); + return; + } + for (QGraphicsItem *f = item->focusProxy(); f != 0; f = f->focusProxy()) { + if (f == this) { + qWarning("QGraphicsItem::setFocusProxy: %p is already in the focus proxy chain", item); + return; + } + } + } + + QGraphicsItem *lastFocusProxy = d_ptr->focusProxy; + d_ptr->focusProxy = item; + if (d_ptr->scene) { + if (lastFocusProxy) + d_ptr->scene->d_func()->focusProxyReverseMap.remove(lastFocusProxy, this); + if (item) + d_ptr->scene->d_func()->focusProxyReverseMap.insert(item, this); + } +} + +/*! \since 4.4 Grabs the mouse input. diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index a307622..5c9297f 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -226,6 +226,9 @@ public: void setFocus(Qt::FocusReason focusReason = Qt::OtherFocusReason); void clearFocus(); + QGraphicsItem *focusProxy() const; + void setFocusProxy(QGraphicsItem *item); + void grabMouse(); void ungrabMouse(); void grabKeyboard(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 4729634..fee7083 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -122,6 +122,7 @@ public: index(-1), siblingIndex(-1), depth(0), + focusProxy(0), acceptedMouseButtons(0x1f), visible(1), explicitlyHidden(0), @@ -409,6 +410,7 @@ public: int index; int siblingIndex; int depth; + QGraphicsItem *focusProxy; // Packed 32 bytes quint32 acceptedMouseButtons : 5; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index b017022..4796436 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -491,6 +491,13 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) item->d_func()->scene = 0; + // Unregister focus proxy. + QMultiHash::iterator it = focusProxyReverseMap.find(item); + while (it != focusProxyReverseMap.end() && it.key() == item) { + it.value()->d_ptr->focusProxy = 0; + it = focusProxyReverseMap.erase(it); + } + // Remove from parent, or unregister from toplevels. if (QGraphicsItem *parentItem = item->parentItem()) { if (parentItem->scene()) { @@ -559,6 +566,58 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) /*! \internal */ +void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item, + Qt::FocusReason focusReason) +{ + Q_Q(QGraphicsScene); + if (item == focusItem) + return; + if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable) + || !item->isVisible() || !item->isEnabled())) { + item = 0; + } + + if (item) { + q->setFocus(focusReason); + if (item == focusItem) + return; + } + + if (focusItem) { + QFocusEvent event(QEvent::FocusOut, focusReason); + lastFocusItem = focusItem; + focusItem = 0; + sendEvent(lastFocusItem, &event); + + if (lastFocusItem + && (lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { + // Reset any visible preedit text + QInputMethodEvent imEvent; + sendEvent(lastFocusItem, &imEvent); + + // Close any external input method panel + for (int i = 0; i < views.size(); ++i) + views.at(i)->inputContext()->reset(); + } + } + + if (item) { + if (item->isWidget()) { + // Update focus child chain. + static_cast(item)->d_func()->setFocusWidget(); + } + + focusItem = item; + QFocusEvent event(QEvent::FocusIn, focusReason); + sendEvent(item, &event); + } + + updateInputMethodSensitivityInViews(); +} + +/*! + \internal +*/ void QGraphicsScenePrivate::addPopup(QGraphicsWidget *widget) { Q_ASSERT(widget); @@ -2597,49 +2656,10 @@ QGraphicsItem *QGraphicsScene::focusItem() const void QGraphicsScene::setFocusItem(QGraphicsItem *item, Qt::FocusReason focusReason) { Q_D(QGraphicsScene); - if (item == d->focusItem) - return; - if (item && (!(item->flags() & QGraphicsItem::ItemIsFocusable) - || !item->isVisible() || !item->isEnabled())) { - item = 0; - } - - if (item) { - setFocus(focusReason); - if (item == d->focusItem) - return; - } - - if (d->focusItem) { - QFocusEvent event(QEvent::FocusOut, focusReason); - d->lastFocusItem = d->focusItem; - d->focusItem = 0; - d->sendEvent(d->lastFocusItem, &event); - - if (d->lastFocusItem - && (d->lastFocusItem->flags() & QGraphicsItem::ItemAcceptsInputMethod)) { - // Reset any visible preedit text - QInputMethodEvent imEvent; - d->sendEvent(d->lastFocusItem, &imEvent); - - // Close any external input method panel - for (int i = 0; i < d->views.size(); ++i) - d->views.at(i)->inputContext()->reset(); - } - } - - if (item) { - if (item->isWidget()) { - // Update focus child chain. - static_cast(item)->d_func()->setFocusWidget(); - } - - d->focusItem = item; - QFocusEvent event(QEvent::FocusIn, focusReason); - d->sendEvent(item, &event); - } - - d->updateInputMethodSensitivityInViews(); + if (item) + item->setFocus(focusReason); + else + d->setFocusItemHelper(item, focusReason); } /*! diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 9a91acc..a4bbdd2 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -130,6 +130,8 @@ public: QGraphicsWidget *tabFocusFirst; QGraphicsWidget *activeWindow; int activationRefCount; + void setFocusItemHelper(QGraphicsItem *item, Qt::FocusReason focusReason); + QMultiHash focusProxyReverseMap; QList popupWidgets; void addPopup(QGraphicsWidget *widget); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index f58cad2..011e480 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -76,6 +76,46 @@ Q_DECLARE_METATYPE(QRectF) #define Q_CHECK_PAINTEVENTS #endif +class EventSpy : public QGraphicsWidget +{ + Q_OBJECT +public: + EventSpy(QObject *watched, QEvent::Type type) + : _count(0), spied(type) + { + watched->installEventFilter(this); + } + + EventSpy(QGraphicsScene *scene, QGraphicsItem *watched, QEvent::Type type) + : _count(0), spied(type) + { + scene->addItem(this); + watched->installSceneEventFilter(this); + } + + int count() const { return _count; } + +protected: + bool eventFilter(QObject *watched, QEvent *event) + { + Q_UNUSED(watched); + if (event->type() == spied) + ++_count; + return false; + } + + bool sceneEventFilter(QGraphicsItem *watched, QEvent *event) + { + Q_UNUSED(watched); + if (event->type() == spied) + ++_count; + return false; + } + + int _count; + QEvent::Type spied; +}; + class EventTester : public QGraphicsItem { public: @@ -234,6 +274,7 @@ private slots: void sorting(); void itemHasNoContents(); void hitTestUntransformableItem(); + void focusProxy(); // task specific tests below me void task141694_textItemEnsureVisible(); @@ -7344,5 +7385,84 @@ void tst_QGraphicsItem::hitTestUntransformableItem() QCOMPARE(items.at(0), static_cast(item3)); } +void tst_QGraphicsItem::focusProxy() +{ + QGraphicsScene scene; + QGraphicsItem *item = scene.addRect(0, 0, 10, 10); + item->setFlag(QGraphicsItem::ItemIsFocusable); + QVERIFY(!item->focusProxy()); + + QGraphicsItem *item2 = scene.addRect(0, 0, 10, 10); + item2->setFlag(QGraphicsItem::ItemIsFocusable); + item->setFocusProxy(item2); + QCOMPARE(item->focusProxy(), item2); + + item->setFocus(); + QVERIFY(item->hasFocus()); + QVERIFY(item2->hasFocus()); + + // Try to make a focus chain loop + QString err; + QTextStream stream(&err); + stream << "QGraphicsItem::setFocusProxy: " + << (void*)item << " is already in the focus proxy chain" << flush; + QTest::ignoreMessage(QtWarningMsg, err.toLatin1().constData()); + item2->setFocusProxy(item); // fails + QCOMPARE(item->focusProxy(), (QGraphicsItem *)item2); + QCOMPARE(item2->focusProxy(), (QGraphicsItem *)0); + + // Try to assign self as focus proxy + QTest::ignoreMessage(QtWarningMsg, "QGraphicsItem::setFocusProxy: cannot assign self as focus proxy"); + item->setFocusProxy(item); // fails + QCOMPARE(item->focusProxy(), (QGraphicsItem *)item2); + QCOMPARE(item2->focusProxy(), (QGraphicsItem *)0); + + // Reset the focus proxy + item->setFocusProxy(0); + QCOMPARE(item->focusProxy(), (QGraphicsItem *)0); + QVERIFY(!item->hasFocus()); + QVERIFY(item2->hasFocus()); + + // Test deletion + item->setFocusProxy(item2); + QCOMPARE(item->focusProxy(), (QGraphicsItem *)item2); + delete item2; + QCOMPARE(item->focusProxy(), (QGraphicsItem *)0); + + // Test event delivery + item2 = scene.addRect(0, 0, 10, 10); + item2->setFlag(QGraphicsItem::ItemIsFocusable); + item->setFocusProxy(item2); + item->clearFocus(); + + EventSpy focusInSpy(&scene, item, QEvent::FocusIn); + EventSpy focusOutSpy(&scene, item, QEvent::FocusOut); + EventSpy focusInSpy2(&scene, item2, QEvent::FocusIn); + EventSpy focusOutSpy2(&scene, item2, QEvent::FocusOut); + QCOMPARE(focusInSpy.count(), 0); + QCOMPARE(focusOutSpy.count(), 0); + QCOMPARE(focusInSpy2.count(), 0); + QCOMPARE(focusOutSpy2.count(), 0); + + item->setFocus(); + QCOMPARE(focusInSpy.count(), 0); + QCOMPARE(focusInSpy2.count(), 1); + item->clearFocus(); + QCOMPARE(focusOutSpy.count(), 0); + QCOMPARE(focusOutSpy2.count(), 1); + + // Test two items proxying one item. + QGraphicsItem *item3 = scene.addRect(0, 0, 10, 10); + item3->setFlag(QGraphicsItem::ItemIsFocusable); + item3->setFocusProxy(item2); // item and item3 use item2 as proxy + + QCOMPARE(item->focusProxy(), item2); + QCOMPARE(item2->focusProxy(), (QGraphicsItem *)0); + QCOMPARE(item3->focusProxy(), item2); + delete item2; + QCOMPARE(item->focusProxy(), (QGraphicsItem *)0); + QCOMPARE(item3->focusProxy(), (QGraphicsItem *)0); +} + QTEST_MAIN(tst_QGraphicsItem) #include "tst_qgraphicsitem.moc" -- cgit v0.12 From 5234d083c9b00ed508dae7cc8c47d21da46325c6 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 23 Jul 2009 07:52:38 +0200 Subject: Fix merge error, restore size of bit field. Change 34fde4a4 removes one bit from the flags bitfield, which was added in change 7bc98d7b. This happened during resolving of a merge conflict and caused some input method related autotests in tst_QGraphicsView to fail. Reviewed-by: mbm --- src/gui/graphicsview/qgraphicsitem_p.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index fee7083..1cf188e 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -440,7 +440,7 @@ public: // New 32 bits quint32 fullUpdatePending : 1; - quint32 flags : 12; + quint32 flags : 13; quint32 dirtyChildrenBoundingRect : 1; quint32 paintedViewBoundingRectsNeedRepaint : 1; quint32 dirtySceneTransform : 1; @@ -453,7 +453,7 @@ public: quint32 acceptedTouchBeginEvent : 1; quint32 filtersDescendantEvents : 1; quint32 sceneTransformTranslateOnly : 1; - quint32 unused : 7; // feel free to use + quint32 unused : 6; // feel free to use // Optional stacking order int globalStackingOrder; -- cgit v0.12 From f9103011abc672059cda53078e84d9e73e687e12 Mon Sep 17 00:00:00 2001 From: Martin Jones Date: Thu, 23 Jul 2009 17:12:55 +1000 Subject: Build with rvct compiler. Reviewed-by: akennedy --- src/xmlpatterns/parser/qmaintainingreader.cpp | 4 ++-- src/xmlpatterns/parser/qmaintainingreader_p.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/xmlpatterns/parser/qmaintainingreader.cpp b/src/xmlpatterns/parser/qmaintainingreader.cpp index 0513555..8569f05 100644 --- a/src/xmlpatterns/parser/qmaintainingreader.cpp +++ b/src/xmlpatterns/parser/qmaintainingreader.cpp @@ -172,7 +172,7 @@ void MaintainingReader::validateElement(const Looku QStringList allowed; for(int i = 0; i < totalCount; ++i) - allowed.append(formatKeyword(toString(all.at(i)))); + allowed.append(QPatternist::formatKeyword(TokenLookupClass::toString(all.at(i)))); /* Note, we can't run toString() on attrName, because we're in this branch, * the token lookup doesn't have the string(!).*/ @@ -229,7 +229,7 @@ void MaintainingReader::validateElement(const Looku if(!requiredButMissing.isEmpty()) { error(QtXmlPatterns::tr("The attribute %1 must appear on element %2.") - .arg(formatKeyword(toString(*requiredButMissing.constBegin())), + .arg(QPatternist::formatKeyword(TokenLookupClass::toString(*requiredButMissing.constBegin())), formatKeyword(name())), ReportContext::XTSE0010); } diff --git a/src/xmlpatterns/parser/qmaintainingreader_p.h b/src/xmlpatterns/parser/qmaintainingreader_p.h index c2c991e..eb20bdb 100644 --- a/src/xmlpatterns/parser/qmaintainingreader_p.h +++ b/src/xmlpatterns/parser/qmaintainingreader_p.h @@ -59,6 +59,7 @@ #include #include "qxpathhelper_p.h" +#include "qxslttokenlookup_p.h" class QUrl; -- cgit v0.12 From bf095defcbc6f025e39aab32f2ab8102639fd0d2 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 23 Jul 2009 09:42:55 +0200 Subject: Remove the close shortcut from the example since QMdiArea provides this Since QMdiArea provides this already via the standard keys, then we don't want to add it ourselves otherwise it triggers an ambigious shortcut on the platforms which already has CTRL+F4. Task-number: 161999 Reviewed-by: Kavindra Palaraja --- examples/mainwindows/mdi/mainwindow.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/mainwindows/mdi/mainwindow.cpp b/examples/mainwindows/mdi/mainwindow.cpp index 3cb54f1..9ef2cae 100644 --- a/examples/mainwindows/mdi/mainwindow.cpp +++ b/examples/mainwindows/mdi/mainwindow.cpp @@ -259,7 +259,6 @@ void MainWindow::createActions() connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); closeAct = new QAction(tr("Cl&ose"), this); - closeAct->setShortcut(tr("Ctrl+F4")); closeAct->setStatusTip(tr("Close the active window")); connect(closeAct, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow())); -- cgit v0.12 From a2d64535d011a47cb2bdf91002f9210cf6b656b1 Mon Sep 17 00:00:00 2001 From: Tom Cooksey Date: Thu, 23 Jul 2009 09:38:51 +0200 Subject: Fix build on Harmattan Reviewed-By: Trustme --- src/opengl/qgl_x11egl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 11131ea..99b026d 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -469,7 +469,7 @@ void QGLWidgetPrivate::recreateEglSurface(bool force) } } -GLuint QGLContextPrivate::bindTextureFromNativePixmap(const QPixmap& pm, const qint64 key, bool canInvert) +QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pm, const qint64 key, bool canInvert) { // TODO return 0; -- cgit v0.12 From 350f857f116a734ea25f91887999eeb17e064350 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Thu, 23 Jul 2009 10:13:37 +0200 Subject: Ensure all the standard shorcuts are used for the Close Action in MDI Since there is more than one standard shorcut for closing a MDI window, then ensure that all of them can be used. Task-number: 161999 Reviewed-by: Simon Hausmann --- src/gui/widgets/qmdisubwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/widgets/qmdisubwindow.cpp b/src/gui/widgets/qmdisubwindow.cpp index 24dea37..e8de957 100644 --- a/src/gui/widgets/qmdisubwindow.cpp +++ b/src/gui/widgets/qmdisubwindow.cpp @@ -1066,7 +1066,7 @@ void QMdiSubWindowPrivate::createSystemMenu() addToSystemMenu(CloseAction, QMdiSubWindow::tr("&Close"), SLOT(close())); actions[CloseAction]->setIcon(style->standardIcon(QStyle::SP_TitleBarCloseButton, 0, q)); #if !defined(QT_NO_SHORTCUT) - actions[CloseAction]->setShortcut(QKeySequence::Close); + actions[CloseAction]->setShortcuts(QKeySequence::Close); #endif updateActions(); } -- cgit v0.12 From 9377881d6d6f5c07aa134c8f1708d0afd0d06e86 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Wed, 22 Jul 2009 16:53:49 +0200 Subject: "Emacs" style keyboard shortcuts don't work on Cocoa. Mac supports only single key shortcuts as key equivalent for menu items. So if a multiple key QKeySequence is set, use Qt's shortcut mechanism instead of the native menu shortcut mechanism. Task-number: 258438 Reviewed-by: Norwegian Rock Cat --- src/gui/kernel/qcocoaview_mac.mm | 9 ++++++++- src/gui/widgets/qmenu_mac.mm | 6 ++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 3e5bfb6..3bc348c 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -1039,7 +1039,7 @@ extern "C" { - (void) insertText:(id)aString { - if ([aString length]) { + if ([aString length] && composing) { // Send the commit string to the widget. QString commitText; if ([aString isKindOfClass:[NSAttributedString class]]) { @@ -1052,7 +1052,14 @@ extern "C" { QInputMethodEvent e; e.setCommitString(commitText); qt_sendSpontaneousEvent(qwidget, &e); + } else { + // The key sequence "`q" on a French Keyboard will generate two calls to insertText before + // it returns from interpretKeyEvents. The first call will turn off 'composing' and accept + // the "`" key. The last keyDown event needs to be processed by the widget to get the + // character "q". The string parameter is ignored for the second call. + sendKeyEvents = true; } + composingText->clear(); } diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index 77e98c4..a562076 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1376,8 +1376,9 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) accel = qt_mac_menu_merge_accel(action); } } + // Show multiple key sequences as part of the menu text. if (accel.count() > 1) - text += QLatin1String(" (****)"); //just to denote a multi stroke shortcut + text += QLatin1String(" (") + accel.toString(QKeySequence::NativeText) + QLatin1String(")"); QString finalString = qt_mac_removeMnemonics(text); @@ -1466,7 +1467,8 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) } #else [item setSubmenu:0]; - if (!accel.isEmpty()) { + // No key equivalent set for multiple key QKeySequence. + if (!accel.isEmpty() && accel.count() == 1) { [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)]; [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)]; } else { -- cgit v0.12 From d6a01d0f948361ac5cacab0bf9f8585041485259 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 22 Jul 2009 09:59:54 +0200 Subject: Sockets: Added support for SO_KEEPALIVE and TCP_NODELAY Introduce QAbstractSocket::setSocketOption that allows to set the socket options for TCP Keep Alive and TCP_NODELAY (disabling Nagle's Algorithm). Reviewed-by: Thiago --- src/network/socket/qabstractsocket.cpp | 64 +++++++++++++++++++++++++ src/network/socket/qabstractsocket.h | 8 ++++ src/network/socket/qabstractsocketengine_p.h | 4 +- src/network/socket/qhttpsocketengine.cpp | 21 +++++++- src/network/socket/qnativesocketengine_unix.cpp | 24 +++++++++- src/network/socket/qnativesocketengine_win.cpp | 22 ++++++++- src/network/socket/qsocks5socketengine.cpp | 20 ++++++-- src/network/socket/qtcpsocket.h | 1 + 8 files changed, 154 insertions(+), 10 deletions(-) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index d099382..be90b96 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -332,6 +332,22 @@ \sa QAbstractSocket::state() */ +/*! + \enum QAbstractSocket::SocketOption + \since 4.6 + + This enum represents the options that can be set on a socket. + If desired, they can be set after having received the connected() signal from + the socket or after having received a new socket from a QTcpServer. + + \value LowDelayOption Try to optimize the socket for low latency. For a QTcpSocket + this would set the TCP_NODELAY option and disable Nagle's algorithm. Set this to 1 + to enable. + \value KeepAliveOption Set this to 1 to enable the SO_KEEPALIVE socket option + + \sa QAbstractSocket::setSocketOption(), QAbstractSocket::socketOption() +*/ + #include "qabstractsocket.h" #include "qabstractsocket_p.h" @@ -1548,6 +1564,54 @@ bool QAbstractSocket::setSocketDescriptor(int socketDescriptor, SocketState sock return true; } +/*! + Sets the option \a option to the value described by \a value. + + \sa socketOption() +*/ +void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, QVariant value) +{ + if (!d_func()->socketEngine) + return; + + switch (option) { + case LowDelayOption: + d_func()->socketEngine->setOption(QAbstractSocketEngine::LowDelayOption, value.toInt()); + break; + + case KeepAliveOption: + d_func()->socketEngine->setOption(QAbstractSocketEngine::KeepAliveOption, value.toInt()); + break; + } +} + +/*! + Returns the value of the \a option option. + + \sa setSocketOption() +*/ +QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option) +{ + if (!d_func()->socketEngine) + return QVariant(); + + int ret = -1; + switch (option) { + case LowDelayOption: + ret = d_func()->socketEngine->option(QAbstractSocketEngine::LowDelayOption); + break; + + case KeepAliveOption: + ret = d_func()->socketEngine->option(QAbstractSocketEngine::KeepAliveOption); + break; + } + if (ret == -1) + return QVariant(); + else + return QVariant(ret); +} + + /* Returns the difference between msecs and elapsed. If msecs is -1, however, -1 is returned. diff --git a/src/network/socket/qabstractsocket.h b/src/network/socket/qabstractsocket.h index ed187e5..50a38bb 100644 --- a/src/network/socket/qabstractsocket.h +++ b/src/network/socket/qabstractsocket.h @@ -116,6 +116,10 @@ public: Connection = ConnectedState #endif }; + enum SocketOption { + LowDelayOption, // TCP_NODELAY + KeepAliveOption // SO_KEEPALIVE + }; QAbstractSocket(SocketType socketType, QObject *parent); virtual ~QAbstractSocket(); @@ -149,6 +153,10 @@ public: bool setSocketDescriptor(int socketDescriptor, SocketState state = ConnectedState, OpenMode openMode = ReadWrite); + // ### Qt 5: Make virtual? + void setSocketOption(QAbstractSocket::SocketOption o, QVariant v); + QVariant socketOption(QAbstractSocket::SocketOption o); + SocketType socketType() const; SocketState state() const; SocketError error() const; diff --git a/src/network/socket/qabstractsocketengine_p.h b/src/network/socket/qabstractsocketengine_p.h index b784f65..39c00cc 100644 --- a/src/network/socket/qabstractsocketengine_p.h +++ b/src/network/socket/qabstractsocketengine_p.h @@ -92,7 +92,9 @@ public: SendBufferSocketOption, AddressReusable, BindExclusively, - ReceiveOutOfBandData + ReceiveOutOfBandData, + LowDelayOption, + KeepAliveOption }; virtual bool initialize(QAbstractSocket::SocketType type, QAbstractSocket::NetworkLayerProtocol protocol = QAbstractSocket::IPv4Protocol) = 0; diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 156a9f4..84b7c14 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -276,13 +276,30 @@ qint64 QHttpSocketEngine::pendingDatagramSize() const } #endif // QT_NO_UDPSOCKET -int QHttpSocketEngine::option(SocketOption) const +int QHttpSocketEngine::option(SocketOption option) const { + Q_D(const QHttpSocketEngine); + if (d->socket) { + // convert the enum and call the real socket + if (option == QAbstractSocketEngine::LowDelayOption) + return d->socket->socketOption(QAbstractSocket::LowDelayOption).toInt(); + if (option == QAbstractSocketEngine::KeepAliveOption) + return d->socket->socketOption(QAbstractSocket::KeepAliveOption).toInt(); + } return -1; } -bool QHttpSocketEngine::setOption(SocketOption, int) +bool QHttpSocketEngine::setOption(SocketOption option, int value) { + Q_D(QHttpSocketEngine); + if (d->socket) { + // convert the enum and call the real socket + if (option == QAbstractSocketEngine::LowDelayOption) + d->socket->setSocketOption(QAbstractSocket::LowDelayOption, value); + if (option == QAbstractSocketEngine::KeepAliveOption) + d->socket->setSocketOption(QAbstractSocket::KeepAliveOption, value); + return true; + } return false; } diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 3991ae6..b4b673a 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -65,6 +65,8 @@ #include #endif +#include + QT_BEGIN_NAMESPACE #if defined QNATIVESOCKETENGINE_DEBUG @@ -203,6 +205,8 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co return -1; int n = -1; + int level = SOL_SOCKET; // default + switch (opt) { case QNativeSocketEngine::ReceiveBufferSocketOption: n = SO_RCVBUF; @@ -222,11 +226,18 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co case QNativeSocketEngine::ReceiveOutOfBandData: n = SO_OOBINLINE; break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; } int v = -1; QT_SOCKOPTLEN_T len = sizeof(v); - if (getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1) + if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) return v; return -1; } @@ -242,6 +253,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt return false; int n = 0; + int level = SOL_SOCKET; // default + switch (opt) { case QNativeSocketEngine::ReceiveBufferSocketOption: n = SO_RCVBUF; @@ -282,9 +295,16 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt case QNativeSocketEngine::ReceiveOutOfBandData: n = SO_OOBINLINE; break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; } - return ::setsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, sizeof(v)) == 0; + return ::setsockopt(socketDescriptor, level, n, (char *) &v, sizeof(v)) == 0; } bool QNativeSocketEnginePrivate::nativeConnect(const QHostAddress &addr, quint16 port) diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 6bc23ce..f0b9f0b 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -362,6 +362,8 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co return -1; int n = -1; + int level = SOL_SOCKET; // default + switch (opt) { case QNativeSocketEngine::ReceiveBufferSocketOption: n = SO_RCVBUF; @@ -389,11 +391,18 @@ int QNativeSocketEnginePrivate::option(QNativeSocketEngine::SocketOption opt) co case QNativeSocketEngine::ReceiveOutOfBandData: n = SO_OOBINLINE; break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; } int v = -1; QT_SOCKOPTLEN_T len = sizeof(v); - if (getsockopt(socketDescriptor, SOL_SOCKET, n, (char *) &v, &len) != -1) + if (getsockopt(socketDescriptor, level, n, (char *) &v, &len) != -1) return v; return -1; } @@ -409,6 +418,8 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt return false; int n = 0; + int level = SOL_SOCKET; // default + switch (opt) { case QNativeSocketEngine::ReceiveBufferSocketOption: n = SO_RCVBUF; @@ -440,9 +451,16 @@ bool QNativeSocketEnginePrivate::setOption(QNativeSocketEngine::SocketOption opt case QNativeSocketEngine::ReceiveOutOfBandData: n = SO_OOBINLINE; break; + case QNativeSocketEngine::LowDelayOption: + level = IPPROTO_TCP; + n = TCP_NODELAY; + break; + case QNativeSocketEngine::KeepAliveOption: + n = SO_KEEPALIVE; + break; } - if (::setsockopt(socketDescriptor, SOL_SOCKET, n, (char*)&v, sizeof(v)) != 0) { + if (::setsockopt(socketDescriptor, level, n, (char*)&v, sizeof(v)) != 0) { WS_ERROR_DEBUG(WSAGetLastError()); return false; } diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index c9e5150..d226f21 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1621,14 +1621,28 @@ qint64 QSocks5SocketEngine::pendingDatagramSize() const int QSocks5SocketEngine::option(SocketOption option) const { - Q_UNUSED(option); + Q_D(const QSocks5SocketEngine); + if (d->data && d->data->controlSocket) { + // convert the enum and call the real socket + if (option == QAbstractSocketEngine::LowDelayOption) + return d->data->controlSocket->socketOption(QAbstractSocket::LowDelayOption).toInt(); + if (option == QAbstractSocketEngine::KeepAliveOption) + return d->data->controlSocket->socketOption(QAbstractSocket::KeepAliveOption).toInt(); + } return -1; } bool QSocks5SocketEngine::setOption(SocketOption option, int value) { - Q_UNUSED(option); - Q_UNUSED(value); + Q_D(QSocks5SocketEngine); + if (d->data && d->data->controlSocket) { + // convert the enum and call the real socket + if (option == QAbstractSocketEngine::LowDelayOption) + d->data->controlSocket->setSocketOption(QAbstractSocket::LowDelayOption, value); + if (option == QAbstractSocketEngine::KeepAliveOption) + d->data->controlSocket->setSocketOption(QAbstractSocket::KeepAliveOption, value); + return true; + } return false; } diff --git a/src/network/socket/qtcpsocket.h b/src/network/socket/qtcpsocket.h index 81f81de..4e1003a 100644 --- a/src/network/socket/qtcpsocket.h +++ b/src/network/socket/qtcpsocket.h @@ -43,6 +43,7 @@ #define QTCPSOCKET_H #include +#include QT_BEGIN_HEADER -- cgit v0.12 From 23fcdf1a78d981a6d986a907450b71a82bed5efa Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 22 Jul 2009 10:40:42 +0200 Subject: QFtp: Also set LowDelay option on the control socket Reviewed-by: Thiago --- src/network/access/qftp.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index 35e0a18..421e671 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -869,6 +869,9 @@ void QFtpPI::connected() #if defined(QFTPPI_DEBUG) // qDebug("QFtpPI state: %d [connected()]", state); #endif + // try to improve performance by setting TCP_NODELAY + commandSocket.setSocketOption(QAbstractSocket::LowDelayOption, 1); + emit connectState(QFtp::Connected); } -- cgit v0.12 From 6844c1b37514a7ceed2378049f8bad887f58d4bf Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 22 Jul 2009 10:59:37 +0200 Subject: tst_qnetworkreply: Small and simple latency testing Reviewed-by: Thiago --- tests/benchmarks/benchmarks.pro | 1 + tests/benchmarks/qnetworkreply/main.cpp | 74 ++++++++++++++++++++++++ tests/benchmarks/qnetworkreply/qnetworkreply.pro | 13 +++++ 3 files changed, 88 insertions(+) create mode 100644 tests/benchmarks/qnetworkreply/main.cpp create mode 100644 tests/benchmarks/qnetworkreply/qnetworkreply.pro diff --git a/tests/benchmarks/benchmarks.pro b/tests/benchmarks/benchmarks.pro index 1ee0c41..bf02731 100644 --- a/tests/benchmarks/benchmarks.pro +++ b/tests/benchmarks/benchmarks.pro @@ -11,6 +11,7 @@ SUBDIRS = containers-associative \ qstring \ qstringlist \ qmatrix4x4 \ + qnetworkreply \ qobject \ qrect \ qregexp \ diff --git a/tests/benchmarks/qnetworkreply/main.cpp b/tests/benchmarks/qnetworkreply/main.cpp new file mode 100644 index 0000000..3f1e9f7 --- /dev/null +++ b/tests/benchmarks/qnetworkreply/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ +// This file contains benchmarks for QNetworkReply functions. + +#include +#include +#include +#include +#include +#include +#include "../../auto/network-settings.h" + +class tst_qnetworkreply : public QObject +{ + Q_OBJECT +private slots: + void httpLatency(); + +}; + +void tst_qnetworkreply::httpLatency() +{ + QNetworkAccessManager manager; + QBENCHMARK{ + QNetworkRequest request(QUrl("http://" + QtNetworkSettings::serverName() + "/qtest/")); + QNetworkReply* reply = manager.get(request); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()), Qt::QueuedConnection); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(!QTestEventLoop::instance().timeout()); + delete reply; + } +} + +QTEST_MAIN(tst_qnetworkreply) + +#include "main.moc" diff --git a/tests/benchmarks/qnetworkreply/qnetworkreply.pro b/tests/benchmarks/qnetworkreply/qnetworkreply.pro new file mode 100644 index 0000000..060acf5 --- /dev/null +++ b/tests/benchmarks/qnetworkreply/qnetworkreply.pro @@ -0,0 +1,13 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_qnetworkreply +DEPENDPATH += . +INCLUDEPATH += . + +QT -= gui +QT += network + +CONFIG += release + +# Input +SOURCES += main.cpp -- cgit v0.12 From e5207123dff4eb6b6eaea244d697ec14c08a502e Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Wed, 22 Jul 2009 10:28:13 +0200 Subject: QNAM HTTP Code: Use new LowDelay socket option Reviewed-by: Thiago --- src/network/access/qhttpnetworkconnection.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index c824fac..3f0b244 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -409,6 +409,7 @@ bool QHttpNetworkConnectionPrivate::sendRequest(QAbstractSocket *socket) channels[i].bytesTotal = channels[i].request.contentLength(); } else { + socket->flush(); // ### Remove this when pipelining is implemented. We want less TCP packets! channels[i].state = WaitingState; break; } @@ -1198,6 +1199,10 @@ void QHttpNetworkConnectionPrivate::_q_connected() QAbstractSocket *socket = qobject_cast(q->sender()); if (!socket) return; // ### error + + // improve performance since we get the request sent by the kernel ASAP + socket->setSocketOption(QAbstractSocket::LowDelayOption, 1); + int i = indexOf(socket); // ### FIXME: if the server closes the connection unexpectedly, we shouldn't send the same broken request again! //channels[i].reconnectAttempts = 2; -- cgit v0.12 From 30f6a1d06723aac5168dcef32cba10cd99b85242 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 23 Jul 2009 12:10:46 +0200 Subject: linker fix for WinCE - link against correct library - theoretically it should be ok to use QHostInfo::localHostName(), but for this test it is fine Reviewed-by: Thomas Hartmann --- tests/auto/qsqldatabase/qsqldatabase.pro | 5 ++++- tests/auto/qsqldriver/qsqldriver.pro | 3 ++- tests/auto/qsqlquery/qsqlquery.pro | 3 ++- tests/auto/qsqlquerymodel/qsqlquerymodel.pro | 1 + tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro | 1 + tests/auto/qsqltablemodel/qsqltablemodel.pro | 3 ++- tests/auto/qsqlthread/qsqlthread.pro | 3 ++- 7 files changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/auto/qsqldatabase/qsqldatabase.pro b/tests/auto/qsqldatabase/qsqldatabase.pro index 534a2d3..3bca79a 100644 --- a/tests/auto/qsqldatabase/qsqldatabase.pro +++ b/tests/auto/qsqldatabase/qsqldatabase.pro @@ -5,7 +5,10 @@ QT += sql contains(QT_CONFIG, qt3support): QT += qt3support -win32:!wince*: LIBS += -lws2_32 +win32: { + !wince*: LIBS += -lws2_32 + else: LIBS += -lws2 +} wince*: { DEPLOYMENT_PLUGIN += qsqlite diff --git a/tests/auto/qsqldriver/qsqldriver.pro b/tests/auto/qsqldriver/qsqldriver.pro index 0024841..84f1cb2 100644 --- a/tests/auto/qsqldriver/qsqldriver.pro +++ b/tests/auto/qsqldriver/qsqldriver.pro @@ -6,7 +6,8 @@ QT += sql wince*: { plugFiles.sources = ../../../plugins/sqldrivers plugFiles.path = . - DEPLOYMENT += plugFiles + DEPLOYMENT += plugFiles + LIBS += -lws2 } else { win32-g++ { LIBS += -lws2_32 diff --git a/tests/auto/qsqlquery/qsqlquery.pro b/tests/auto/qsqlquery/qsqlquery.pro index d70ede3..7996637 100644 --- a/tests/auto/qsqlquery/qsqlquery.pro +++ b/tests/auto/qsqlquery/qsqlquery.pro @@ -10,5 +10,6 @@ QT = core sql wince*: { plugFiles.sources = ../../../plugins/sqldrivers plugFiles.path = . - DEPLOYMENT += plugFiles + DEPLOYMENT += plugFiles + LIBS += -lws2 } diff --git a/tests/auto/qsqlquerymodel/qsqlquerymodel.pro b/tests/auto/qsqlquerymodel/qsqlquerymodel.pro index 669db6e..6004ab0 100644 --- a/tests/auto/qsqlquerymodel/qsqlquerymodel.pro +++ b/tests/auto/qsqlquerymodel/qsqlquerymodel.pro @@ -5,6 +5,7 @@ QT += sql wince*: { DEPLOYMENT_PLUGIN += qsqlite + LIBS += -lws2 } else { win32:LIBS += -lws2_32 } diff --git a/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro b/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro index a35a56c..a25cb93 100644 --- a/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro +++ b/tests/auto/qsqlrelationaltablemodel/qsqlrelationaltablemodel.pro @@ -7,6 +7,7 @@ wince*: { plugFiles.sources = ../../../plugins/sqldrivers plugFiles.path = . DEPLOYMENT += plugFiles + LIBS += -lws2 } else { win32-g++ { LIBS += -lws2_32 diff --git a/tests/auto/qsqltablemodel/qsqltablemodel.pro b/tests/auto/qsqltablemodel/qsqltablemodel.pro index cf5fbea..170862e 100644 --- a/tests/auto/qsqltablemodel/qsqltablemodel.pro +++ b/tests/auto/qsqltablemodel/qsqltablemodel.pro @@ -6,7 +6,8 @@ QT += sql wince*: { plugFiles.sources = ../../../plugins/sqldrivers plugFiles.path = . - DEPLOYMENT += plugFiles + DEPLOYMENT += plugFiles + LIBS += -lws2 } else { win32:LIBS += -lws2_32 } diff --git a/tests/auto/qsqlthread/qsqlthread.pro b/tests/auto/qsqlthread/qsqlthread.pro index 23aa598..9049f4c 100644 --- a/tests/auto/qsqlthread/qsqlthread.pro +++ b/tests/auto/qsqlthread/qsqlthread.pro @@ -7,7 +7,8 @@ QT = core sql wince*: { plugFiles.sources = ../../../plugins/sqldrivers plugFiles.path = . - DEPLOYMENT += plugFiles + DEPLOYMENT += plugFiles + LIBS += -lws2 } else { win32:LIBS += -lws2_32 } -- cgit v0.12 From 588f8daeb52cfea461cbcb8c128de5997ab5a6cf Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 23 Jul 2009 12:41:52 +0200 Subject: make statemachine compile with QT_NO_PROPERTIES --- src/corelib/statemachine/qstate.cpp | 4 ++++ src/corelib/statemachine/qstate.h | 2 ++ src/corelib/statemachine/qstatemachine.cpp | 14 ++++++++++++++ src/corelib/statemachine/qstatemachine_p.h | 2 ++ 4 files changed, 22 insertions(+) diff --git a/src/corelib/statemachine/qstate.cpp b/src/corelib/statemachine/qstate.cpp index f74edc3..2042288 100644 --- a/src/corelib/statemachine/qstate.cpp +++ b/src/corelib/statemachine/qstate.cpp @@ -215,6 +215,8 @@ QList QStatePrivate::transitions() const return result; } +#ifndef QT_NO_PROPERTIES + /*! Instructs this state to set the property with the given \a name of the given \a object to the given \a value when the state is entered. @@ -239,6 +241,8 @@ void QState::assignProperty(QObject *object, const char *name, d->propertyAssignments.append(QPropertyAssignment(object, name, value)); } +#endif // QT_NO_PROPERTIES + /*! Returns this state's error state. diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h index 41d32be..ce88b25 100644 --- a/src/corelib/statemachine/qstate.h +++ b/src/corelib/statemachine/qstate.h @@ -87,8 +87,10 @@ public: ChildMode childMode() const; void setChildMode(ChildMode mode); +#ifndef QT_NO_PROPERTIES void assignProperty(QObject *object, const char *name, const QVariant &value); +#endif Q_SIGNALS: void finished(); diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 5402b04..a02480b 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -395,7 +395,9 @@ void QStateMachinePrivate::microstep(QEvent *event, const QList enteredStates = enterStates(event, enabledTransitions); +#ifndef QT_NO_PROPERTIES applyProperties(enabledTransitions, exitedStates, enteredStates); +#endif #ifdef QSTATEMACHINE_DEBUG qDebug() << q_func() << ": configuration after entering states:" << configuration; qDebug() << q_func() << ": end microstep"; @@ -666,6 +668,8 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, } } +#ifndef QT_NO_PROPERTIES + void QStateMachinePrivate::applyProperties(const QList &transitionList, const QList &exitedStates, const QList &enteredStates) @@ -853,6 +857,8 @@ void QStateMachinePrivate::applyProperties(const QList &tr } } +#endif // QT_NO_PROPERTIES + bool QStateMachinePrivate::isFinal(const QAbstractState *s) { return qobject_cast(s) != 0; @@ -932,6 +938,8 @@ bool QStateMachinePrivate::isInFinalState(QAbstractState* s) const return false; } +#ifndef QT_NO_PROPERTIES + void QStateMachinePrivate::registerRestorable(QObject *object, const QByteArray &propertyName) { RestorableId id(object, propertyName); @@ -976,6 +984,8 @@ void QStateMachinePrivate::unregisterRestorable(QObject *object, const QByteArra registeredRestorables.remove(id); } +#endif // QT_NO_PROPERTIES + QAbstractState *QStateMachinePrivate::findErrorState(QAbstractState *context) { // Find error state recursively in parent hierarchy if not set explicitly for context state @@ -1088,12 +1098,14 @@ void QStateMachinePrivate::_q_animationFinished() resetAnimationEndValues.remove(anim); } +#ifndef QT_NO_PROPERTIES // Set the final property value. QPropertyAssignment assn = propertyForAnimation.take(anim); Q_ASSERT(assn.object != 0); assn.object->setProperty(assn.propertyName, assn.value); if (!assn.explicitlySet) unregisterRestorable(assn.object, assn.propertyName); +#endif QAbstractState *state = stateForAnimation.take(anim); Q_ASSERT(state != 0); @@ -1161,8 +1173,10 @@ void QStateMachinePrivate::_q_start() QEvent nullEvent(QEvent::None); executeTransitionContent(&nullEvent, transitions); QList enteredStates = enterStates(&nullEvent, transitions); +#ifndef QT_NO_PROPERTIES applyProperties(transitions, QList() << start, enteredStates); +#endif delete start; #ifdef QSTATEMACHINE_DEBUG diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 21e405d..cae21aa 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -151,6 +151,7 @@ public: void **args); void scheduleProcess(); +#ifndef QT_NO_PROPERTIES typedef QPair RestorableId; QHash registeredRestorables; void registerRestorable(QObject *object, const QByteArray &propertyName); @@ -158,6 +159,7 @@ public: bool hasRestorable(QObject *object, const QByteArray &propertyName) const; QVariant restorableValue(QObject *object, const QByteArray &propertyName) const; QList restorablesToPropertyList(const QHash &restorables) const; +#endif State state; bool processing; -- cgit v0.12 From 7ade13540e6caa6449c02a8832e670a499e97189 Mon Sep 17 00:00:00 2001 From: Prasanth Ullattil Date: Thu, 23 Jul 2009 11:59:30 +0200 Subject: "Emacs" style keyboard shortcuts don't work on Carbon. Set the native key equivalent for menu items only for single key shortcuts. Qt's shortcut mechanism will take care of sending the multiple key shortcut events. Task-number: 258438 Reviewed-by: Norwegian Rock Cat --- src/gui/widgets/qmenu_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index a562076..87f6f82 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -1460,7 +1460,7 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) data.whichData |= kMenuItemDataCmdKey; data.whichData |= kMenuItemDataCmdKeyModifiers; data.whichData |= kMenuItemDataCmdKeyGlyph; - if (!accel.isEmpty()) { + if (accel.count() == 1) { qt_mac_get_accel(accel[0], (quint32*)&data.cmdKeyModifiers, (quint32*)&data.cmdKeyGlyph); if (data.cmdKeyGlyph == 0) data.cmdKey = (UniChar)accel[0]; @@ -1468,7 +1468,7 @@ QMenuPrivate::QMacMenuPrivate::syncAction(QMacMenuAction *action) #else [item setSubmenu:0]; // No key equivalent set for multiple key QKeySequence. - if (!accel.isEmpty() && accel.count() == 1) { + if (accel.count() == 1) { [item setKeyEquivalent:keySequenceToKeyEqivalent(accel)]; [item setKeyEquivalentModifierMask:keySequenceModifierMask(accel)]; } else { -- cgit v0.12 From c2fe149aa4bc5ca212fcee3d149abb96098f31b5 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 23 Jul 2009 13:14:35 +0200 Subject: Omit monotonic timer detection/conditional code on Mac OS X Now that we have a monotonic time source on the Mac, we don't need to compile in the code to detect wall-time changes and do timer adjustments. Reviewed-by: nrc --- src/corelib/kernel/qeventdispatcher_unix.cpp | 30 ++++++++++++---------------- src/corelib/kernel/qeventdispatcher_unix_p.h | 2 +- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index 9deb78f..fac8a28 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -291,9 +291,6 @@ QTimerInfoList::QTimerInfoList() msPerTick = 0; } #else -# if defined(Q_OS_MAC) - useMonotonicTimers = true; -# endif // using monotonic timers unconditionally getTime(currentTime); #endif @@ -307,7 +304,7 @@ timeval QTimerInfoList::updateCurrentTime() return currentTime; } -#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) +#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED) /* Returns true if the real time clock has changed by more than 10% @@ -342,19 +339,7 @@ bool QTimerInfoList::timeChanged(timeval *delta) void QTimerInfoList::getTime(timeval &t) { -#if defined(Q_OS_MAC) - { - static mach_timebase_info_data_t info = {0,0}; - if (info.denom == 0) - mach_timebase_info(&info); - - uint64_t cpu_time = mach_absolute_time(); - uint64_t nsecs = cpu_time * (info.numer / info.denom); - t.tv_sec = nsecs * 1e-9; - t.tv_usec = nsecs * 1e-3 - (t.tv_sec * 1e6); - return; - } -#elif !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) +#if !defined(QT_NO_CLOCK_MONOTONIC) && !defined(QT_BOOTSTRAPPED) if (useMonotonicTimers) { timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); @@ -394,10 +379,21 @@ void QTimerInfoList::repairTimersIfNeeded() void QTimerInfoList::getTime(timeval &t) { +#if defined(Q_OS_MAC) + static mach_timebase_info_data_t info = {0,0}; + if (info.denom == 0) + mach_timebase_info(&info); + + uint64_t cpu_time = mach_absolute_time(); + uint64_t nsecs = cpu_time * (info.numer / info.denom); + t.tv_sec = nsecs * 1e-9; + t.tv_usec = nsecs * 1e-3 - (t.tv_sec * 1e6); +#else timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); t.tv_sec = ts.tv_sec; t.tv_usec = ts.tv_nsec / 1000; +#endif } void QTimerInfoList::repairTimersIfNeeded() diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index d1f7431..ebba21b 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -116,7 +116,7 @@ struct QTimerInfo { class QTimerInfoList : public QList { -#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) || defined(QT_BOOTSTRAPPED) +#if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED) bool useMonotonicTimers; timeval previousTime; -- cgit v0.12 From 86422951df8073babe8d9dcfbd63fe216aa4662e Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 23 Jul 2009 13:35:39 +0200 Subject: doc: Removed a few links to obsolete functions (not controversial). --- src/gui/graphicsview/qgraphicsitem.cpp | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 4e3677a..0ff3685 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -307,8 +307,6 @@ QStyleOptionGraphicsItem::exposedRect or QStyleOptionGraphicsItem::matrix. By default, the exposedRect is initialized to the item's boundingRect and the matrix is untransformed. Enable this flag for more fine-grained values. - Note that QStyleOptionGraphicsItem::levelOfDetail is unaffected by this flag - and is always initialized to 1. Use QStyleOptionGraphicsItem::levelOfDetailFromTransform for a more fine-grained value. @@ -1237,7 +1235,7 @@ void QGraphicsItem::setGroup(QGraphicsItemGroup *group) Returns a pointer to this item's parent item. If this item does not have a parent, 0 is returned. - \sa setParentItem(), children() + \sa setParentItem(), childItems() */ QGraphicsItem *QGraphicsItem::parentItem() const { @@ -1353,7 +1351,7 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const the parent. You should not \l{QGraphicsScene::addItem()}{add} the item to the scene yourself. - \sa parentItem(), children() + \sa parentItem(), childItems() */ void QGraphicsItem::setParentItem(QGraphicsItem *parent) { @@ -2298,10 +2296,10 @@ bool QGraphicsItem::acceptsHoverEvents() const stays "hovered" until the cursor leaves its area, including its children's areas. - If a parent item handles child events (setHandlesChildEvents()), it will - receive hover move, drag move, and drop events as the cursor passes - through its children, but it does not receive hover enter and hover leave, - nor drag enter and drag leave events on behalf of its children. + If a parent item handles child events, it will receive hover move, + drag move, and drop events as the cursor passes through its + children, but it does not receive hover enter and hover leave, nor + drag enter and drag leave events on behalf of its children. A QGraphicsWidget with window decorations will accept hover events regardless of the value of acceptHoverEvents(). @@ -2715,7 +2713,7 @@ void QGraphicsItem::ungrabKeyboard() For convenience, you can also call scenePos() to determine the item's position in scene coordinates, regardless of its parent. - \sa x(), y(), setPos(), matrix(), {The Graphics View Coordinate System} + \sa x(), y(), setPos(), transform(), {The Graphics View Coordinate System} */ QPointF QGraphicsItem::pos() const { @@ -9706,13 +9704,10 @@ QVariant QGraphicsSimpleTextItem::extension(const QVariant &variant) const setParentItem(). The boundingRect() function of QGraphicsItemGroup returns the - bounding rectangle of all items in the item group. In addition, - item groups have handlesChildEvents() enabled by default, so all - events sent to a member of the group go to the item group (i.e., - selecting one item in a group will select them all). - QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on its - children (i.e., with respect to the geometry of the group item, the - children are treated as if they were transformable). + bounding rectangle of all items in the item group. + QGraphicsItemGroup ignores the ItemIgnoresTransformations flag on + its children (i.e., with respect to the geometry of the group + item, the children are treated as if they were transformable). There are two ways to construct an item group. The easiest and most common approach is to pass a list of items (e.g., all -- cgit v0.12 From 9081c1b97532f76b350a712c8e8e6d0bd4cadfdc Mon Sep 17 00:00:00 2001 From: Benjamin Poulain Date: Thu, 23 Jul 2009 14:04:19 +0200 Subject: Fix two errors of QDirIteratorPrivate::matchesFilters() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The filter for includeSystem was exectuted twice. The second time was not correct according to d9a620633d0a5fa5e69ab06ec9a706118f3df2a6 (QFileInfo::exists() can return false for system file). For skipDirs, a parenthesis was missing in the test of includeHidden and includeSystem. This was introduced in the refactoring of 44766d265c16551043d2739171069fe042c40091 Reviewed-by: João Abecasis --- src/corelib/io/qdiriterator.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qdiriterator.cpp b/src/corelib/io/qdiriterator.cpp index 3bfea65..30d2558 100644 --- a/src/corelib/io/qdiriterator.cpp +++ b/src/corelib/io/qdiriterator.cpp @@ -309,17 +309,11 @@ bool QDirIteratorPrivate::matchesFilters(const QString &fileName, const QFileInf || (!fi.exists() && fi.isSymLink()))) return false; - - if (!includeSystem && !dotOrDotDot && ((fi.exists() && !fi.isFile() && !fi.isDir() && !fi.isSymLink()) - || (!fi.exists() && fi.isSymLink()))) { - return false; - } - // skip directories const bool skipDirs = !(filters & (QDir::Dirs | QDir::AllDirs)); if (skipDirs && fi.isDir()) { - if (!(includeHidden && !dotOrDotDot && fi.isHidden()) - || (includeSystem && !fi.exists() && fi.isSymLink())) + if (!((includeHidden && !dotOrDotDot && fi.isHidden()) + || (includeSystem && !fi.exists() && fi.isSymLink()))) return false; } -- cgit v0.12 From 1e25ea7f04a44c84562216e5d305eddd12e9b4d7 Mon Sep 17 00:00:00 2001 From: Markus Goetz Date: Thu, 23 Jul 2009 14:19:18 +0200 Subject: Socket code: Forgot since 4.6 doc tag Reviewed-by: TrustMe --- src/network/socket/qabstractsocket.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index be90b96..290522c 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1568,6 +1568,7 @@ bool QAbstractSocket::setSocketDescriptor(int socketDescriptor, SocketState sock Sets the option \a option to the value described by \a value. \sa socketOption() + \since 4.6 */ void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, QVariant value) { @@ -1589,6 +1590,7 @@ void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, QVar Returns the value of the \a option option. \sa setSocketOption() + \since 4.6 */ QVariant QAbstractSocket::socketOption(QAbstractSocket::SocketOption option) { -- cgit v0.12 From df4fe401f98e53c9d93b9a4cb683f23f45043d2b Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 23 Jul 2009 14:50:23 +0200 Subject: Doc: Removed invalid statements about item views and QTextDocument. Task-number: 257669 Reviewed-by: Trust Me Bikeshed-value-for-reviewed-by-field: 11 --- doc/src/richtext.qdoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/richtext.qdoc b/doc/src/richtext.qdoc index 1c76268..c43db0c 100644 --- a/doc/src/richtext.qdoc +++ b/doc/src/richtext.qdoc @@ -714,8 +714,8 @@ Ideas for other sections: \previouspage Common Rich Text Editing Tasks Qt's text widgets are able to display rich text, specified using a subset of \l{HTML 4} - markup. Widgets that use QTextDocument, such as QLabel, QTextEdit, QTreeWidgetItem and - the other item widgets, are able to display rich text specified in this way. + markup. Widgets that use QTextDocument, such as QLabel and QTextEdit, are able to display + rich text specified in this way. \tableofcontents -- cgit v0.12 From 4b148a23d4c524ec0abc67415b596c6952c517a8 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 23 Jul 2009 14:52:24 +0200 Subject: Doc: Fixed qdoc warnings Reviewed-by: Trust Me --- src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp | 2 +- src/qt3support/widgets/q3dockarea.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp index f5afbec..34da644 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp @@ -270,7 +270,7 @@ void QWebView::setPage(QWebPage *page) 'ftp'. The result is then passed through QUrl's tolerant parser, and in the case or success, a valid QUrl is returned, or else a QUrl(). - \section2 Examples: + \section1 Examples: \list \o webkit.org becomes http://webkit.org diff --git a/src/qt3support/widgets/q3dockarea.cpp b/src/qt3support/widgets/q3dockarea.cpp index a823caa..d76835a 100644 --- a/src/qt3support/widgets/q3dockarea.cpp +++ b/src/qt3support/widgets/q3dockarea.cpp @@ -482,7 +482,7 @@ int Q3DockAreaLayout::widthForHeight(int h) const \img qmainwindow-qdockareas.png QMainWindow's Q3DockAreas \target lines - \section2 Lines. + \section1 Lines. Q3DockArea uses the concept of lines. A line is a horizontal region which may contain dock windows side-by-side. A dock area -- cgit v0.12 From 9ad53e9404889b119f26d0a7bc7c70bf93364e23 Mon Sep 17 00:00:00 2001 From: Martin Smith Date: Thu, 23 Jul 2009 14:59:31 +0200 Subject: qdoc: Removed obsolete classes from annotated lists. --- tools/qdoc3/htmlgenerator.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index e31f6cf..d82e9f8 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1848,6 +1848,9 @@ HtmlGenerator::generateAnnotatedList(const Node *relative, foreach (const QString &name, nodeMap.keys()) { const Node *node = nodeMap[name]; + if (node->status() == Node::Obsolete) + continue; + if (++row % 2 == 1) out() << ""; else -- cgit v0.12 From 9a1e0047d02fd94f92eda6cd6751bfe4cd876cd2 Mon Sep 17 00:00:00 2001 From: "Bradley T. Hughes" Date: Thu, 23 Jul 2009 13:21:51 +0200 Subject: Fix time change detection on UNIX systems without monotonic timers A few fixes in one: 1. Don't loop on select() when not using monotonic timers... when select returns, the time may have changed, and the offset calculated in the loop may be very wrong on the next iteration. 2. Calculate the elapsed time deltas using timevals instead of integers using milliseconds. This handles changing the time by more than a few hours or days (i.e. months and years) without overflow. 3. When repairing the timers, the diff is already the correct sign, so we should just add the diff. Task-number: 250681 Reviewed-by: Thiago --- src/corelib/kernel/qeventdispatcher_unix.cpp | 75 +++++++++++++++++++--------- src/corelib/kernel/qeventdispatcher_unix_p.h | 46 ++++++++++------- 2 files changed, 79 insertions(+), 42 deletions(-) diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index fac8a28..2139545 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -67,6 +67,25 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT bool qt_disable_lowpriority_timers=false; +// check for _POSIX_MONOTONIC_CLOCK support +static bool supportsMonotonicClock() +{ + bool returnValue; + +#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) + returnValue = false; +# if (_POSIX_MONOTONIC_CLOCK == 0) + // detect if the system support monotonic timers + long x = sysconf(_SC_MONOTONIC_CLOCK); + returnValue = x >= 200112L; +# endif +#else + returnValue = true; +#endif + + return returnValue; +} + /***************************************************************************** UNIX signal handling *****************************************************************************/ @@ -262,18 +281,11 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, */ QTimerInfoList::QTimerInfoList() + : useMonotonicTimers(supportsMonotonicClock()) { -#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) - useMonotonicTimers = false; - -# if (_POSIX_MONOTONIC_CLOCK == 0) - // detect if the system support monotonic timers - long x = sysconf(_SC_MONOTONIC_CLOCK); - useMonotonicTimers = x != -1; -# endif - getTime(currentTime); +#if (_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC) if (!useMonotonicTimers) { // not using monotonic timers, initialize the timeChanged() machinery previousTime = currentTime; @@ -290,9 +302,6 @@ QTimerInfoList::QTimerInfoList() ticksPerSecond = 0; msPerTick = 0; } -#else - // using monotonic timers unconditionally - getTime(currentTime); #endif firstTimerInfo = currentTimerInfo = 0; @@ -306,6 +315,20 @@ timeval QTimerInfoList::updateCurrentTime() #if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED) +template <> +timeval qAbs(const timeval &t) +{ + timeval tmp = t; + if (tmp.tv_sec < 0) { + tmp.tv_sec = -tmp.tv_sec - 1; + tmp.tv_usec -= 1000000; + } + if (tmp.tv_sec == 0 && tmp.tv_usec < 0) { + tmp.tv_usec = -tmp.tv_usec; + } + return normalizedTimeval(tmp); +} + /* Returns true if the real time clock has changed by more than 10% relative to the processor time since the last time this function was @@ -318,23 +341,27 @@ bool QTimerInfoList::timeChanged(timeval *delta) tms unused; clock_t currentTicks = times(&unused); - int elapsedTicks = currentTicks - previousTicks; + clock_t elapsedTicks = currentTicks - previousTicks; timeval elapsedTime = currentTime - previousTime; - int elapsedMsecTicks = (elapsedTicks * 1000) / ticksPerSecond; - int deltaMsecs = (elapsedTime.tv_sec * 1000 + elapsedTime.tv_usec / 1000) - - elapsedMsecTicks; - if (delta) { - delta->tv_sec = deltaMsecs / 1000; - delta->tv_usec = (deltaMsecs % 1000) * 1000; - } + timeval elapsedTimeTicks; + elapsedTimeTicks.tv_sec = elapsedTicks / ticksPerSecond; + elapsedTimeTicks.tv_usec = (((elapsedTicks * 1000) / ticksPerSecond) % 1000) * 1000; + + timeval dummy; + if (!delta) + delta = &dummy; + *delta = elapsedTime - elapsedTimeTicks; + previousTicks = currentTicks; previousTime = currentTime; // If tick drift is more than 10% off compared to realtime, we assume that the clock has // been set. Of course, we have to allow for the tick granularity as well. - - return (qAbs(deltaMsecs) - msPerTick) * 10 > elapsedMsecTicks; + timeval tickGranularity; + tickGranularity.tv_sec = 0; + tickGranularity.tv_usec = msPerTick * 1000; + return elapsedTimeTicks < ((qAbs(*delta) - tickGranularity) * 10); } void QTimerInfoList::getTime(timeval &t) @@ -424,7 +451,7 @@ void QTimerInfoList::timerRepair(const timeval &diff) // repair all timers for (int i = 0; i < size(); ++i) { register QTimerInfo *t = at(i); - t->timeout = t->timeout - diff; + t->timeout = t->timeout + diff; } } @@ -622,7 +649,7 @@ int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd timeval *timeout) { Q_D(QEventDispatcherUNIX); - if (timeout) { + if (timeout && d->timerList.useMonotonicTimers) { // handle the case where select returns with a timeout, too // soon. timeval tvStart = d->timerList.currentTime; diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index ebba21b..28e7f9b 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -71,6 +71,18 @@ QT_BEGIN_NAMESPACE #endif // Internal operator functions for timevals +inline timeval &normalizedTimeval(timeval &t) +{ + while (t.tv_usec > 1000000l) { + ++t.tv_sec; + t.tv_usec -= 1000000l; + } + while (t.tv_usec < 0l) { + --t.tv_sec; + t.tv_usec += 1000000l; + } + return t; +} inline bool operator<(const timeval &t1, const timeval &t2) { return t1.tv_sec < t2.tv_sec || (t1.tv_sec == t2.tv_sec && t1.tv_usec < t2.tv_usec); } inline bool operator==(const timeval &t1, const timeval &t2) @@ -78,31 +90,29 @@ inline bool operator==(const timeval &t1, const timeval &t2) inline timeval &operator+=(timeval &t1, const timeval &t2) { t1.tv_sec += t2.tv_sec; - if ((t1.tv_usec += t2.tv_usec) >= 1000000l) { - ++t1.tv_sec; - t1.tv_usec -= 1000000l; - } - return t1; + t1.tv_usec += t2.tv_usec; + return normalizedTimeval(t1); } inline timeval operator+(const timeval &t1, const timeval &t2) { timeval tmp; tmp.tv_sec = t1.tv_sec + t2.tv_sec; - if ((tmp.tv_usec = t1.tv_usec + t2.tv_usec) >= 1000000l) { - ++tmp.tv_sec; - tmp.tv_usec -= 1000000l; - } - return tmp; + tmp.tv_usec = t1.tv_usec + t2.tv_usec; + return normalizedTimeval(tmp); } inline timeval operator-(const timeval &t1, const timeval &t2) { timeval tmp; - tmp.tv_sec = t1.tv_sec - t2.tv_sec; - if ((tmp.tv_usec = t1.tv_usec - t2.tv_usec) < 0l) { - --tmp.tv_sec; - tmp.tv_usec += 1000000l; - } - return tmp; + tmp.tv_sec = t1.tv_sec - (t2.tv_sec - 1); + tmp.tv_usec = t1.tv_usec - (t2.tv_usec + 1000000); + return normalizedTimeval(tmp); +} +inline timeval operator*(const timeval &t1, int mul) +{ + timeval tmp; + tmp.tv_sec = t1.tv_sec * mul; + tmp.tv_usec = t1.tv_usec * mul; + return normalizedTimeval(tmp); } // internal timer info @@ -117,8 +127,6 @@ struct QTimerInfo { class QTimerInfoList : public QList { #if ((_POSIX_MONOTONIC_CLOCK-0 <= 0) && !defined(Q_OS_MAC)) || defined(QT_BOOTSTRAPPED) - bool useMonotonicTimers; - timeval previousTime; clock_t previousTicks; int ticksPerSecond; @@ -133,6 +141,8 @@ class QTimerInfoList : public QList public: QTimerInfoList(); + const bool useMonotonicTimers; + void getTime(timeval &t); timeval currentTime; -- cgit v0.12 From 6689850242c524cea7877d5fdb41d235e0b55d87 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 23 Jul 2009 15:45:51 +0200 Subject: Doc: link to bugreport form and the public repository --- doc/src/bughowto.qdoc | 8 +++++--- doc/src/trolltech-webpages.qdoc | 10 +++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/src/bughowto.qdoc b/doc/src/bughowto.qdoc index 927cb04..fae1180 100644 --- a/doc/src/bughowto.qdoc +++ b/doc/src/bughowto.qdoc @@ -52,7 +52,9 @@ Notes}, and the \l{Task Tracker} on the Qt website to see if the issue is already known. - Always include the following information in your bug report: + If you have found a new bug, please submit a bug report using + the \l{Bug Report Form}. Always include the following information + in your bug report: \list 1 \o The name and version number of your compiler @@ -66,6 +68,6 @@ such a program can be created with some minor changes to one of the many example programs in Qt's \c examples directory. - Please submit the bug report using the \l{Task Tracker} on the Qt - website. + If you have implemented a bug fix and want to contribute your fix + directly, then you can do so through the \l{Public Qt Repository}. */ diff --git a/doc/src/trolltech-webpages.qdoc b/doc/src/trolltech-webpages.qdoc index 7d48167..abbe4e0 100644 --- a/doc/src/trolltech-webpages.qdoc +++ b/doc/src/trolltech-webpages.qdoc @@ -165,11 +165,6 @@ */ /*! - \externalpage http://www.qtsoftware.com/developer/supported-platforms/supported-platforms/ - \title Qt 4 Supported Platforms -*/ - -/*! \externalpage http://www.qtsoftware.com/products/qtopia/ \title Qt Extended */ @@ -243,3 +238,8 @@ \externalpage http://www.qtsoftware.com/developer/faqs/qt/installation \title Installation FAQ */ + +/*! + \externalpage http://qt.gitorious.org + \title Public Qt Repository +*/ -- cgit v0.12 From 9a77d6c409b991957fc069a2b47476a419ea1aab Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Thu, 23 Jul 2009 16:21:32 +0200 Subject: Finish up my AA_DontSwapMetaAndControl feature. Ugh. The whole reason I added this was so that the text() would be preserved for people that did stuff with Control. Somehow in all the other fixes I did, I forgot to actually do that part. Reviewed-by: Denis --- src/gui/kernel/qkeymapper_mac.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index 017c13c..8eee665 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -729,8 +729,10 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e QString text(ourChar); /* This is actually wrong - but unfortunatly it is the best that can be done for now because of the Control/Meta mapping problems */ - if (modifiers & (Qt::ControlModifier | Qt::MetaModifier)) + if (modifiers & (Qt::ControlModifier | Qt::MetaModifier) + && !qApp->testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) { text = QString(); + } if (widget) { -- cgit v0.12 From 29016ad7cf1e11ae9967748f91acac6f0054bbf8 Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Thu, 23 Jul 2009 13:36:44 +0200 Subject: Fixed embedded mouse and keyboard docu for 4.6 Reviewed-By: Paul --- doc/src/emb-charinput.qdoc | 54 ++++++++++++--- doc/src/emb-kmap2qmap.qdoc | 84 ++++++++++++++++++++++++ doc/src/emb-pointer.qdoc | 17 ++--- doc/src/snippets/code/doc_src_emb-charinput.qdoc | 2 +- src/gui/embedded/qkbd_qws.cpp | 8 +-- 5 files changed, 139 insertions(+), 26 deletions(-) create mode 100644 doc/src/emb-kmap2qmap.qdoc diff --git a/doc/src/emb-charinput.qdoc b/doc/src/emb-charinput.qdoc index c9c768c..565d953 100644 --- a/doc/src/emb-charinput.qdoc +++ b/doc/src/emb-charinput.qdoc @@ -82,13 +82,13 @@ \section1 Available Keyboard Drivers - \l {Qt for Embedded Linux} provides ready-made drivers for the SL5000, Yopy, - Vr41XX, console (TTY) and USB protocols. Run the \c configure - script to list the available drivers: + \l {Qt for Embedded Linux} provides ready-made drivers for the console + (TTY) and the standard Linux Input Subsystem (USB, PS/2, ...). Run the + \c configure script to list the available drivers: \snippet doc/src/snippets/code/doc_src_emb-charinput.qdoc 0 - Note that the console keyboard driver also handles console + Note that only the console (TTY) keyboard driver handles console switching (\bold{Ctrl+Alt+F1}, ..., \bold{Ctrl+Alt+F10}) and termination (\bold{Ctrl+Alt+Backspace}). @@ -105,6 +105,17 @@ detect the plugin, loading the driver into the server application at run-time. + \section1 Keymaps + + Starting with 4.6, \l {Qt for Embedded Linux} has gained support for + user defined keymaps. Keymap handling is supported by the builtin + keyboard drivers \c TTY and \c LinuxInput. Custom keyboard drivers can + use the existing keymap handling code via + QWSKeyboardHandler::processKeycode(). + + By default Qt will use an internal, compiled-in US keymap. + See the options below for how to load a different keymap. + \section1 Specifying a Keyboard Driver To specify which driver to use, set the QWS_KEYBOARD environment @@ -113,14 +124,41 @@ \snippet doc/src/snippets/code/doc_src_emb-charinput.qdoc 2 - The \c argument are \c SL5000, \c Yopy, \c VR41xx, \c - TTY, \c USB and \l {QKbdDriverPlugin::keys()}{keys} identifying - custom drivers, and the driver specific options are typically a - device, e.g., \c /dev/tty0. + The \c argument are \c TTY, \c LinuxInput and \l + {QKbdDriverPlugin::keys()}{keys} identifying custom drivers, and the + driver specific options are typically a device, e.g., \c /dev/tty0. Multiple keyboard drivers can be specified in one go: \snippet doc/src/snippets/code/doc_src_emb-charinput.qdoc 3 Input will be read from all specified drivers. + + Currently the following options are supported by both the \c TTY and \c + LinuxInput driver: + + \table + \header \o Option \o Description + \row \o \c /dev/xxx \o + Open the specified device, instead of the driver's default device. + \row \o \c repeat-delay= \o + Time in milliseconds until auto-repeat kicks in. + \row \o \c repeat-rate= \o + Time in milliseconds specifying interval between auto-repeats. + \row \o \c keymap=xx.qmap \o + File name of a keymap file in Qt's \c qmap format. See \l {kmap2qmap} + for instructions on how to create thoes files.\br Please note that the + file name can of course also be the name of a QResource. + \row \o \c disable-zap \o + Disable the QWS server "Zap" shortcut \bold{Ctrl+Alt+Backspace} + \row \o \c enable-compose \o + Activate Latin-1 composing features in the builtin US keymap. You can + use the right \c AltGr or right \c Alt is used as a dead key modifier, + while \c AltGr+. is the compose key. For example: + \list + \o \c AltGr + \c " + \c u = \uuml (u with diaeresis / umlaut u) + \o \c AltGr + \c . + \c / + \c o = \oslash (slashed o) + \endlist + \endtable + */ diff --git a/doc/src/emb-kmap2qmap.qdoc b/doc/src/emb-kmap2qmap.qdoc new file mode 100644 index 0000000..2b3f687 --- /dev/null +++ b/doc/src/emb-kmap2qmap.qdoc @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page qt-embedded-kmap2qmap.html + \title kmap2qmap + \ingroup qt-embedded-linux + + \c kmap2qmap is a tool to generate keymaps for use on Embedded Linux. + The source files have to be in standard Linux \c kmap format that is + e.g. understood by the kernel's \c loadkeys command. This means you + can use the following sources to generate \c qmap files: + + \list + \o The \l {http://lct.sourceforge.net/}{Linux Console Tools (LCT)} project. + \o \l {http://www.x.org/}{Xorg} X11 keymaps can be converted to the \c + kmap format with the \c ckbcomp utility. + \o Since \c kmap files are plain text files, they can also be hand crafted. + \endlist + + The generated \c qmap files are size optimized binary files. + + \c kmap2qmap is a command line program, that needs at least 2 files as + parameters. The last one will be the generated \c .qmap file, while all + the others will be parsed as input \c .kmap files. For example: + + \code + kmap2qmap i386/qwertz/de-latin1-nodeadkeys.kmap include/compose.latin1.inc de-latin1-nodeadkeys.qmap + \endcode + + \c kmap2qmap doesn't support all the (pseudo) symbols that the Linux + kernel supports. If you are converting a standard keymap you will get a + lot of warnings for things like \c Show_Registers, \c Hex_A, etc.: you + can safely ignore those. + + It also doesn't support numeric symbols (e.g. \c{keycode 1 = 4242}, + instead of \c{keycode 1 = colon}), since these are deprecated and can + change from one kernel version to the other. + + On the other hand, \c kmap2qmap supports one additional, Qt specific, + symbol: \c QtZap. The built-in US keymap has that symbol mapped tp + \c{Ctrl+Alt+Backspace} and it serves as a shortcut to kill your QWS + server (similiar to the X11 server). + + See also \l {Qt for Embedded Linux Character Input} +*/ diff --git a/doc/src/emb-pointer.qdoc b/doc/src/emb-pointer.qdoc index b13dec0..49504fe 100644 --- a/doc/src/emb-pointer.qdoc +++ b/doc/src/emb-pointer.qdoc @@ -64,9 +64,10 @@ \section1 Available Drivers \l{Qt for Embedded Linux} provides ready-made drivers for the MouseMan, - IntelliMouse, Microsoft, NEC Vr41XX, Linux Touch Panel and Yopy - protocols as well as the universal touch screen library, - tslib. Run the \c configure script to list the available drivers: + IntelliMouse, Microsoft and Linux Touch Panel protocols, for the + standard Linux Input Subsystem as well as the universal touch screen + library, tslib. Run the \c configure script to list the available + drivers: \if defined(QTOPIA_PHONE) @@ -125,7 +126,7 @@ \snippet doc/src/snippets/code/doc_src_emb-pointer.qdoc 4 The valid values for the \c argument are \c MouseMan, \c - IntelliMouse, \c Microsoft, \c VR41xx, \c LinuxTP, \c Yopy, \c + IntelliMouse, \c Microsoft, \c LinuxTP, \c LinuxInput, \c Tslib and \l {QMouseDriverPlugin::keys()}{keys} identifying custom drivers, and the driver specific options are typically a device, e.g., \c /dev/mouse for mouse devices and \c /dev/ts for touch @@ -137,14 +138,6 @@ Input will be read from all specified drivers. - Note that the \c Vr41xx driver also accepts two optional - arguments: \c press= defining a mouse click (the default - value is 750) and \c filter= specifying the length of the - filter used to eliminate noise (the default length is 3). For - example: - - \snippet doc/src/snippets/code/doc_src_emb-pointer.qdoc 6 - \table \header \o The Tslib Mouse Driver \row diff --git a/doc/src/snippets/code/doc_src_emb-charinput.qdoc b/doc/src/snippets/code/doc_src_emb-charinput.qdoc index 2539e13..f6b33fe 100644 --- a/doc/src/snippets/code/doc_src_emb-charinput.qdoc +++ b/doc/src/snippets/code/doc_src_emb-charinput.qdoc @@ -4,7 +4,7 @@ //! [1] -configure -qt-kbd-s15000 +configure -qt-kbd-linuxinput //! [1] diff --git a/src/gui/embedded/qkbd_qws.cpp b/src/gui/embedded/qkbd_qws.cpp index 7799339..756a398 100644 --- a/src/gui/embedded/qkbd_qws.cpp +++ b/src/gui/embedded/qkbd_qws.cpp @@ -453,8 +453,9 @@ void QWSKeyboardHandler::endAutoRepeat() Maps \a keycode according to a keymap and sends that key event to the \l{Qt for Embedded Linux} server application. - Please see the QWS_KEYBOARD documentation for a description on how to - create and use keymap files. + Please see the \l{Qt for Embedded Linux Character Input} and the \l + {kmap2qmap} documentations for a description on how to create and use + keymap files. The key event is identified by its \a keycode value and the \a isPress and \a autoRepeat parameters. @@ -475,9 +476,6 @@ void QWSKeyboardHandler::endAutoRepeat() implementation needs to take care of a special action, like console switching or LED handling. - Standard Linux console keymaps can be found at the - \l {http://lct.sourceforege.net}{LCT project} - If standard Linux console keymaps are used, \a keycode must be one of the standardized values defined in \c /usr/include/linux/input.h -- cgit v0.12 From 89fc5334c2ef0b92114284d0ffb26d65f76fdb3b Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Wed, 22 Jul 2009 16:21:43 +0200 Subject: Qt/EL mouse and keyboard driver cleanup. * removed the vr41xx, yopy and sl5000 drivers (old PDAs) * removed the bus mouse driver (ISA days should be over) * renamed the LinuxIS mouse driver to LinuxInput (consistency with the key driver) * unified the LinuxInput mouse and key driver I/O handling Reviewed-By: Paul --- configure | 4 +- src/gui/embedded/embedded.pri | 40 +-- src/gui/embedded/qkbddriverfactory_qws.cpp | 24 -- src/gui/embedded/qkbdlinuxinput_qws.cpp | 13 +- src/gui/embedded/qkbdsl5000_qws.cpp | 367 --------------------- src/gui/embedded/qkbdsl5000_qws.h | 92 ------ src/gui/embedded/qkbdtty_qws.cpp | 20 +- src/gui/embedded/qkbdvr41xx_qws.cpp | 186 ----------- src/gui/embedded/qkbdvr41xx_qws.h | 73 ---- src/gui/embedded/qkbdyopy_qws.cpp | 211 ------------ src/gui/embedded/qkbdyopy_qws.h | 73 ---- src/gui/embedded/qmousebus_qws.cpp | 239 -------------- src/gui/embedded/qmousebus_qws.h | 76 ----- src/gui/embedded/qmousedriverfactory_qws.cpp | 34 +- src/gui/embedded/qmouselinuxinput_qws.cpp | 205 ++++++++++++ src/gui/embedded/qmouselinuxinput_qws.h | 78 +++++ src/gui/embedded/qmousevr41xx_qws.cpp | 251 -------------- src/gui/embedded/qmousevr41xx_qws.h | 80 ----- src/gui/embedded/qmouseyopy_qws.cpp | 185 ----------- src/gui/embedded/qmouseyopy_qws.h | 80 ----- src/plugins/kbddrivers/kbddrivers.pro | 3 - src/plugins/kbddrivers/sl5000/main.cpp | 76 ----- src/plugins/kbddrivers/sl5000/sl5000.pro | 16 - src/plugins/kbddrivers/vr41xx/main.cpp | 76 ----- src/plugins/kbddrivers/vr41xx/vr41xx.pro | 14 - src/plugins/kbddrivers/yopy/main.cpp | 76 ----- src/plugins/kbddrivers/yopy/yopy.pro | 14 - src/plugins/mousedrivers/bus/bus.pro | 14 - src/plugins/mousedrivers/bus/main.cpp | 76 ----- src/plugins/mousedrivers/linuxis/linuxis.pro | 10 - .../linuxis/linuxismousedriverplugin.cpp | 83 ----- .../linuxis/linuxismousedriverplugin.h | 58 ---- .../mousedrivers/linuxis/linuxismousehandler.cpp | 180 ---------- .../mousedrivers/linuxis/linuxismousehandler.h | 72 ---- src/plugins/mousedrivers/mousedrivers.pro | 5 +- src/plugins/mousedrivers/vr41xx/main.cpp | 76 ----- src/plugins/mousedrivers/vr41xx/vr41xx.pro | 14 - src/plugins/mousedrivers/yopy/main.cpp | 76 ----- src/plugins/mousedrivers/yopy/yopy.pro | 14 - 39 files changed, 319 insertions(+), 2965 deletions(-) delete mode 100644 src/gui/embedded/qkbdsl5000_qws.cpp delete mode 100644 src/gui/embedded/qkbdsl5000_qws.h delete mode 100644 src/gui/embedded/qkbdvr41xx_qws.cpp delete mode 100644 src/gui/embedded/qkbdvr41xx_qws.h delete mode 100644 src/gui/embedded/qkbdyopy_qws.cpp delete mode 100644 src/gui/embedded/qkbdyopy_qws.h delete mode 100644 src/gui/embedded/qmousebus_qws.cpp delete mode 100644 src/gui/embedded/qmousebus_qws.h create mode 100644 src/gui/embedded/qmouselinuxinput_qws.cpp create mode 100644 src/gui/embedded/qmouselinuxinput_qws.h delete mode 100644 src/gui/embedded/qmousevr41xx_qws.cpp delete mode 100644 src/gui/embedded/qmousevr41xx_qws.h delete mode 100644 src/gui/embedded/qmouseyopy_qws.cpp delete mode 100644 src/gui/embedded/qmouseyopy_qws.h delete mode 100644 src/plugins/kbddrivers/sl5000/main.cpp delete mode 100644 src/plugins/kbddrivers/sl5000/sl5000.pro delete mode 100644 src/plugins/kbddrivers/vr41xx/main.cpp delete mode 100644 src/plugins/kbddrivers/vr41xx/vr41xx.pro delete mode 100644 src/plugins/kbddrivers/yopy/main.cpp delete mode 100644 src/plugins/kbddrivers/yopy/yopy.pro delete mode 100644 src/plugins/mousedrivers/bus/bus.pro delete mode 100644 src/plugins/mousedrivers/bus/main.cpp delete mode 100644 src/plugins/mousedrivers/linuxis/linuxis.pro delete mode 100644 src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.cpp delete mode 100644 src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.h delete mode 100644 src/plugins/mousedrivers/linuxis/linuxismousehandler.cpp delete mode 100644 src/plugins/mousedrivers/linuxis/linuxismousehandler.h delete mode 100644 src/plugins/mousedrivers/vr41xx/main.cpp delete mode 100644 src/plugins/mousedrivers/vr41xx/vr41xx.pro delete mode 100644 src/plugins/mousedrivers/yopy/main.cpp delete mode 100644 src/plugins/mousedrivers/yopy/yopy.pro diff --git a/configure b/configure index b65e6d5..4b75a75 100755 --- a/configure +++ b/configure @@ -614,9 +614,9 @@ CFG_GFX_ON="linuxfb multiscreen" CFG_GFX_PLUGIN_AVAILABLE= CFG_GFX_PLUGIN= CFG_GFX_OFF= -CFG_KBD_AVAILABLE="tty linuxinput sl5000 yopy vr41xx qvfb" +CFG_KBD_AVAILABLE="tty linuxinput qvfb" CFG_KBD_ON="tty" #default, see QMakeVar above -CFG_MOUSE_AVAILABLE="pc bus linuxtp yopy vr41xx tslib qvfb" +CFG_MOUSE_AVAILABLE="pc linuxtp linuxinput tslib qvfb" CFG_MOUSE_ON="pc linuxtp" #default, see QMakeVar above CFG_ARCH= diff --git a/src/gui/embedded/embedded.pri b/src/gui/embedded/embedded.pri index 4a9aa3f..53a2512 100644 --- a/src/gui/embedded/embedded.pri +++ b/src/gui/embedded/embedded.pri @@ -141,15 +141,7 @@ embedded { !contains( kbd-drivers, qvfb ) { kbd-drivers += qvfb } - } - - contains( kbd-drivers, sl5000 ) { - HEADERS +=embedded/qkbdsl5000_qws.h - SOURCES +=embedded/qkbdsl5000_qws.cpp - !contains( kbd-drivers, tty ) { - kbd-drivers += tty - } - } + } contains( kbd-drivers, tty ) { HEADERS +=embedded/qkbdtty_qws.h @@ -166,16 +158,6 @@ embedded { SOURCES +=embedded/qkbdum_qws.cpp } - contains( kbd-drivers, yopy ) { - HEADERS +=embedded/qkbdyopy_qws.h - SOURCES +=embedded/qkbdyopy_qws.cpp - } - - contains( kbd-drivers, vr41xx ) { - HEADERS +=embedded/qkbdvr41xx_qws.h - SOURCES +=embedded/qkbdvr41xx_qws.cpp - } - # # Mouse drivers # @@ -189,29 +171,19 @@ embedded { SOURCES +=embedded/qmousepc_qws.cpp } - contains( mouse-drivers, bus ) { - HEADERS +=embedded/qmousebus_qws.h - SOURCES +=embedded/qmousebus_qws.cpp - } - contains( mouse-drivers, linuxtp ) { HEADERS +=embedded/qmouselinuxtp_qws.h SOURCES +=embedded/qmouselinuxtp_qws.cpp } - contains( mouse-drivers, vr41xx ) { - HEADERS +=embedded/qmousevr41xx_qws.h - SOURCES +=embedded/qmousevr41xx_qws.cpp - } - - contains( mouse-drivers, yopy ) { - HEADERS +=embedded/qmouseyopy_qws.h - SOURCES +=embedded/qmouseyopy_qws.cpp - } - contains( mouse-drivers, tslib ) { LIBS += -lts HEADERS +=embedded/qmousetslib_qws.h SOURCES +=embedded/qmousetslib_qws.cpp } + + contains( mouse-drivers, linuxinput ) { + HEADERS +=embedded/qmouselinuxinput_qws.h + SOURCES +=embedded/qmouselinuxinput_qws.cpp + } } diff --git a/src/gui/embedded/qkbddriverfactory_qws.cpp b/src/gui/embedded/qkbddriverfactory_qws.cpp index c599396..b77eb72 100644 --- a/src/gui/embedded/qkbddriverfactory_qws.cpp +++ b/src/gui/embedded/qkbddriverfactory_qws.cpp @@ -47,10 +47,7 @@ #include "qkbdtty_qws.h" #include "qkbdlinuxinput_qws.h" #include "qkbdum_qws.h" -#include "qkbdsl5000_qws.h" #include "qkbdvfb_qws.h" -#include "qkbdyopy_qws.h" -#include "qkbdvr41xx_qws.h" #include #include "private/qfactoryloader_p.h" #include "qkbddriverplugin_qws.h" @@ -104,18 +101,6 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, QWSKeyboardHandler *QKbdDriverFactory::create(const QString& key, const QString& device) { QString driver = key.toLower(); -#ifndef QT_NO_QWS_KBD_SL5000 - if (driver == QLatin1String("sl5000") || driver.isEmpty()) - return new QWSSL5000KeyboardHandler(device); -#endif -#ifndef QT_NO_QWS_KBD_YOPY - if (driver == QLatin1String("yopy") || driver.isEmpty()) - return new QWSYopyKeyboardHandler(device); -#endif -#ifndef QT_NO_QWS_KBD_VR41XX - if (driver == QLatin1String("vr41xx") || driver.isEmpty()) - return new QWSVr41xxKeyboardHandler(device); -#endif #ifndef QT_NO_QWS_KEYBOARD # ifndef QT_NO_QWS_KBD_TTY if (driver == QLatin1String("tty") || driver.isEmpty()) @@ -158,15 +143,6 @@ QStringList QKbdDriverFactory::keys() { QStringList list; -#ifndef QT_NO_QWS_KBD_SL5000 - list << QLatin1String("SL5000"); -#endif -#ifndef QT_NO_QWS_KBD_YOPY - list << QLatin1String("YOPY"); -#endif -#ifndef QT_NO_QWS_KBD_VR41XX - list << QLatin1String("VR41xx"); -#endif #ifndef QT_NO_QWS_KBD_TTY list << QLatin1String("TTY"); #endif diff --git a/src/gui/embedded/qkbdlinuxinput_qws.cpp b/src/gui/embedded/qkbdlinuxinput_qws.cpp index e552731..6aa6633 100644 --- a/src/gui/embedded/qkbdlinuxinput_qws.cpp +++ b/src/gui/embedded/qkbdlinuxinput_qws.cpp @@ -76,6 +76,7 @@ private: int m_fd; int m_tty_fd; struct termios m_tty_attr; + int m_orig_kbmode; }; QWSLinuxInputKeyboardHandler::QWSLinuxInputKeyboardHandler(const QString &device) @@ -95,8 +96,7 @@ bool QWSLinuxInputKeyboardHandler::filterInputEvent(quint16 &, qint32 &) } QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, const QString &device) - : m_handler(h), m_fd(-1), m_tty_fd(-1) - + : m_handler(h), m_fd(-1), m_tty_fd(-1), m_orig_kbmode(K_XLATE) { setObjectName(QLatin1String("LinuxInputSubsystem Keyboard Handler")); @@ -135,7 +135,10 @@ QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, struct ::termios termdata; tcgetattr(m_tty_fd, &termdata); - // setting this tranlation mode is also needed in INPUT mode to prevent + // record the original mode so we can restore it again in the destructor. + ::ioctl(m_tty_fd, KDGKBMODE, &m_orig_kbmode); + + // setting this tranlation mode is even needed in INPUT mode to prevent // the shell from also interpreting codes, if the process has a tty // attached: e.g. Ctrl+C wouldn't copy, but kill the application. ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW); @@ -152,7 +155,7 @@ QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, tcsetattr(m_tty_fd, TCSANOW, &termdata); } } else { - qWarning("Cannot open input device '%s': %s", qPrintable(dev), strerror(errno)); + qWarning("Cannot open keyboard input device '%s': %s", qPrintable(dev), strerror(errno)); return; } } @@ -160,7 +163,7 @@ QWSLinuxInputKbPrivate::QWSLinuxInputKbPrivate(QWSLinuxInputKeyboardHandler *h, QWSLinuxInputKbPrivate::~QWSLinuxInputKbPrivate() { if (m_tty_fd >= 0) { - ::ioctl(m_tty_fd, KDSKBMODE, K_XLATE); + ::ioctl(m_tty_fd, KDSKBMODE, m_orig_kbmode); tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr); } if (m_fd >= 0) diff --git a/src/gui/embedded/qkbdsl5000_qws.cpp b/src/gui/embedded/qkbdsl5000_qws.cpp deleted file mode 100644 index cf82c10..0000000 --- a/src/gui/embedded/qkbdsl5000_qws.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkbdsl5000_qws.h" - -#ifndef QT_NO_QWS_KBD_SL5000 - -#include "qwindowsystem_qws.h" -#include "qwsutils_qws.h" -#include "qscreen_qws.h" - -#include "qapplication.h" -#include "qnamespace.h" -#include "qtimer.h" - -#include // overrides QT_OPEN - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -QT_BEGIN_NAMESPACE - -static const QWSKeyMap sl5000KeyMap[] = { - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 00 - { Qt::Key_A, 'a' , 'A' , 'A'-64 }, // 01 - { Qt::Key_B, 'b' , 'B' , 'B'-64 }, // 02 - { Qt::Key_C, 'c' , 'C' , 'C'-64 }, // 03 - { Qt::Key_D, 'd' , 'D' , 'D'-64 }, // 04 - { Qt::Key_E, 'e' , 'E' , 'E'-64 }, // 05 - { Qt::Key_F, 'f' , 'F' , 'F'-64 }, // 06 - { Qt::Key_G, 'g' , 'G' , 'G'-64 }, // 07 - { Qt::Key_H, 'h' , 'H' , 'H'-64 }, // 08 - { Qt::Key_I, 'i' , 'I' , 'I'-64 }, // 09 - { Qt::Key_J, 'j' , 'J' , 'J'-64 }, // 0a 10 - { Qt::Key_K, 'k' , 'K' , 'K'-64 }, // 0b - { Qt::Key_L, 'l' , 'L' , 'L'-64 }, // 0c - { Qt::Key_M, 'm' , 'M' , 'M'-64 }, // 0d - { Qt::Key_N, 'n' , 'N' , 'N'-64 }, // 0e - { Qt::Key_O, 'o' , 'O' , 'O'-64 }, // 0f - { Qt::Key_P, 'p' , 'P' , 'P'-64 }, // 10 - { Qt::Key_Q, 'q' , 'Q' , 'Q'-64 }, // 11 - { Qt::Key_R, 'r' , 'R' , 'R'-64 }, // 12 - { Qt::Key_S, 's' , 'S' , 'S'-64 }, // 13 - { Qt::Key_T, 't' , 'T' , 'T'-64 }, // 14 20 - { Qt::Key_U, 'u' , 'U' , 'U'-64 }, // 15 - { Qt::Key_V, 'v' , 'V' , 'V'-64 }, // 16 - { Qt::Key_W, 'w' , 'W' , 'W'-64 }, // 17 - { Qt::Key_X, 'x' , 'X' , 'X'-64 }, // 18 - { Qt::Key_Y, 'y' , 'Y' , 'Y'-64 }, // 19 - { Qt::Key_Z, 'z' , 'Z' , 'Z'-64 }, // 1a - { Qt::Key_Shift, 0xffff , 0xffff , 0xffff }, // 1b - { Qt::Key_Return, 13 , 13 , 0xffff }, // 1c - { Qt::Key_F11, 0xffff , 0xffff , 0xffff }, // 1d todo - { Qt::Key_F22, 0xffff , 0xffff , 0xffff }, // 1e 30 - { Qt::Key_Backspace, 8 , 8 , 0xffff }, // 1f - { Qt::Key_F31, 0xffff , 0xffff , 0xffff }, // 20 - { Qt::Key_F35, 0xffff , 0xffff , 0xffff }, // 21 light - { Qt::Key_Escape, 0xffff , 0xffff , 0xffff }, // 22 - - // Direction key code are for *UNROTATED* display. - { Qt::Key_Up, 0xffff , 0xffff , 0xffff }, // 23 - { Qt::Key_Right, 0xffff , 0xffff , 0xffff }, // 24 - { Qt::Key_Left, 0xffff , 0xffff , 0xffff }, // 25 - { Qt::Key_Down, 0xffff , 0xffff , 0xffff }, // 26 - - { Qt::Key_F33, 0xffff , 0xffff , 0xffff }, // 27 OK - { Qt::Key_F12, 0xffff , 0xffff , 0xffff }, // 28 40 home - { Qt::Key_1, '1' , 'q' , 'Q'-64 }, // 29 - { Qt::Key_2, '2' , 'w' , 'W'-64 }, // 2a - { Qt::Key_3, '3' , 'e' , 'E'-64 }, // 2b - { Qt::Key_4, '4' , 'r' , 'R'-64 }, // 2c - { Qt::Key_5, '5' , 't' , 'T'-64 }, // 2d - { Qt::Key_6, '6' , 'y' , 'Y'-64 }, // 2e - { Qt::Key_7, '7' , 'u' , 'U'-64 }, // 2f - { Qt::Key_8, '8' , 'i' , 'I'-64 }, // 30 - { Qt::Key_9, '9' , 'o' , 'O'-64 }, // 31 - { Qt::Key_0, '0' , 'p' , 'P'-64 }, // 32 50 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 33 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 34 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 35 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 36 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 37 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 38 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 39 - { Qt::Key_Minus, '-' , 'b' , 'B'-64 }, // 3a - { Qt::Key_Plus, '+' , 'n' , 'N'-64 }, // 3b - { Qt::Key_CapsLock, 0xffff , 0xffff , 0xffff }, // 3c 60 - { Qt::Key_At, '@' , 's' , 'S'-64 }, // 3d - { Qt::Key_Question, '?' , '?' , 0xffff }, // 3e - { Qt::Key_Comma, ',' , ',' , 0xffff }, // 3f - { Qt::Key_Period, '.' , '.' , 0xffff }, // 40 - { Qt::Key_Tab, 9 , '\\' , 0xffff }, // 41 - { Qt::Key_X, 0xffff , 'x' , 'X'-64 }, // 42 - { Qt::Key_C, 0xffff , 'c' , 'C'-64 }, // 43 - { Qt::Key_V, 0xffff , 'v' , 'V'-64 }, // 44 - { Qt::Key_Slash, '/' , '/' , 0xffff }, // 45 - { Qt::Key_Apostrophe, '\'' , '\'' , 0xffff }, // 46 70 - { Qt::Key_Semicolon, ';' , ';' , 0xffff }, // 47 - { Qt::Key_QuoteDbl, '\"' , '\"' , 0xffff }, // 48 - { Qt::Key_Colon, ':' , ':' , 0xffff }, // 49 - { Qt::Key_NumberSign, '#' , 'd' , 'D'-64 }, // 4a - { Qt::Key_Dollar, '$' , 'f' , 'F'-64 }, // 4b - { Qt::Key_Percent, '%' , 'g' , 'G'-64 }, // 4c - { Qt::Key_Underscore, '_' , 'h' , 'H'-64 }, // 4d - { Qt::Key_Ampersand, '&' , 'j' , 'J'-64 }, // 4e - { Qt::Key_Asterisk, '*' , 'k' , 'K'-64 }, // 4f - { Qt::Key_ParenLeft, '(' , 'l' , 'L'-64 }, // 50 80 - { Qt::Key_Delete, '[' , '[' , '[' }, // 51 - { Qt::Key_Z, 0xffff , 'z' , 'Z'-64 }, // 52 - { Qt::Key_Equal, '=' , 'm' , 'M'-64 }, // 53 - { Qt::Key_ParenRight, ')' , ']' , ']' }, // 54 - { Qt::Key_AsciiTilde, '~' , '^' , '^' }, // 55 - { Qt::Key_Less, '<' , '{' , '{' }, // 56 - { Qt::Key_Greater, '>' , '}' , '}' }, // 57 - { Qt::Key_F9, 0xffff , 0xffff , 0xffff }, // 58 datebook - { Qt::Key_F10, 0xffff , 0xffff , 0xffff }, // 59 address - { Qt::Key_F13, 0xffff , 0xffff , 0xffff }, // 5a 90 email - { Qt::Key_F30, ' ' , ' ' , 0xffff }, // 5b select - { Qt::Key_Space, ' ' , '|' , '`' }, // 5c - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 5d - { Qt::Key_Exclam, '!' , 'a' , 'A'-64 }, // 5e - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 5f - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 60 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 61 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 62 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 63 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 64 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 65 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 66 - { Qt::Key_Meta, 0xffff , 0xffff , 0xffff }, // 67 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 68 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 69 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6a - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6b - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6c - { Qt::Key_F34, 0xffff , 0xffff , 0xffff }, // 6d power - { Qt::Key_F13, 0xffff , 0xffff , 0xffff }, // 6e mail long - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 6f - { Qt::Key_NumLock, 0xffff , 0xffff , 0xffff }, // 70 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 71 - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 72 - { 0x20ac, 0xffff , 0x20ac , 0x20ac }, // 73 Euro sign - { Qt::Key_unknown, 0xffff , 0xffff , 0xffff }, // 74 - { Qt::Key_F32, 0xffff , 0xffff , 0xffff }, // 75 Sync - { 0, 0xffff , 0xffff , 0xffff } -}; - -static const int keyMSize = sizeof(sl5000KeyMap)/sizeof(QWSKeyMap)-1; - -QWSSL5000KeyboardHandler::QWSSL5000KeyboardHandler(const QString &device) - : QWSTtyKeyboardHandler(device) -{ - shift = false; - alt = false; - ctrl = false; - extended = 0; - prevuni = 0; - prevkey = 0; - caps = false; - meta = false; - fn = false; - numLock = false; - - sharp_kbdctl_modifstat st; - int dev = QT_OPEN(device.isEmpty()?"/dev/sharp_kbdctl":device.toLocal8Bit().constData(), O_RDWR); - if (dev >= 0) { - memset(&st, 0, sizeof(st)); - st.which = 3; - int ret = ioctl(dev, SHARP_KBDCTL_GETMODIFSTAT, (char*)&st); - if(!ret) - numLock = (bool)st.stat; - QT_CLOSE(dev); - } -} - -QWSSL5000KeyboardHandler::~QWSSL5000KeyboardHandler() -{ -} - -const QWSKeyMap *QWSSL5000KeyboardHandler::keyMap() const -{ - return sl5000KeyMap; -} - -bool QWSSL5000KeyboardHandler::filterKeycode(char &code) -{ - int keyCode = Qt::Key_unknown; - bool release = false; - - if (code & 0x80) { - release = true; - code &= 0x7f; - } - - if (fn && !meta && (code >= 0x42 && code <= 0x52)) { - ushort unicode=0; - int scan=0; - if (code == 0x42) { unicode='X'-'@'; scan=Qt::Key_X; } // Cut - else if (code == 0x43) { unicode='C'-'@'; scan=Qt::Key_C; } // Copy - else if (code == 0x44) { unicode='V'-'@'; scan=Qt::Key_V; } // Paste - else if (code == 0x52) { unicode='Z'-'@'; scan=Qt::Key_Z; } // Undo - if (scan) { - processKeyEvent(unicode, scan, Qt::ControlModifier, !release, false); - return true; - } - } - - if (code < keyMSize) { - keyCode = keyMap()[int(code)].key_code; - } - - bool repeatable = true; - - if (release && (keyCode == Qt::Key_F34 || keyCode == Qt::Key_F35)) - return true; // no release for power and light keys - if ((keyCode >= Qt::Key_F1 && keyCode <= Qt::Key_F35) - || keyCode == Qt::Key_Escape || keyCode == Qt::Key_Home - || keyCode == Qt::Key_Shift || keyCode == Qt::Key_Meta) - repeatable = false; - - if (qt_screen->isTransformed() - && keyCode >= Qt::Key_Left && keyCode <= Qt::Key_Down) - { - keyCode = transformDirKey(keyCode); - } - - // Ctrl-Alt-Delete exits qws - if (ctrl && alt && keyCode == Qt::Key_Delete) { - qApp->quit(); - } - - if (keyCode == Qt::Key_F22) { /* Fn key */ - fn = !release; - } else if (keyCode == Qt::Key_NumLock) { - if (release) - numLock = !numLock; - } else if (keyCode == Qt::AltModifier) { - alt = !release; - } else if (keyCode == Qt::ControlModifier) { - ctrl = !release; - } else if (keyCode == Qt::ShiftModifier) { - shift = !release; - } else if (keyCode == Qt::MetaModifier) { - meta = !release; - } else if (keyCode == Qt::Key_CapsLock && release) { - caps = !caps; - } - if (keyCode != Qt::Key_unknown) { - bool bAlt = alt; - bool bCtrl = ctrl; - bool bShift = shift; - int unicode = 0; - if (code < keyMSize) { - bool bCaps = caps ^ shift; - if (fn) { - if (shift) { - bCaps = bShift = false; - bCtrl = true; - } - if (meta) { - bCaps = bShift = true; - bAlt = true; - } - } else if (meta) { - bCaps = bShift = true; - } - if (code > 40 && caps) { - // fn-keys should only react to shift, not caps - bCaps = bShift = shift; - } - if (numLock) { - if (keyCode != Qt::Key_Space && keyCode != Qt::Key_Tab) - bCaps = bShift = false; - } - if (keyCode == Qt::Key_Delete && (bAlt || bCtrl)) { - keyCode = Qt::Key_BraceLeft; - unicode = '['; - bCaps = bShift = bAlt = bCtrl = false; - } else if (keyCode == Qt::Key_F31 && bCtrl) { - keyCode = Qt::Key_QuoteLeft; - unicode = '`'; - } else if (bCtrl) - unicode = keyMap()[int(code)].ctrl_unicode ? keyMap()[int(code)].ctrl_unicode : 0xffff; - else if (bCaps) - unicode = keyMap()[int(code)].shift_unicode ? keyMap()[int(code)].shift_unicode : 0xffff; - else - unicode = keyMap()[int(code)].unicode ? keyMap()[int(code)].unicode : 0xffff; - } - - modifiers = 0; - if (bAlt) modifiers |= Qt::AltModifier; - if (bCtrl) modifiers |= Qt::ControlModifier; - if (bShift) modifiers |= Qt::ShiftModifier; - - // looks wrong -- WWA - bool repeat = false; - if (prevuni == unicode && prevkey == keyCode && !release) - repeat = true; - - processKeyEvent(unicode, keyCode, modifiers, !release, repeat); - - if (!release) { - prevuni = unicode; - prevkey = keyCode; - } else { - prevkey = prevuni = 0; - } - } - - if (repeatable && !release) - beginAutoRepeat(prevuni, prevkey, modifiers); - else - endAutoRepeat(); - - return true; -} - -QT_END_NAMESPACE - -#endif // QT_NO_QWS_KBD_SL5000 diff --git a/src/gui/embedded/qkbdsl5000_qws.h b/src/gui/embedded/qkbdsl5000_qws.h deleted file mode 100644 index 42afbe1..0000000 --- a/src/gui/embedded/qkbdsl5000_qws.h +++ /dev/null @@ -1,92 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QKBDSL5000_QWS_H -#define QKBDSL5000_QWS_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_QWS_KBD_SL5000 - -struct QWSKeyMap { - uint key_code; - ushort unicode; - ushort shift_unicode; - ushort ctrl_unicode; -}; - - -class QWSSL5000KeyboardHandler : public QWSTtyKeyboardHandler -{ -public: - explicit QWSSL5000KeyboardHandler(const QString&); - virtual ~QWSSL5000KeyboardHandler(); - - bool filterKeycode(char &keycode); - virtual const QWSKeyMap *keyMap() const; - -private: - bool shift; - bool alt; - bool ctrl; - bool caps; - uint extended:2; - Qt::KeyboardModifiers modifiers; - int prevuni; - int prevkey; - bool meta; - bool fn; - bool numLock; -}; - -#endif // QT_NO_QWS_KBD_SL5000 - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QKBDSL5000_QWS_H diff --git a/src/gui/embedded/qkbdtty_qws.cpp b/src/gui/embedded/qkbdtty_qws.cpp index 8c1e79b..f107567 100644 --- a/src/gui/embedded/qkbdtty_qws.cpp +++ b/src/gui/embedded/qkbdtty_qws.cpp @@ -90,7 +90,7 @@ private: struct termios m_tty_attr; char m_last_keycode; int m_vt_qws; - int m_originalKbdMode; + int m_orig_kbmode; }; @@ -111,7 +111,7 @@ bool QWSTtyKeyboardHandler::filterKeycode(char &) } QWSTtyKbPrivate::QWSTtyKbPrivate(QWSTtyKeyboardHandler *h, const QString &device) - : m_handler(h), m_tty_fd(-1), m_last_keycode(0), m_vt_qws(0) + : m_handler(h), m_tty_fd(-1), m_last_keycode(0), m_vt_qws(0), m_orig_kbmode(K_XLATE) { setObjectName(QLatin1String("TTY Keyboard Handler")); #ifndef QT_NO_QWS_SIGNALHANDLER @@ -152,15 +152,15 @@ QWSTtyKbPrivate::QWSTtyKbPrivate(QWSTtyKeyboardHandler *h, const QString &device tcgetattr(m_tty_fd, &termdata); #if defined(Q_OS_LINUX) - // record the original mode so we can restore it again in the constructor - ::ioctl(m_tty_fd, KDGKBMODE, m_originalKbdMode); + // record the original mode so we can restore it again in the destructor. + ::ioctl(m_tty_fd, KDGKBMODE, &m_orig_kbmode); // PLEASE NOTE: - // The tty keycode interface can only report keycodes 0x01 .. 0x7f + // the tty keycode interface can only report keycodes 0x01 .. 0x7f // KEY_MAX is however defined to 0x1ff. In practice this is sufficient // for a PC style keyboard though. - // we don't support K_RAW anymore - if you need, you habe to add a - // scan- to keycode converter. + // we don't support K_RAW anymore - if you need that, you have to add + // a scan- to keycode converter yourself. ::ioctl(m_tty_fd, KDSKBMODE, K_MEDIUMRAW); #endif @@ -211,12 +211,10 @@ QWSTtyKbPrivate::~QWSTtyKbPrivate() { if (m_tty_fd >= 0) { #if defined(Q_OS_LINUX) - ::ioctl(m_tty_fd, KDSKBMODE, m_originalKbdMode); + ::ioctl(m_tty_fd, KDSKBMODE, m_orig_kbmode); #endif tcsetattr(m_tty_fd, TCSANOW, &m_tty_attr); - - // we're leaking m_tty_fd here? - //QT_CLOSE(m_tty_fd); + QT_CLOSE(m_tty_fd); } } diff --git a/src/gui/embedded/qkbdvr41xx_qws.cpp b/src/gui/embedded/qkbdvr41xx_qws.cpp deleted file mode 100644 index 6d8299b..0000000 --- a/src/gui/embedded/qkbdvr41xx_qws.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qkbdvr41xx_qws.h" - -#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_VR41XX) - -#include -#include -#include -#include -#include -#include -#include - -#include -#include // overrides QT_OPEN - -QT_BEGIN_NAMESPACE - -class QWSVr41xxKbPrivate : public QObject -{ - Q_OBJECT -public: - QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QString&); - virtual ~QWSVr41xxKbPrivate(); - - bool isOpen() { return buttonFD > 0; } - -private slots: - void readKeyboardData(); - -private: - QString terminalName; - int buttonFD; - int kbdIdx; - int kbdBufferLen; - unsigned char *kbdBuffer; - QSocketNotifier *notifier; - QWSVr41xxKeyboardHandler *handler; -}; - -QWSVr41xxKeyboardHandler::QWSVr41xxKeyboardHandler(const QString &device) -{ - d = new QWSVr41xxKbPrivate(this, device); -} - -QWSVr41xxKeyboardHandler::~QWSVr41xxKeyboardHandler() -{ - delete d; -} - -QWSVr41xxKbPrivate::QWSVr41xxKbPrivate(QWSVr41xxKeyboardHandler *h, const QString &device) : handler(h) -{ - terminalName = device; - if (terminalName.isEmpty()) - terminalName = QLatin1String("/dev/buttons"); - buttonFD = -1; - notifier = 0; - - buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0);; - if (buttonFD < 0) { - qWarning("Cannot open %s\n", qPrintable(terminalName)); - return; - } - - if (buttonFD >= 0) { - notifier = new QSocketNotifier(buttonFD, QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)),this, - SLOT(readKeyboardData())); - } - - kbdBufferLen = 80; - kbdBuffer = new unsigned char [kbdBufferLen]; - kbdIdx = 0; -} - -QWSVr41xxKbPrivate::~QWSVr41xxKbPrivate() -{ - if (buttonFD > 0) { - QT_CLOSE(buttonFD); - buttonFD = -1; - } - delete notifier; - notifier = 0; - delete [] kbdBuffer; -} - -void QWSVr41xxKbPrivate::readKeyboardData() -{ - int n = 0; - do { - n = QT_READ(buttonFD, kbdBuffer+kbdIdx, kbdBufferLen - kbdIdx); - if (n > 0) - kbdIdx += n; - } while (n > 0); - - int idx = 0; - while (kbdIdx - idx >= 2) { - unsigned char *next = kbdBuffer + idx; - unsigned short *code = (unsigned short *)next; - int keycode = Qt::Key_unknown; - switch ((*code) & 0x0fff) { - case 0x7: - keycode = Qt::Key_Up; - break; - case 0x9: - keycode = Qt::Key_Right; - break; - case 0x8: - keycode = Qt::Key_Down; - break; - case 0xa: - keycode = Qt::Key_Left; - break; - case 0x3: - keycode = Qt::Key_Up; - break; - case 0x4: - keycode = Qt::Key_Down; - break; - case 0x1: - keycode = Qt::Key_Return; - break; - case 0x2: - keycode = Qt::Key_F4; - break; - default: - qDebug("Unrecognised key sequence %d", *code); - } - if ((*code) & 0x8000) - handler->processKeyEvent(0, keycode, 0, false, false); - else - handler->processKeyEvent(0, keycode, 0, true, false); - idx += 2; - } - - int surplus = kbdIdx - idx; - for (int i = 0; i < surplus; i++) - kbdBuffer[i] = kbdBuffer[idx+i]; - kbdIdx = surplus; -} - -QT_END_NAMESPACE - -#include "qkbdvr41xx_qws.moc" - -#endif // QT_NO_QWS_KBD_VR41XX diff --git a/src/gui/embedded/qkbdvr41xx_qws.h b/src/gui/embedded/qkbdvr41xx_qws.h deleted file mode 100644 index 1a657b9..0000000 --- a/src/gui/embedded/qkbdvr41xx_qws.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QKBDVR41XX_QWS_H -#define QKBDVR41XX_QWS_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_VR41XX) - -class QWSVr41xxKbPrivate; - -class QWSVr41xxKeyboardHandler : public QWSKeyboardHandler -{ -public: - explicit QWSVr41xxKeyboardHandler(const QString&); - virtual ~QWSVr41xxKeyboardHandler(); - -private: - QWSVr41xxKbPrivate *d; -}; - -#endif // QT_NO_QWS_KBD_VR41XX - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QKBDVR41XX_QWS_H diff --git a/src/gui/embedded/qkbdyopy_qws.cpp b/src/gui/embedded/qkbdyopy_qws.cpp deleted file mode 100644 index edb732c..0000000 --- a/src/gui/embedded/qkbdyopy_qws.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/* - * YOPY buttons driver - * Contributed by Ron Victorelli (victorrj at icubed.com) - */ - -#include "qkbdyopy_qws.h" - -#ifndef QT_NO_QWS_KBD_YOPY - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include // overrides QT_OPEN - -extern "C" { - int getpgid(int); -} - -#include -#include - -QT_BEGIN_NAMESPACE - -class QWSYopyKbPrivate : public QObject -{ - Q_OBJECT -public: - QWSYopyKbPrivate(QWSYopyKeyboardHandler *h, const QString&); - virtual ~QWSYopyKbPrivate(); - - bool isOpen() { return buttonFD > 0; } - -private slots: - void readKeyboardData(); - -private: - QString terminalName; - int buttonFD; - struct termios newT, oldT; - QSocketNotifier *notifier; - QWSYopyKeyboardHandler *handler; -}; - -QWSYopyKeyboardHandler::QWSYopyKeyboardHandler(const QString &device) -{ - d = new QWSYopyKbPrivate(this, device); -} - -QWSYopyKeyboardHandler::~QWSYopyKeyboardHandler() -{ - delete d; -} - -QWSYopyKbPrivate::QWSYopyKbPrivate(QWSYopyKeyboardHandler *h, const QString &device) : handler(h) -{ - terminalName = device.isEmpty()?"/dev/tty1":device.toLatin1().constData(); - buttonFD = -1; - notifier = 0; - - buttonFD = QT_OPEN(terminalName.toLatin1().constData(), O_RDWR | O_NDELAY, 0); - if (buttonFD < 0) { - qWarning("Cannot open %s\n", qPrintable(terminalName)); - return; - } else { - - tcsetpgrp(buttonFD, getpgid(0)); - - /* put tty into "straight through" mode. - */ - if (tcgetattr(buttonFD, &oldT) < 0) { - qFatal("Linux-kbd: tcgetattr failed"); - } - - newT = oldT; - newT.c_lflag &= ~(ICANON | ECHO | ISIG); - newT.c_iflag &= ~(ISTRIP | IGNCR | ICRNL | INLCR | IXOFF | IXON); - newT.c_iflag |= IGNBRK; - newT.c_cc[VMIN] = 0; - newT.c_cc[VTIME] = 0; - - - if (tcsetattr(buttonFD, TCSANOW, &newT) < 0) { - qFatal("Linux-kbd: TCSANOW tcsetattr failed"); - } - - if (ioctl(buttonFD, KDSKBMODE, K_MEDIUMRAW) < 0) { - qFatal("Linux-kbd: KDSKBMODE tcsetattr failed"); - } - - notifier = new QSocketNotifier(buttonFD, QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)),this, - SLOT(readKeyboardData())); - } -} - -QWSYopyKbPrivate::~QWSYopyKbPrivate() -{ - if (buttonFD > 0) { - ::close(buttonFD); - buttonFD = -1; - } -} - -void QWSYopyKbPrivate::readKeyboardData() -{ - uchar buf[1]; - char c='1'; - int fd; - - int n=read(buttonFD,buf,1); - if (n<0) { - qDebug("Keyboard read error %s",strerror(errno)); - } else { - uint code = buf[0]&YPBUTTON_CODE_MASK; - bool press = !(buf[0]&0x80); - // printf("Key=%d/%d/%d\n",buf[1],code,press); - int k=(-1); - switch(code) { - case 39: k=Qt::Key_Up; break; - case 44: k=Qt::Key_Down; break; - case 41: k=Qt::Key_Left; break; - case 42: k=Qt::Key_Right; break; - case 56: k=Qt::Key_F1; break; //windows - case 29: k=Qt::Key_F2; break; //cycle - case 24: k=Qt::Key_F3; break; //record - case 23: k=Qt::Key_F4; break; //mp3 - case 4: k=Qt::Key_F5; break; // PIMS - case 1: k=Qt::Key_Escape; break; // Escape - case 40: k=Qt::Key_Up; break; // prev - case 45: k=Qt::Key_Down; break; // next - case 35: if(!press) { - fd = QT_OPEN("/proc/sys/pm/sleep",O_RDWR,0); - if(fd >= 0) { - QT_WRITE(fd,&c,sizeof(c)); - QT_CLOSE(fd); - // - // Updates all widgets. - // - QWidgetList list = QApplication::allWidgets(); - for (int i = 0; i < list.size(); ++i) { - QWidget *w = list.at(i); - w->update(); - } - } - } - break; - - default: k=(-1); break; - } - - if (k >= 0) { - handler->processKeyEvent(0, k, 0, press, false); - } - } -} - -QT_END_NAMESPACE - -#include "qkbdyopy_qws.moc" - -#endif // QT_NO_QWS_KBD_YOPY diff --git a/src/gui/embedded/qkbdyopy_qws.h b/src/gui/embedded/qkbdyopy_qws.h deleted file mode 100644 index b4e45bd..0000000 --- a/src/gui/embedded/qkbdyopy_qws.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QKBDYOPY_QWS_H -#define QKBDYOPY_QWS_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_QWS_KBD_YOPY - -class QWSYopyKbPrivate; - -class QWSYopyKeyboardHandler : public QWSKeyboardHandler -{ -public: - explicit QWSYopyKeyboardHandler(const QString&); - virtual ~QWSYopyKeyboardHandler(); - -private: - QWSYopyKbPrivate *d; -}; - -#endif // QT_NO_QWS_KBD_YOPY - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QKBDYOPY_QWS_H diff --git a/src/gui/embedded/qmousebus_qws.cpp b/src/gui/embedded/qmousebus_qws.cpp deleted file mode 100644 index 0b674b6..0000000 --- a/src/gui/embedded/qmousebus_qws.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmousebus_qws.h" - -#ifndef QT_NO_QWS_MOUSE_BUS - -#include "qwindowsystem_qws.h" -#include "qsocketnotifier.h" - -#include "qapplication.h" -#include // overrides QT_OPEN - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -/* - * bus mouse driver (a.k.a. Logitech busmouse) - */ - -class QWSBusMouseHandlerPrivate : public QObject -{ - Q_OBJECT -public: - QWSBusMouseHandlerPrivate(QWSBusMouseHandler *h, const QString &driver, const QString &device); - ~QWSBusMouseHandlerPrivate(); - - void suspend(); - void resume(); - -private slots: - void readMouseData(); - -protected: - enum { mouseBufSize = 128 }; - QWSBusMouseHandler *handler; - QSocketNotifier *mouseNotifier; - int mouseFD; - int mouseIdx; - int obstate; - uchar mouseBuf[mouseBufSize]; -}; - -QWSBusMouseHandler::QWSBusMouseHandler(const QString &driver, const QString &device) - : QWSMouseHandler(driver, device) -{ - d = new QWSBusMouseHandlerPrivate(this, driver, device); -} - -QWSBusMouseHandler::~QWSBusMouseHandler() -{ - delete d; -} - -void QWSBusMouseHandler::suspend() -{ - d->suspend(); -} - -void QWSBusMouseHandler::resume() -{ - d->resume(); -} - - -QWSBusMouseHandlerPrivate::QWSBusMouseHandlerPrivate(QWSBusMouseHandler *h, - const QString &, const QString &device) - : handler(h) - -{ - QString mouseDev = device; - if (mouseDev.isEmpty()) - mouseDev = QLatin1String("/dev/mouse"); - obstate = -1; - mouseFD = -1; - mouseFD = QT_OPEN(mouseDev.toLocal8Bit(), O_RDWR | O_NDELAY); - if (mouseFD < 0) - mouseFD = QT_OPEN(mouseDev.toLocal8Bit(), O_RDONLY | O_NDELAY); - if (mouseFD < 0) - qDebug("Cannot open %s (%s)", qPrintable(mouseDev), strerror(errno)); - - // Clear pending input - tcflush(mouseFD,TCIFLUSH); - usleep(50000); - - char buf[100]; // busmouse driver will not read if bufsize < 3, YYD - while (QT_READ(mouseFD, buf, 100) > 0) { } // eat unwanted replies - - mouseIdx = 0; - - mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this); - connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); -} - -QWSBusMouseHandlerPrivate::~QWSBusMouseHandlerPrivate() -{ - if (mouseFD >= 0) { - tcflush(mouseFD,TCIFLUSH); // yyd. - QT_CLOSE(mouseFD); - } -} - - -void QWSBusMouseHandlerPrivate::suspend() -{ - mouseNotifier->setEnabled(false); -} - - -void QWSBusMouseHandlerPrivate::resume() -{ - mouseIdx = 0; - obstate = -1; - mouseNotifier->setEnabled(true); -} - -void QWSBusMouseHandlerPrivate::readMouseData() -{ - int n; - // It'll only read 3 bytes a time and return all other buffer zeroed, thus cause protocol errors - for (;;) { - if (mouseBufSize - mouseIdx < 3) - break; - n = QT_READ(mouseFD, mouseBuf+mouseIdx, 3); - if (n != 3) - break; - mouseIdx += 3; - } - - static const int accel_limit = 5; - static const int accel = 2; - - int idx = 0; - int bstate = 0; - int dx = 0, dy = 0; - bool sendEvent = false; - int tdx = 0, tdy = 0; - - while (mouseIdx-idx >= 3) { -#if 0 // debug - qDebug("Got mouse data"); -#endif - uchar *mb = mouseBuf+idx; - bstate = 0; - dx = 0; - dy = 0; - sendEvent = false; - if (((mb[0] & 0x04))) - bstate |= Qt::LeftButton; - if (((mb[0] & 0x01))) - bstate |= Qt::RightButton; - - dx=(signed char)mb[1]; - dy=(signed char)mb[2]; - sendEvent=true; - - if (sendEvent) { - if (qAbs(dx) > accel_limit || qAbs(dy) > accel_limit) { - dx *= accel; - dy *= accel; - } - tdx += dx; - tdy += dy; - if (bstate != obstate) { - QPoint pos = handler->pos() + QPoint(tdx,-tdy); - handler->limitToScreen(pos); - handler->mouseChanged(pos,bstate); - sendEvent = false; - tdx = 0; - tdy = 0; - obstate = bstate; - } - } - idx += 3; - } - if (sendEvent) { - QPoint pos = handler->pos() + QPoint(tdx,-tdy); - handler->limitToScreen(pos); - handler->mouseChanged(pos,bstate); - } - - int surplus = mouseIdx - idx; - for (int i = 0; i < surplus; i++) - mouseBuf[i] = mouseBuf[idx+i]; - mouseIdx = surplus; -} - -QT_END_NAMESPACE - -#include "qmousebus_qws.moc" - -#endif // QT_NO_QWS_MOUSE_BUS diff --git a/src/gui/embedded/qmousebus_qws.h b/src/gui/embedded/qmousebus_qws.h deleted file mode 100644 index 407da98..0000000 --- a/src/gui/embedded/qmousebus_qws.h +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMOUSEBUS_QWS_H -#define QMOUSEBUS_QWS_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_QWS_MOUSE_BUS - -class QWSBusMouseHandlerPrivate; - -class QWSBusMouseHandler : public QWSMouseHandler -{ -public: - explicit QWSBusMouseHandler(const QString & = QString(), - const QString & = QString()); - ~QWSBusMouseHandler(); - - void suspend(); - void resume(); -protected: - QWSBusMouseHandlerPrivate *d; -}; - -#endif // QT_NO_QWS_MOUSE_BUS - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QMOUSEBUS_QWS_H diff --git a/src/gui/embedded/qmousedriverfactory_qws.cpp b/src/gui/embedded/qmousedriverfactory_qws.cpp index 7e51818..46898ae 100644 --- a/src/gui/embedded/qmousedriverfactory_qws.cpp +++ b/src/gui/embedded/qmousedriverfactory_qws.cpp @@ -43,10 +43,8 @@ #include "qapplication.h" #include "qmousepc_qws.h" -#include "qmousebus_qws.h" -#include "qmousevr41xx_qws.h" -#include "qmouseyopy_qws.h" #include "qmouselinuxtp_qws.h" +#include "qmouselinuxinput_qws.h" #include "qmousevfb_qws.h" #include "qmousetslib_qws.h" #include @@ -108,14 +106,6 @@ QWSMouseHandler *QMouseDriverFactory::create(const QString& key, const QString & if (driver == QLatin1String("linuxtp") || driver.isEmpty()) return new QWSLinuxTPMouseHandler(key, device); #endif -#ifndef QT_NO_QWS_MOUSE_YOPY - if (driver == QLatin1String("yopy") || driver.isEmpty()) - return new QWSYopyMouseHandler(key, device); -#endif -#ifndef QT_NO_QWS_MOUSE_VR41XX - if (driver == QLatin1String("vr41xx") || driver.isEmpty()) - return new QWSVr41xxMouseHandler(key, device); -#endif #ifndef QT_NO_QWS_MOUSE_PC if (driver == QLatin1String("auto") || driver == QLatin1String("intellimouse") @@ -126,14 +116,16 @@ QWSMouseHandler *QMouseDriverFactory::create(const QString& key, const QString & return new QWSPcMouseHandler(key, device); } #endif -#ifndef QT_NO_QWS_MOUSE_BUS - if (driver == QLatin1String("bus")) - return new QWSBusMouseHandler(key, device); -#endif #ifndef QT_NO_QWS_MOUSE_TSLIB if (driver == QLatin1String("tslib") || driver.isEmpty()) return new QWSTslibMouseHandler(key, device); #endif +# ifndef QT_NO_QWS_MOUSE_LINUXINPUT + if (driver == QLatin1String("linuxinput") || \ + driver == QLatin1String("usb") || \ + driver == QLatin1String("linuxis")) + return new QWSLinuxInputMouseHandler(device); +# endif #ifndef QT_NO_QWS_MOUSE_QVFB if (driver == QLatin1String("qvfbmouse") || driver == QLatin1String("qvfb")) return new QVFbMouseHandler(key, device); @@ -160,12 +152,6 @@ QStringList QMouseDriverFactory::keys() #ifndef QT_NO_QWS_MOUSE_LINUXTP list << QLatin1String("LinuxTP"); #endif -#ifndef QT_NO_QWS_MOUSE_YOPY - list << QLatin1String("Yopy"); -#endif -#ifndef QT_NO_QWS_MOUSE_VR41XX - list << QLatin1String("VR41xx"); -#endif #ifndef QT_NO_QWS_MOUSE_PC list << QLatin1String("Auto") << QLatin1String("IntelliMouse") @@ -173,12 +159,12 @@ QStringList QMouseDriverFactory::keys() << QLatin1String("MouseSystems") << QLatin1String("MouseMan"); #endif -#ifndef QT_NO_QWS_MOUSE_BUS - list << QLatin1String("Bus"); -#endif #ifndef QT_NO_QWS_MOUSE_TSLIB list << QLatin1String("Tslib"); #endif +#ifndef QT_NO_QWS_MOUSE_LINUXINPUT + list << QLatin1String("LinuxInput"); +#endif #if !defined(Q_OS_WIN32) || defined(QT_MAKEDLL) #ifndef QT_NO_LIBRARY diff --git a/src/gui/embedded/qmouselinuxinput_qws.cpp b/src/gui/embedded/qmouselinuxinput_qws.cpp new file mode 100644 index 0000000..6ea8807 --- /dev/null +++ b/src/gui/embedded/qmouselinuxinput_qws.cpp @@ -0,0 +1,205 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmouselinuxinput_qws.h" + +#include +#include + +#include +#include // overrides QT_OPEN + +#include + +#include + +QT_BEGIN_NAMESPACE + + +class QWSLinuxInputMousePrivate : public QObject +{ + Q_OBJECT +public: + QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *, const QString &); + ~QWSLinuxInputMousePrivate(); + + void enable(bool on); + +private Q_SLOTS: + void readMouseData(); + +private: + QWSLinuxInputMouseHandler *m_handler; + QSocketNotifier * m_notify; + int m_fd; + int m_x, m_y; + int m_buttons; +}; + +QWSLinuxInputMouseHandler::QWSLinuxInputMouseHandler(const QString &device) + : QWSCalibratedMouseHandler(device) +{ + d = new QWSLinuxInputMousePrivate(this, device); +} + +QWSLinuxInputMouseHandler::~QWSLinuxInputMouseHandler() +{ + delete d; +} + +void QWSLinuxInputMouseHandler::suspend() +{ + d->enable(false); +} + +void QWSLinuxInputMouseHandler::resume() +{ + d->enable(true); +} + +QWSLinuxInputMousePrivate::QWSLinuxInputMousePrivate(QWSLinuxInputMouseHandler *h, const QString &device) + : m_handler(h), m_notify(0), m_x(0), m_y(0), m_buttons(0) +{ + setObjectName(QLatin1String("LinuxInputSubsystem Mouse Handler")); + + QString dev = QLatin1String("/dev/input/event0"); + if (device.startsWith(QLatin1String("/dev/"))) + dev = device; + + m_fd = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY | O_NDELAY, 0); + if (m_fd >= 0) { + m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); + } else { + qWarning("Cannot open mouse input device '%s': %s", qPrintable(dev), strerror(errno)); + return; + } +} + +QWSLinuxInputMousePrivate::~QWSLinuxInputMousePrivate() +{ + if (m_fd >= 0) + QT_CLOSE(m_fd); +} + +void QWSLinuxInputMousePrivate::enable(bool on) +{ + if (m_notify) + m_notify->setEnabled(on); +} + +void QWSLinuxInputMousePrivate::readMouseData() +{ + if (!qt_screen) + return; + + struct ::input_event buffer[32]; + int n = 0; + + forever { + n = QT_READ(m_fd, reinterpret_cast(buffer) + n, sizeof(buffer) - n); + + if (n == 0) { + qWarning("Got EOF from the input device."); + return; + } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) { + qWarning("Could not read from input device: %s", strerror(errno)); + return; + } else if (n % sizeof(buffer[0]) == 0) { + break; + } + } + + n /= sizeof(buffer[0]); + + for (int i = 0; i < n; ++i) { + struct ::input_event *data = &buffer[i]; + + bool unknown = false; + if (data->type == EV_ABS) { + if (data->code == ABS_X) { + m_x = data->value; + } else if (data->code == ABS_Y) { + m_y = data->value; + } else { + unknown = true; + } + } else if (data->type == EV_REL) { + if (data->code == REL_X) { + m_x += data->value; + } else if (data->code == REL_Y) { + m_y += data->value; + } else { + unknown = true; + } + } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { + m_buttons = data->value ? Qt::LeftButton : 0; + } else if (data->type == EV_KEY) { + int button = 0; + switch (data->code) { + case BTN_LEFT: button = Qt::LeftButton; break; + case BTN_MIDDLE: button = Qt::MidButton; break; + case BTN_RIGHT: button = Qt::RightButton; break; + } + if (data->value) + m_buttons |= button; + else + m_buttons &= ~button; + } else if (data->type == EV_SYN && data->code == SYN_REPORT) { + QPoint pos(m_x, m_y); + pos = m_handler->transform(pos); + m_handler->limitToScreen(pos); + m_handler->mouseChanged(pos, m_buttons); + } else if (data->type == EV_MSC && data->code == MSC_SCAN) { + // kernel encountered an unmapped key - just ignore it + continue; + } else { + unknown = true; + } + if (unknown) { + qWarning("unknown mouse event type=%x, code=%x, value=%x", data->type, data->code, data->value); + } + } +} + +QT_END_NAMESPACE + +#include "qmouselinuxinput_qws.moc" diff --git a/src/gui/embedded/qmouselinuxinput_qws.h b/src/gui/embedded/qmouselinuxinput_qws.h new file mode 100644 index 0000000..25e351f --- /dev/null +++ b/src/gui/embedded/qmouselinuxinput_qws.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMOUSELINUXINPUT_QWS_H +#define QMOUSELINUXINPUT_QWS_H + +#include + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +#ifndef QT_NO_QWS_MOUSE_LINUXINPUT + +class QWSLinuxInputMousePrivate; + +class QWSLinuxInputMouseHandler : public QWSCalibratedMouseHandler +{ +public: + QWSLinuxInputMouseHandler(const QString &); + ~QWSLinuxInputMouseHandler(); + + void suspend(); + void resume(); + +private: + QWSLinuxInputMousePrivate *d; + + friend class QWSLinuxInputMousePrivate; +}; + +#endif // QT_NO_QWS_MOUSE_LINUXINPUT + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMOUSELINUXINPUT_QWS_H diff --git a/src/gui/embedded/qmousevr41xx_qws.cpp b/src/gui/embedded/qmousevr41xx_qws.cpp deleted file mode 100644 index b7491d9..0000000 --- a/src/gui/embedded/qmousevr41xx_qws.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmousevr41xx_qws.h" - -#ifndef QT_NO_QWS_MOUSE_VR41XX -#include "qwindowsystem_qws.h" -#include "qsocketnotifier.h" -#include "qtimer.h" -#include "qapplication.h" -#include "qscreen_qws.h" -#include -#include -#include // overrides QT_OPEN - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -static const int defaultFilterSize = 3; - -class QWSVr41xxMouseHandlerPrivate : public QObject -{ - Q_OBJECT -public: - QWSVr41xxMouseHandlerPrivate(QWSVr41xxMouseHandler *, const QString &, const QString &); - ~QWSVr41xxMouseHandlerPrivate(); - - void resume(); - void suspend(); - -private slots: - void sendRelease(); - void readMouseData(); - -private: - bool getSample(); - ushort currSample[6]; - uint currLength; - - int mouseFD; - int mouseIdx; - QTimer *rtimer; - QSocketNotifier *mouseNotifier; - QWSVr41xxMouseHandler *handler; - QPoint lastPos; - bool isPressed; - int filterSize; - int pressLimit; -}; - -QWSVr41xxMouseHandler::QWSVr41xxMouseHandler(const QString &drv, const QString &dev) - : QWSCalibratedMouseHandler(drv, dev) -{ - d = new QWSVr41xxMouseHandlerPrivate(this, drv, dev); -} - -QWSVr41xxMouseHandler::~QWSVr41xxMouseHandler() -{ - delete d; -} - -void QWSVr41xxMouseHandler::resume() -{ - d->resume(); -} - -void QWSVr41xxMouseHandler::suspend() -{ - d->suspend(); -} - -QWSVr41xxMouseHandlerPrivate::QWSVr41xxMouseHandlerPrivate(QWSVr41xxMouseHandler *h, const QString &, const QString &device) - : currLength(0), handler(h) -{ - QStringList options = device.split(QLatin1String(":")); - int index = -1; - - filterSize = defaultFilterSize; - QRegExp filterRegExp(QLatin1String("filter=(\\d+)")); - index = options.indexOf(filterRegExp); - if (index != -1) { - filterSize = qMax(1, filterRegExp.cap(1).toInt()); - options.removeAt(index); - } - handler->setFilterSize(filterSize); - - pressLimit = 750; - QRegExp pressRegExp(QLatin1String("press=(\\d+)")); - index = options.indexOf(pressRegExp); - if (index != -1) { - pressLimit = filterRegExp.cap(1).toInt(); - options.removeAt(index); - } - - QString dev; - if (options.isEmpty()) - dev = QLatin1String("/dev/vrtpanel"); - else - dev = options.first(); - - if ((mouseFD = QT_OPEN(dev.toLocal8Bit().constData(), O_RDONLY)) < 0) { - qWarning("Cannot open %s (%s)", qPrintable(dev), strerror(errno)); - return; - } - sleep(1); - - if (fcntl(mouseFD, F_SETFL, O_NONBLOCK) < 0) { - qWarning("Error initializing touch panel."); - return; - } - - mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this); - connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); - - rtimer = new QTimer(this); - rtimer->setSingleShot(true); - connect(rtimer, SIGNAL(timeout()), this, SLOT(sendRelease())); - mouseIdx = 0; -} - -QWSVr41xxMouseHandlerPrivate::~QWSVr41xxMouseHandlerPrivate() -{ - if (mouseFD >= 0) - QT_CLOSE(mouseFD); -} - -void QWSVr41xxMouseHandlerPrivate::suspend() -{ - mouseNotifier->setEnabled(false); -} - - -void QWSVr41xxMouseHandlerPrivate::resume() -{ - mouseIdx = 0; - mouseNotifier->setEnabled(true); -} - -void QWSVr41xxMouseHandlerPrivate::sendRelease() -{ - handler->sendFiltered(lastPos, Qt::NoButton); - isPressed = false; -} - -bool QWSVr41xxMouseHandlerPrivate::getSample() -{ - const int n = QT_READ(mouseFD, - reinterpret_cast(currSample) + currLength, - sizeof(currSample) - currLength); - - if (n > 0) - currLength += n; - - if (currLength < sizeof(currSample)) - return false; - - currLength = 0; - return true; -} - -void QWSVr41xxMouseHandlerPrivate::readMouseData() -{ - const int sampleLength = sizeof(currSample) / sizeof(ushort); - QVarLengthArray samples(sampleLength * filterSize); - - // Only return last 'filterSize' samples - int head = 0; - int tail = 0; - int nSamples = 0; - while (getSample()) { - if (!(currSample[0] & 0x8000) || (currSample[5] < pressLimit)) - continue; - - ushort *data = samples.data() + head * sampleLength; - memcpy(data, currSample, sizeof(currSample)); - ++nSamples; - head = (head + 1) % filterSize; - if (nSamples >= filterSize) - tail = (tail + 1) % filterSize; - } - - if (nSamples == 0) - return; - - // send mouse events - while (tail != head || filterSize == 1) { - const ushort *data = samples.data() + tail * sampleLength; - lastPos = QPoint(data[3] - data[4], data[2] - data[1]); - handler->sendFiltered(lastPos, Qt::LeftButton); - isPressed = true; - tail = (tail + 1) % filterSize; - if (filterSize == 1) - break; - } - - if (isPressed) - rtimer->start(50); // release unreliable -} - -QT_END_NAMESPACE - -#include "qmousevr41xx_qws.moc" - -#endif //QT_NO_QWS_MOUSE_VR41 diff --git a/src/gui/embedded/qmousevr41xx_qws.h b/src/gui/embedded/qmousevr41xx_qws.h deleted file mode 100644 index 46d07e0..0000000 --- a/src/gui/embedded/qmousevr41xx_qws.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMOUSEVR41XX_QWS_H -#define QMOUSEVR41XX_QWS_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_QWS_MOUSE_VR41XX - -class QWSVr41xxMouseHandlerPrivate; - -class QWSVr41xxMouseHandler : public QWSCalibratedMouseHandler -{ -public: - explicit QWSVr41xxMouseHandler(const QString & = QString(), - const QString & = QString()); - ~QWSVr41xxMouseHandler(); - - void resume(); - void suspend(); - -protected: - QWSVr41xxMouseHandlerPrivate *d; - -private: - friend class QWSVr41xxMouseHandlerPrivate; -}; - -#endif // QT_NO_QWS_MOUSE_VR41XX - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QMOUSEVR41XX_QWS_H diff --git a/src/gui/embedded/qmouseyopy_qws.cpp b/src/gui/embedded/qmouseyopy_qws.cpp deleted file mode 100644 index 3a541d3..0000000 --- a/src/gui/embedded/qmouseyopy_qws.cpp +++ /dev/null @@ -1,185 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qmouseyopy_qws.h" - -#ifndef QT_NO_QWS_MOUSE_YOPY -#include "qwindowsystem_qws.h" -#include "qsocketnotifier.h" -#include "qapplication.h" -#include "qscreen_qws.h" -#include // overrides QT_OPEN - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QWSYopyMouseHandlerPrivate : public QObject -{ - Q_OBJECT -public: - QWSYopyMouseHandlerPrivate(QWSYopyMouseHandler *h); - ~QWSYopyMouseHandlerPrivate(); - - void suspend(); - void resume(); - -private slots: - void readMouseData(); - -private: - int mouseFD; - int prevstate; - QSocketNotifier *mouseNotifier; - QWSYopyMouseHandler *handler; -}; - -QWSYopyMouseHandler::QWSYopyMouseHandler(const QString &driver, const QString &device) - : QWSMouseHandler(driver, device) -{ - d = new QWSYopyMouseHandlerPrivate(this); -} - -QWSYopyMouseHandler::~QWSYopyMouseHandler() -{ - delete d; -} - -void QWSYopyMouseHandler::resume() -{ - d->resume(); -} - -void QWSYopyMouseHandler::suspend() -{ - d->suspend(); -} - -QWSYopyMouseHandlerPrivate::QWSYopyMouseHandlerPrivate(QWSYopyMouseHandler *h) - : handler(h) -{ - if ((mouseFD = QT_OPEN("/dev/ts", O_RDONLY)) < 0) { - qWarning("Cannot open /dev/ts (%s)", strerror(errno)); - return; - } else { - sleep(1); - } - prevstate=0; - mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, - this); - connect(mouseNotifier, SIGNAL(activated(int)),this, SLOT(readMouseData())); -} - -QWSYopyMouseHandlerPrivate::~QWSYopyMouseHandlerPrivate() -{ - if (mouseFD >= 0) - QT_CLOSE(mouseFD); -} - -#define YOPY_XPOS(d) (d[1]&0x3FF) -#define YOPY_YPOS(d) (d[2]&0x3FF) -#define YOPY_PRES(d) (d[0]&0xFF) -#define YOPY_STAT(d) (d[3]&0x01) - -struct YopyTPdata { - - unsigned char status; - unsigned short xpos; - unsigned short ypos; - -}; - -void QWSYopyMouseHandlerPrivate::suspend() -{ - mouseNotifier->setEnabled(false); -} - - -void QWSYopyMouseHandlerPrivate::resume() -{ - prevstate = 0; - mouseNotifier->setEnabled(true); -} - -void QWSYopyMouseHandlerPrivate::readMouseData() -{ - if(!qt_screen) - return; - YopyTPdata data; - - unsigned int yopDat[4]; - - int ret; - - ret=QT_READ(mouseFD,&yopDat,sizeof(yopDat)); - - if(ret) { - data.status= (YOPY_PRES(yopDat)) ? 1 : 0; - data.xpos=YOPY_XPOS(yopDat); - data.ypos=YOPY_YPOS(yopDat); - QPoint q; - q.setX(data.xpos); - q.setY(data.ypos); - if (data.status && !prevstate) { - handler->mouseChanged(q,Qt::LeftButton); - } else if(!data.status && prevstate) { - handler->mouseChanged(q,0); - } - prevstate = data.status; - } - if(ret<0) { - qDebug("Error %s",strerror(errno)); - } -} - -QT_END_NAMESPACE - -#include "qmouseyopy_qws.moc" - -#endif //QT_NO_QWS_MOUSE_YOPY diff --git a/src/gui/embedded/qmouseyopy_qws.h b/src/gui/embedded/qmouseyopy_qws.h deleted file mode 100644 index 0d24a8f..0000000 --- a/src/gui/embedded/qmouseyopy_qws.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMOUSEYOPY_QWS_H -#define QMOUSEYOPY_QWS_H - -#include - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -#ifndef QT_NO_QWS_MOUSE_YOPY - -// YOPY touch panel support based on changes contributed by Ron Victorelli -// (victorrj at icubed.com) to Custom TP driver. - -class QWSYopyMouseHandlerPrivate; - -class QWSYopyMouseHandler : public QWSMouseHandler -{ -public: - explicit QWSYopyMouseHandler(const QString & = QString(), - const QString & = QString()); - ~QWSYopyMouseHandler(); - - void resume(); - void suspend(); - -protected: - QWSYopyMouseHandlerPrivate *d; -}; - -#endif // QT_NO_QWS_MOUSE_YOPY - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QMOUSEYOPY_QWS_H diff --git a/src/plugins/kbddrivers/kbddrivers.pro b/src/plugins/kbddrivers/kbddrivers.pro index a34b780..dbab47b 100644 --- a/src/plugins/kbddrivers/kbddrivers.pro +++ b/src/plugins/kbddrivers/kbddrivers.pro @@ -1,5 +1,2 @@ TEMPLATE = subdirs contains(kbd-plugins, linuxinput): SUBDIRS += linuxinput -contains(kbd-plugins, sl5000): SUBDIRS += sl5000 -contains(kbd-plugins, vr41xx): SUBDIRS += vr41xx -contains(kbd-plugins, yopy): SUBDIRS += yopy diff --git a/src/plugins/kbddrivers/sl5000/main.cpp b/src/plugins/kbddrivers/sl5000/main.cpp deleted file mode 100644 index cc68747..0000000 --- a/src/plugins/kbddrivers/sl5000/main.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE - -class QSL5000KbdDriver : public QKbdDriverPlugin -{ -public: - QSL5000KbdDriver(); - - QStringList keys() const; - QWSKeyboardHandler* create(const QString &driver, const QString &device); -}; - -QSL5000KbdDriver::QSL5000KbdDriver() - : QKbdDriverPlugin() -{ -} - -QStringList QSL5000KbdDriver::keys() const -{ - return (QStringList() << QLatin1String("SL5000")); -} - -QWSKeyboardHandler* QSL5000KbdDriver::create(const QString &driver, - const QString &device) -{ - if (driver.compare(QLatin1String("SL5000"), Qt::CaseInsensitive)) - return 0; - return new QWSSL5000KeyboardHandler(device); -} - -Q_EXPORT_PLUGIN2(qwssl5000kbddriver, QSL5000KbdDriver) - -QT_END_NAMESPACE diff --git a/src/plugins/kbddrivers/sl5000/sl5000.pro b/src/plugins/kbddrivers/sl5000/sl5000.pro deleted file mode 100644 index e52cf0d..0000000 --- a/src/plugins/kbddrivers/sl5000/sl5000.pro +++ /dev/null @@ -1,16 +0,0 @@ -TARGET = qsl5000kbddriver -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/kbddrivers -target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers -INSTALLS += target - -DEFINES += QT_QWS_KBD_SL5000 QT_QWS_KBD_TTY - -HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qkbdsl5000_qws.h \ - $$QT_SOURCE_TREE/src/gui/embedded/qkbdtty_qws.h - -SOURCES = main.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qkbdsl5000_qws.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qkbdtty_qws.cpp - diff --git a/src/plugins/kbddrivers/vr41xx/main.cpp b/src/plugins/kbddrivers/vr41xx/main.cpp deleted file mode 100644 index c9ba4d7..0000000 --- a/src/plugins/kbddrivers/vr41xx/main.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE - -class QVr41xxKbdDriver : public QKbdDriverPlugin -{ -public: - QVr41xxKbdDriver(); - - QStringList keys() const; - QWSKeyboardHandler* create(const QString &driver, const QString &device); -}; - -QVr41xxKbdDriver::QVr41xxKbdDriver() - : QKbdDriverPlugin() -{ -} - -QStringList QVr41xxKbdDriver::keys() const -{ - return (QStringList() << QLatin1String("VR41xx")); -} - -QWSKeyboardHandler* QVr41xxKbdDriver::create(const QString &driver, - const QString &device) -{ - if (driver.compare(QLatin1String("VR41xx"), Qt::CaseInsensitive)) - return 0; - return new QWSVr41xxKeyboardHandler(device); -} - -Q_EXPORT_PLUGIN2(qwsvr41xxkbddriver, QVr41xxKbdDriver) - -QT_END_NAMESPACE diff --git a/src/plugins/kbddrivers/vr41xx/vr41xx.pro b/src/plugins/kbddrivers/vr41xx/vr41xx.pro deleted file mode 100644 index f9f103f..0000000 --- a/src/plugins/kbddrivers/vr41xx/vr41xx.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qvr41xxkbddriver -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/kbddrivers -target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers -INSTALLS += target - -DEFINES += QT_QWS_KBD_VR41XX - -HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qkbdvr41xx_qws.h - -SOURCES = main.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qkbdvr41xx_qws.cpp - diff --git a/src/plugins/kbddrivers/yopy/main.cpp b/src/plugins/kbddrivers/yopy/main.cpp deleted file mode 100644 index 7079d88..0000000 --- a/src/plugins/kbddrivers/yopy/main.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE - -class QYopyKbdDriver : public QKbdDriverPlugin -{ -public: - QYopyKbdDriver(); - - QStringList keys() const; - QWSKeyboardHandler* create(const QString &driver, const QString &device); -}; - -QYopyKbdDriver::QYopyKbdDriver() - : QKbdDriverPlugin() -{ -} - -QStringList QYopyKbdDriver::keys() const -{ - return (QStringList() << QLatin1String("Yopy")); -} - -QWSKeyboardHandler* QYopyKbdDriver::create(const QString &driver, - const QString &device) -{ - if (driver.compare(QLatin1String("Yopy"), Qt::CaseInsensitive)) - return 0; - return new QWSYopyKeyboardHandler(device); -} - -Q_EXPORT_PLUGIN2(qwsyopykbddriver, QYopyKbdDriver) - -QT_END_NAMESPACE diff --git a/src/plugins/kbddrivers/yopy/yopy.pro b/src/plugins/kbddrivers/yopy/yopy.pro deleted file mode 100644 index 66a663c..0000000 --- a/src/plugins/kbddrivers/yopy/yopy.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qyopykbddriver -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/kbddrivers -target.path = $$[QT_INSTALL_PLUGINS]/kbddrivers -INSTALLS += target - -DEFINES += QT_QWS_KBD_YOPY - -HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qkbdyopy_qws.h - -SOURCES = main.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qkbdyopy_qws.cpp - diff --git a/src/plugins/mousedrivers/bus/bus.pro b/src/plugins/mousedrivers/bus/bus.pro deleted file mode 100644 index cdb0332..0000000 --- a/src/plugins/mousedrivers/bus/bus.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qbusmousedriver -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mousedrivers -target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers -INSTALLS += target - -DEFINES += QT_QWS_MOUSE_BUS - -HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qmousebus_qws.h - -SOURCES = main.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qmousebus_qws.cpp - diff --git a/src/plugins/mousedrivers/bus/main.cpp b/src/plugins/mousedrivers/bus/main.cpp deleted file mode 100644 index f56c890..0000000 --- a/src/plugins/mousedrivers/bus/main.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE - -class QBusMouseDriver : public QMouseDriverPlugin -{ -public: - QBusMouseDriver(); - - QStringList keys() const; - QWSMouseHandler* create(const QString &driver, const QString &device); -}; - -QBusMouseDriver::QBusMouseDriver() - : QMouseDriverPlugin() -{ -} - -QStringList QBusMouseDriver::keys() const -{ - return (QStringList() << "Bus"); -} - -QWSMouseHandler* QBusMouseDriver::create(const QString &driver, - const QString &device) -{ - if (driver.compare(QLatin1String("Bus"), Qt::CaseInsensitive)) - return 0; - return new QWSBusMouseHandler(driver, device); -} - -Q_EXPORT_PLUGIN2(qwsbusmousehandler, QBusMouseDriver) - -QT_END_NAMESPACE diff --git a/src/plugins/mousedrivers/linuxis/linuxis.pro b/src/plugins/mousedrivers/linuxis/linuxis.pro deleted file mode 100644 index bcc209b..0000000 --- a/src/plugins/mousedrivers/linuxis/linuxis.pro +++ /dev/null @@ -1,10 +0,0 @@ -TARGET = linuxismousehandler -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mousedrivers -target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers -INSTALLS += target - -HEADERS = linuxismousedriverplugin.h linuxismousehandler.h -SOURCES = linuxismousedriverplugin.cpp linuxismousehandler.cpp - diff --git a/src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.cpp b/src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.cpp deleted file mode 100644 index 4d530d9..0000000 --- a/src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.cpp +++ /dev/null @@ -1,83 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "linuxismousedriverplugin.h" -#include "linuxismousehandler.h" - -#include -#if 1 -#define qLog(x) qDebug() -#else -#define qLog(x) while (0) qDebug() -#endif -LinuxInputSubsystemMouseDriverPlugin::LinuxInputSubsystemMouseDriverPlugin( QObject *parent ) - : QMouseDriverPlugin( parent ) -{ -} - -LinuxInputSubsystemMouseDriverPlugin::~LinuxInputSubsystemMouseDriverPlugin() -{ -} - -QWSMouseHandler* LinuxInputSubsystemMouseDriverPlugin::create(const QString& driver, const QString& device) -{ - if ( driver.toLower() == "linuxis" ) { - qLog(Input) << "Before call LinuxInputSubsystemMouseHandler()"; - return new LinuxInputSubsystemMouseHandler(device); - } - return 0; -} - -QWSMouseHandler* LinuxInputSubsystemMouseDriverPlugin::create(const QString& driver) -{ - if( driver.toLower() == "linuxis" ) { - qLog(Input) << "Before call LinuxInputSubsystemMouseHandler()"; - return new LinuxInputSubsystemMouseHandler(); - } - return 0; -} - -QStringList LinuxInputSubsystemMouseDriverPlugin::keys() const -{ - return QStringList() << "linuxis"; -} - -Q_EXPORT_PLUGIN2(qwslinuxismousehandler, LinuxInputSubsystemMouseDriverPlugin) diff --git a/src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.h b/src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.h deleted file mode 100644 index 57759c5..0000000 --- a/src/plugins/mousedrivers/linuxis/linuxismousedriverplugin.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LINUXISMOUSEDRIVERPLUGIN_H -#define LINUXISMOUSEDRIVERPLUGIN_H - -#include - -class LinuxInputSubsystemMouseDriverPlugin : public QMouseDriverPlugin { - Q_OBJECT -public: - LinuxInputSubsystemMouseDriverPlugin( QObject *parent = 0 ); - ~LinuxInputSubsystemMouseDriverPlugin(); - - QWSMouseHandler* create(const QString& driver); - QWSMouseHandler* create(const QString& driver, const QString& device); - QStringList keys()const; -}; - -#endif // LINUXISMOUSEDRIVERPLUGIN_H diff --git a/src/plugins/mousedrivers/linuxis/linuxismousehandler.cpp b/src/plugins/mousedrivers/linuxis/linuxismousehandler.cpp deleted file mode 100644 index aaa6eae..0000000 --- a/src/plugins/mousedrivers/linuxis/linuxismousehandler.cpp +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "linuxismousehandler.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include - - -#if 1 -#define qLog(x) qDebug() -#else -#define qLog(x) while (0) qDebug() -#endif - - -// sanity check values of the range of possible mouse positions -#define MOUSE_SAMPLE_MIN 0 -#define MOUSE_SAMPLE_MAX 2000 - -LinuxInputSubsystemMouseHandler::LinuxInputSubsystemMouseHandler(const QString &device) - : mouseX(0), mouseY(0), mouseBtn(0), mouseIdx(0) -{ - qLog(Input) << "Loaded LinuxInputSubsystem touchscreen plugin!"; - setObjectName("LinuxInputSubsystem Mouse Handler"); - mouseFd = ::open(device.toLocal8Bit().constData(), O_RDONLY | O_NDELAY); - // mouseFd = ::open(device.toLocal8Bit().constData(), O_RDONLY); - if (mouseFd >= 0) { - qLog(Input) << "Opened" << device << "as touchscreen input"; - m_notify = new QSocketNotifier(mouseFd, QSocketNotifier::Read, this); - connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); - } else { - qWarning("Cannot open %s for touchscreen input (%s)", - device.toLocal8Bit().constData(), strerror(errno)); - return; - } -} - -LinuxInputSubsystemMouseHandler::~LinuxInputSubsystemMouseHandler() -{ - if (mouseFd >= 0) - ::close(mouseFd); -} - -void LinuxInputSubsystemMouseHandler::suspend() -{ - m_notify->setEnabled( false ); -} - -void LinuxInputSubsystemMouseHandler::resume() -{ - m_notify->setEnabled( true ); -} - -void LinuxInputSubsystemMouseHandler::readMouseData() -{ - if (!qt_screen) - return; - - int n; - - do { - n = read(mouseFd, mouseBuf + mouseIdx, mouseBufSize - mouseIdx); - if (n > 0) - mouseIdx += n; - - struct input_event *data; - int idx = 0; - - while (mouseIdx-idx >= (int)sizeof(struct input_event)) { - uchar *mb = mouseBuf + idx; - data = (struct input_event *) mb; - // qLog(Input) << "mouse event type =" << data->type << "code =" << data->code << "value =" << data->value; - bool unknown = false; - if (data->type == EV_ABS) { - if (data->code == ABS_X) { - //qLog(Input) << "\tABS_X" << data->value; - mouseX = data->value; - } else if (data->code == ABS_Y) { - //qLog(Input) << "\tABS_Y" << data->value; - mouseY = data->value; - } else { - unknown = true; - } - } else if (data->type == EV_REL) { - //qLog(Input) << "\tEV_REL" << hex << data->code << dec << data->value; - if (data->code == REL_X) { - mouseX += data->value; - } else if (data->code == REL_Y) { - mouseY += data->value; - } else { - unknown = true; - } - } else if (data->type == EV_KEY && data->code == BTN_TOUCH) { - qLog(Input) << "\tBTN_TOUCH" << data->value; - mouseBtn = data->value ? Qt::LeftButton : 0; - } else if (data->type == EV_KEY) { - int button = 0; - switch (data->code) { - case BTN_LEFT: button = Qt::LeftButton; break; - case BTN_MIDDLE: button = Qt::MidButton; break; - case BTN_RIGHT: button = Qt::RightButton; break; - } - if (data->value) - mouseBtn |= button; - else - mouseBtn &= ~button; - } else if (data->type == EV_SYN && data->code == SYN_REPORT) { - QPoint pos( mouseX, mouseY ); - oldmouse = transform( pos ); - //qLog(Input) << "\tSYN_REPORT" << mouseBtn << pos << oldmouse; - emit mouseChanged(oldmouse, mouseBtn); - - } else { - unknown = true; - } - if (unknown) { - qWarning("unknown mouse event type=%x, code=%x, value=%x", data->type, data->code, data->value); - } - idx += sizeof(struct input_event); - } - int surplus = mouseIdx - idx; - for (int i = 0; i < surplus; i++) - mouseBuf[i] = mouseBuf[idx+i]; - mouseIdx = surplus; - } while (n > 0); -} - diff --git a/src/plugins/mousedrivers/linuxis/linuxismousehandler.h b/src/plugins/mousedrivers/linuxis/linuxismousehandler.h deleted file mode 100644 index c898ddb..0000000 --- a/src/plugins/mousedrivers/linuxis/linuxismousehandler.h +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef LINUXISMOUSEHANDLER_H -#define LINUXISMOUSEHANDLER_H - -#include - -class QSocketNotifier; -class LinuxInputSubsystemMouseHandler : public QObject, public QWSCalibratedMouseHandler { - Q_OBJECT -public: - LinuxInputSubsystemMouseHandler(const QString &device = QString("/dev/input/event0")); - ~LinuxInputSubsystemMouseHandler(); - - void suspend(); - void resume(); - -private: - int mouseX, mouseY; - int mouseBtn; - static const int mouseBufSize = 2048; - uchar mouseBuf[mouseBufSize]; - int mouseIdx; - QPoint oldmouse; - - QSocketNotifier *m_notify; - int mouseFd; - -private Q_SLOTS: - void readMouseData(); -}; - -#endif // LINUXISMOUSEHANDLER_H diff --git a/src/plugins/mousedrivers/mousedrivers.pro b/src/plugins/mousedrivers/mousedrivers.pro index e644361..f89682b 100644 --- a/src/plugins/mousedrivers/mousedrivers.pro +++ b/src/plugins/mousedrivers/mousedrivers.pro @@ -1,8 +1,5 @@ TEMPLATE = subdirs -contains(mouse-plugins, bus): SUBDIRS += bus contains(mouse-plugins, linuxtp): SUBDIRS += linuxtp contains(mouse-plugins, pc): SUBDIRS += pc contains(mouse-plugins, tslib): SUBDIRS += tslib -contains(mouse-plugins, vr41xx): SUBDIRS += vr41xx -contains(mouse-plugins, yopy): SUBDIRS += yopy -contains(mouse-plugins, linuxis): SUBDIRS += linuxis +contains(mouse-plugins, linuxinput): SUBDIRS += linuxinput diff --git a/src/plugins/mousedrivers/vr41xx/main.cpp b/src/plugins/mousedrivers/vr41xx/main.cpp deleted file mode 100644 index 8802a02..0000000 --- a/src/plugins/mousedrivers/vr41xx/main.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE - -class QVr41xxMouseDriver : public QMouseDriverPlugin -{ -public: - QVr41xxMouseDriver(); - - QStringList keys() const; - QWSMouseHandler* create(const QString &driver, const QString &device); -}; - -QVr41xxMouseDriver::QVr41xxMouseDriver() - : QMouseDriverPlugin() -{ -} - -QStringList QVr41xxMouseDriver::keys() const -{ - return (QStringList() << QLatin1String("VR41xx")); -} - -QWSMouseHandler* QVr41xxMouseDriver::create(const QString &driver, - const QString &device) -{ - if (driver.compare(QLatin1String("VR41xx"), Qt::CaseInsensitive)) - return 0; - return new QWSVr41xxMouseHandler(driver, device); -} - -Q_EXPORT_PLUGIN2(qwsvr41xxmousehandler, QVr41xxMouseDriver) - -QT_END_NAMESPACE diff --git a/src/plugins/mousedrivers/vr41xx/vr41xx.pro b/src/plugins/mousedrivers/vr41xx/vr41xx.pro deleted file mode 100644 index 1c22d04..0000000 --- a/src/plugins/mousedrivers/vr41xx/vr41xx.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qvr41xxmousedriver -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mousedrivers -target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers -INSTALLS += target - -DEFINES += QT_QWS_MOUSE_VR41XX - -HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qmousevr41xx_qws.h - -SOURCES = main.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qmousevr41xx_qws.cpp - diff --git a/src/plugins/mousedrivers/yopy/main.cpp b/src/plugins/mousedrivers/yopy/main.cpp deleted file mode 100644 index 9db9c4f..0000000 --- a/src/plugins/mousedrivers/yopy/main.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the either Technology Preview License Agreement or the -** Beta Release License Agreement. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain -** additional rights. These rights are described in the Nokia Qt LGPL -** Exception version 1.0, 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. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://www.qtsoftware.com/contact. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include -#include - -QT_BEGIN_NAMESPACE - -class QYopyMouseDriver : public QMouseDriverPlugin -{ -public: - QYopyMouseDriver(); - - QStringList keys() const; - QWSMouseHandler* create(const QString &driver, const QString &device); -}; - -QYopyMouseDriver::QYopyMouseDriver() - : QMouseDriverPlugin() -{ -} - -QStringList QYopyMouseDriver::keys() const -{ - return (QStringList() << QLatin1String("Yopy")); -} - -QWSMouseHandler* QYopyMouseDriver::create(const QString &driver, - const QString &device) -{ - if (driver.compare(QLatin1String("yopy"), Qt::CaseInsensitive)) - return 0; - return new QWSYopyMouseHandler(driver, device); -} - -Q_EXPORT_PLUGIN2(qwsyopymousehandler, QYopyMouseDriver) - -QT_END_NAMESPACE diff --git a/src/plugins/mousedrivers/yopy/yopy.pro b/src/plugins/mousedrivers/yopy/yopy.pro deleted file mode 100644 index 3045430..0000000 --- a/src/plugins/mousedrivers/yopy/yopy.pro +++ /dev/null @@ -1,14 +0,0 @@ -TARGET = qyopymousedriver -include(../../qpluginbase.pri) - -QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/mousedrivers -target.path = $$[QT_INSTALL_PLUGINS]/mousedrivers -INSTALLS += target - -DEFINES += QT_QWS_MOUSE_YOPY - -HEADERS = $$QT_SOURCE_TREE/src/gui/embedded/qmouseyopy_qws.h - -SOURCES = main.cpp \ - $$QT_SOURCE_TREE/src/gui/embedded/qmouseyopy_qws.cpp - -- cgit v0.12 From c36139c665e61866aff4bf8572890a735167a7d0 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 23 Jul 2009 16:49:55 +0200 Subject: repair showSummary after commit 08b3511a0c Reviewed-by: thartman --- tools/configure/configureapp.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 61daca8..ae6ebab 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3109,7 +3109,9 @@ void Configure::buildQmake() void Configure::buildHostTools() { - dictionary[ "DONE" ] = "yes"; + if (dictionary[ "NOPROCESS" ] == "yes") + dictionary[ "DONE" ] = "yes"; + if (!dictionary.contains("XQMAKESPEC")) return; -- cgit v0.12 From 6ac3cbc61a1fc80df0bac755028037586f1fdc3d Mon Sep 17 00:00:00 2001 From: Robert Griebl Date: Thu, 23 Jul 2009 16:56:05 +0200 Subject: Some minor doc fixes. Reviewed-by: Kavindra --- doc/src/emb-charinput.qdoc | 14 +++++++------- doc/src/emb-kmap2qmap.qdoc | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/src/emb-charinput.qdoc b/doc/src/emb-charinput.qdoc index 565d953..dc4eed5 100644 --- a/doc/src/emb-charinput.qdoc +++ b/doc/src/emb-charinput.qdoc @@ -108,7 +108,7 @@ \section1 Keymaps Starting with 4.6, \l {Qt for Embedded Linux} has gained support for - user defined keymaps. Keymap handling is supported by the builtin + user defined keymaps. Keymap handling is supported by the built-in keyboard drivers \c TTY and \c LinuxInput. Custom keyboard drivers can use the existing keymap handling code via QWSKeyboardHandler::processKeycode(). @@ -124,7 +124,7 @@ \snippet doc/src/snippets/code/doc_src_emb-charinput.qdoc 2 - The \c argument are \c TTY, \c LinuxInput and \l + The \c arguments are \c TTY, \c LinuxInput and \l {QKbdDriverPlugin::keys()}{keys} identifying custom drivers, and the driver specific options are typically a device, e.g., \c /dev/tty0. @@ -142,17 +142,17 @@ \row \o \c /dev/xxx \o Open the specified device, instead of the driver's default device. \row \o \c repeat-delay= \o - Time in milliseconds until auto-repeat kicks in. + Time (in milliseconds) until auto-repeat kicks in. \row \o \c repeat-rate= \o - Time in milliseconds specifying interval between auto-repeats. + Time (in milliseconds) specifying the interval between auto-repeats. \row \o \c keymap=xx.qmap \o File name of a keymap file in Qt's \c qmap format. See \l {kmap2qmap} - for instructions on how to create thoes files.\br Please note that the - file name can of course also be the name of a QResource. + for instructions on how to create thoes files.\br Note that the file + name can of course also be the name of a QResource. \row \o \c disable-zap \o Disable the QWS server "Zap" shortcut \bold{Ctrl+Alt+Backspace} \row \o \c enable-compose \o - Activate Latin-1 composing features in the builtin US keymap. You can + Activate Latin-1 composing features in the built-in US keymap. You can use the right \c AltGr or right \c Alt is used as a dead key modifier, while \c AltGr+. is the compose key. For example: \list diff --git a/doc/src/emb-kmap2qmap.qdoc b/doc/src/emb-kmap2qmap.qdoc index 2b3f687..19d33c1 100644 --- a/doc/src/emb-kmap2qmap.qdoc +++ b/doc/src/emb-kmap2qmap.qdoc @@ -66,7 +66,7 @@ kmap2qmap i386/qwertz/de-latin1-nodeadkeys.kmap include/compose.latin1.inc de-latin1-nodeadkeys.qmap \endcode - \c kmap2qmap doesn't support all the (pseudo) symbols that the Linux + \c kmap2qmap does not support all the (pseudo) symbols that the Linux kernel supports. If you are converting a standard keymap you will get a lot of warnings for things like \c Show_Registers, \c Hex_A, etc.: you can safely ignore those. -- cgit v0.12 From 3ce677f1375bc723b5fd5a11ccc21f2af0c45ca1 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 23 Jul 2009 16:55:29 +0200 Subject: configure shows Windows CE specific build steps when its done For cross compilation of Qt for Windows CE the user must call setcepaths before nmake. Now configure shows a helpful message if the xplatform configure switch was used. Task-number: 257352 Reviewed-by: thartman --- tools/configure/configureapp.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index ae6ebab..39588e6 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3342,8 +3342,16 @@ void Configure::generateMakefiles() void Configure::showSummary() { QString make = dictionary[ "MAKE" ]; - cout << endl << endl << "Qt is now configured for building. Just run " << qPrintable(make) << "." << endl; - cout << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl; + if (!dictionary.contains("XQMAKESPEC")) { + cout << endl << endl << "Qt is now configured for building. Just run " << qPrintable(make) << "." << endl; + cout << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl; + } else { + // we are cross compiling for Windows CE + cout << endl << endl << "Qt is now configured for building. To start the build run:" << endl + << "\tsetcepaths " << dictionary.value("XQMAKESPEC") << endl + << "\t" << qPrintable(make) << endl + << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl; + } } Configure::ProjectType Configure::projectType( const QString& proFileName ) -- cgit v0.12 From f439550632c0552514f73d2778c7920811e225f7 Mon Sep 17 00:00:00 2001 From: Jens Bache-Wiig Date: Thu, 23 Jul 2009 17:04:18 +0200 Subject: Fix incorrect button positioning on tabs For tabs with RoundedWest or TriangularWest the button offset was reversed on tab selection. This was very visible on windows where they could actually move outside the tab border. Task-number: 255139 Reviewed-by: paul --- src/gui/styles/qcommonstyle.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 308a0b8..ba28e75 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -2960,6 +2960,9 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt, horizontalShift *= -1; verticalShift *= -1; } + if (tab->shape == QTabBar::RoundedWest || tab->shape == QTabBar::TriangularWest) + horizontalShift = -horizontalShift; + tr.adjust(0, 0, horizontalShift, verticalShift); if (selected) { -- cgit v0.12 From 098be4ffcf4c9ba615332f853fd440ea630a4453 Mon Sep 17 00:00:00 2001 From: Norwegian Rock Cat Date: Thu, 9 Jul 2009 11:51:13 +0200 Subject: Implement an FSEvents-based QFileSystemWatcherEngine This has been around for a while and really should have been put in earlier. Mac OS X (client) has a much lower ulimit for open files than what some other Unix-like OS's have (in defense it does save memory). However, if you start watching a lot of files, it will start to fall down. You can adjust the ulimit, but it's a bit inconvenient. FSEvents watches the directory and notifies you of changes that happen in that directory (and below, but we don't really use it). It also can be adjusted for latency so that performance isn't affected by heavy file system use (but Qt doesn't use that either at the moment). The other thing is that it doesn't require any open files, so it's much better for our number of open files. This feature is only on Leopard and up, so people wanting to deploy Tiger will still have the "open files" problem to deal with. There are still some optimizations available in this code. For example, we could coalesce things down to watch only one high-level directory without changing much of the implementation. The current implementation has some very simplistic ways of handling things, but this simplicity works well. I documented it, so you can see that, yes, I really meant to do that. Task-Id: 164068 (and others) Reviewed-by: Denis --- src/corelib/io/io.pri | 5 +- src/corelib/io/qfilesystemwatcher.cpp | 10 +- src/corelib/io/qfilesystemwatcher_fsevents.cpp | 467 +++++++++++++++++++++ src/corelib/io/qfilesystemwatcher_fsevents_p.h | 127 ++++++ .../qfilesystemwatcher/tst_qfilesystemwatcher.cpp | 80 ++++ 5 files changed, 687 insertions(+), 2 deletions(-) create mode 100644 src/corelib/io/qfilesystemwatcher_fsevents.cpp create mode 100644 src/corelib/io/qfilesystemwatcher_fsevents_p.h diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 5033b21..bd41f5e 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -65,7 +65,10 @@ win32 { SOURCES += io/qfsfileengine_unix.cpp SOURCES += io/qfsfileengine_iterator_unix.cpp SOURCES += io/qprocess_unix.cpp - mac:SOURCES += io/qsettings_mac.cpp + macx-*: { + HEADERS += io/qfilesystemwatcher_fsevents_p.h + SOURCES += io/qsettings_mac.cpp io/qfilesystemwatcher_fsevents.cpp + } linux-*:{ SOURCES += \ diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index b321644..902e240 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -58,6 +58,9 @@ # include "qfilesystemwatcher_inotify_p.h" # include "qfilesystemwatcher_dnotify_p.h" #elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC) +# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +# include "qfilesystemwatcher_fsevents_p.h" +# endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) # include "qfilesystemwatcher_kqueue_p.h" #endif @@ -243,7 +246,12 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine() eng = QDnotifyFileSystemWatcherEngine::create(); return eng; #elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC) - return QKqueueFileSystemWatcherEngine::create(); +# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) + return QFSEventsFileSystemWatcherEngine::create(); + else +# endif + return QKqueueFileSystemWatcherEngine::create(); #else return 0; #endif diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.cpp b/src/corelib/io/qfilesystemwatcher_fsevents.cpp new file mode 100644 index 0000000..3e0aee8 --- /dev/null +++ b/src/corelib/io/qfilesystemwatcher_fsevents.cpp @@ -0,0 +1,467 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include + +#include "qfilesystemwatcher.h" +#include "qfilesystemwatcher_fsevents_p.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +// Static operator overloading so for the sake of some convieniece. +// They only live in this compilation unit to avoid polluting Qt in general. +static bool operator==(const struct ::timespec &left, const struct ::timespec &right) +{ + return left.tv_sec == right.tv_sec + && left.tv_nsec == right.tv_nsec; +} + +static bool operator==(const struct ::stat64 &left, const struct ::stat64 &right) +{ + return left.st_dev == right.st_dev + && left.st_mode == right.st_mode + && left.st_size == right.st_size + && left.st_ino == right.st_ino + && left.st_uid == right.st_uid + && left.st_gid == right.st_gid + && left.st_mtimespec == right.st_mtimespec + && left.st_ctimespec == right.st_ctimespec + && left.st_flags == right.st_flags; +} + +static bool operator!=(const struct ::stat64 &left, const struct ::stat64 &right) +{ + return !(operator==(left, right)); +} + + +static void addPathToHash(PathHash &pathHash, const QString &key, const QFileInfo &fileInfo, + const QString &path) +{ + PathInfoList &list = pathHash[key]; + list.push_back(PathInfo(path, + fileInfo.absoluteFilePath().normalized(QString::NormalizationForm_D).toUtf8())); + pathHash.insert(key, list); +} + +static void removePathFromHash(PathHash &pathHash, const QString &key, const QString &path) +{ + PathInfoList &list = pathHash[key]; + // We make the assumption that the list contains unique paths + PathInfoList::iterator End = list.end(); + PathInfoList::iterator it = list.begin(); + while (it != End) { + if (it->originalPath == path) { + list.erase(it); + break; + } + ++it; + } + if (list.isEmpty()) + pathHash.remove(key); +} + +static void stopFSStream(FSEventStreamRef stream) +{ + if (stream) { + FSEventStreamStop(stream); + FSEventStreamInvalidate(stream); + } +} + +static QString createFSStreamPath(const QString &absolutePath) +{ + // The path returned has a trailing slash, so ensure that here. + QString string = absolutePath; + string.reserve(string.size() + 1); + string.append(QLatin1Char('/')); + return string; +} + +static void cleanupFSStream(FSEventStreamRef stream) +{ + if (stream) + FSEventStreamRelease(stream); +} + +const FSEventStreamCreateFlags QtFSEventFlags = (kFSEventStreamCreateFlagUseCFTypes | kFSEventStreamCreateFlagNoDefer /* | kFSEventStreamCreateFlagWatchRoot*/); + +const CFTimeInterval Latency = 0.033; // This will do updates 30 times a second which is probably more than you need. +#endif + +QFSEventsFileSystemWatcherEngine::QFSEventsFileSystemWatcherEngine() + : fsStream(0), pathsToWatch(0), threadsRunLoop(0) +{ +} + +QFSEventsFileSystemWatcherEngine::~QFSEventsFileSystemWatcherEngine() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + // I assume that at this point, QFileSystemWatcher has already called stop + // on me, so I don't need to invalidate or stop my stream, simply + // release it. + cleanupFSStream(fsStream); + if (pathsToWatch) + CFRelease(pathsToWatch); +#endif +} + +QFSEventsFileSystemWatcherEngine *QFSEventsFileSystemWatcherEngine::create() +{ + return new QFSEventsFileSystemWatcherEngine(); +} + +QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths, + QStringList *files, + QStringList *directories) +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + stop(); + QMutexLocker locker(&mutex); + QStringList failedToAdd; + // if we have a running FSStreamEvent, we have to kill it, we'll re-add the stream soon. + FSEventStreamEventId idToCheck; + if (fsStream) { + idToCheck = FSEventStreamGetLatestEventId(fsStream); + cleanupFSStream(fsStream); + } else { + idToCheck = kFSEventStreamEventIdSinceNow; + } + + // Brain-dead approach, but works. FSEvents actually can already read sub-trees, but since it's + // work to figure out if we are doing a double register, we just register it twice as FSEvents + // seems smart enough to only deliver one event. We also duplicate directory entries in here + // (e.g., if you watch five files in the same directory, you get that directory included in the + // array 5 times). This stupidity also makes remove work correctly though. I'll freely admit + // that we could make this a bit smarter. If you do, check the auto-tests, they should catch at + // least a couple of the issues. + QCFType tmpArray = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); + for (int i = 0; i < paths.size(); ++i) { + const QString &path = paths.at(i); + + QFileInfo fileInfo(path); + if (!fileInfo.exists()) { + failedToAdd.append(path); + continue; + } + + if (fileInfo.isDir()) { + if (directories->contains(path)) { + failedToAdd.append(path); + continue; + } else { + directories->append(path); + // Full file path for dirs. + QCFString cfpath(createFSStreamPath(fileInfo.absoluteFilePath())); + addPathToHash(dirPathInfoHash, cfpath, fileInfo, path); + CFArrayAppendValue(tmpArray, cfpath); + } + } else { + if (files->contains(path)) { + failedToAdd.append(path); + continue; + } else { + // Just the absolute path (minus it's filename) for files. + QCFString cfpath(createFSStreamPath(fileInfo.absolutePath())); + files->append(path); + addPathToHash(filePathInfoHash, cfpath, fileInfo, path); + CFArrayAppendValue(tmpArray, cfpath); + } + } + } + if (CFArrayGetCount(tmpArray) > 0) { + if (pathsToWatch) { + CFArrayAppendArray(tmpArray, pathsToWatch, CFRangeMake(0, CFArrayGetCount(pathsToWatch))); + CFRelease(pathsToWatch); + } + pathsToWatch = CFArrayCreateCopy(kCFAllocatorDefault, tmpArray); + } + FSEventStreamContext context = { 0, this, 0, 0, 0 }; + fsStream = FSEventStreamCreate(kCFAllocatorDefault, + QFSEventsFileSystemWatcherEngine::fseventsCallback, + &context, pathsToWatch, + idToCheck, Latency, QtFSEventFlags); + warmUpFSEvents(); + + return failedToAdd; +#else + Q_UNUSED(paths); + Q_UNUSED(files); + Q_UNUSED(directories); + return QStringList(); +#endif +} + +void QFSEventsFileSystemWatcherEngine::warmUpFSEvents() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + // This function assumes that the mutex has already been grabbed before calling it. + // It exits with the mutex still locked (Q_ASSERT(mutex.isLocked()) ;-). + start(); + waitCondition.wait(&mutex); +#endif +} + +QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &paths, + QStringList *files, + QStringList *directories) +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + stop(); + QMutexLocker locker(&mutex); + // short circuit for smarties that call remove before add and we have nothing. + if (pathsToWatch == 0) + return paths; + QStringList failedToRemove; + // if we have a running FSStreamEvent, we have to stop it, we'll re-add the stream soon. + FSEventStreamEventId idToCheck; + if (fsStream) { + idToCheck = FSEventStreamGetLatestEventId(fsStream); + cleanupFSStream(fsStream); + fsStream = 0; + } else { + idToCheck = kFSEventStreamEventIdSinceNow; + } + + CFIndex itemCount = CFArrayGetCount(pathsToWatch); + QCFType tmpArray = CFArrayCreateMutableCopy(kCFAllocatorDefault, itemCount, + pathsToWatch); + CFRelease(pathsToWatch); + pathsToWatch = 0; + for (int i = 0; i < paths.size(); ++i) { + // Get the itemCount at the beginning to avoid any overruns during the iteration. + itemCount = CFArrayGetCount(tmpArray); + const QString &path = paths.at(i); + QFileInfo fi(path); + QCFString cfpath(createFSStreamPath(fi.absolutePath())); + + CFIndex index = CFArrayGetFirstIndexOfValue(tmpArray, CFRangeMake(0, itemCount), cfpath); + if (index != -1) { + CFArrayRemoveValueAtIndex(tmpArray, index); + files->removeAll(path); + removePathFromHash(filePathInfoHash, cfpath, path); + } else { + // Could be a directory we are watching instead. + QCFString cfdirpath(createFSStreamPath(fi.absoluteFilePath())); + index = CFArrayGetFirstIndexOfValue(tmpArray, CFRangeMake(0, itemCount), cfdirpath); + if (index != -1) { + CFArrayRemoveValueAtIndex(tmpArray, index); + directories->removeAll(path); + removePathFromHash(dirPathInfoHash, cfpath, path); + } else { + failedToRemove.append(path); + } + } + } + itemCount = CFArrayGetCount(tmpArray); + if (itemCount != 0) { + pathsToWatch = CFArrayCreateCopy(kCFAllocatorDefault, tmpArray); + + FSEventStreamContext context = { 0, this, 0, 0, 0 }; + fsStream = FSEventStreamCreate(kCFAllocatorDefault, + QFSEventsFileSystemWatcherEngine::fseventsCallback, + &context, pathsToWatch, idToCheck, Latency, QtFSEventFlags); + warmUpFSEvents(); + } + return failedToRemove; +#else + Q_UNUSED(paths); + Q_UNUSED(files); + Q_UNUSED(directories); + return QStringList(); +#endif +} + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +void QFSEventsFileSystemWatcherEngine::updateList(PathInfoList &list, bool directory, bool emitSignals) +{ + PathInfoList::iterator End = list.end(); + PathInfoList::iterator it = list.begin(); + while (it != End) { + struct ::stat64 newInfo; + if (::stat64(it->absolutePath, &newInfo) == 0) { + if (emitSignals) { + if (newInfo != it->savedInfo) { + it->savedInfo = newInfo; + if (directory) + emit directoryChanged(it->originalPath, false); + else + emit fileChanged(it->originalPath, false); + } + } else { + it->savedInfo = newInfo; + } + } else { + if (errno == ENOENT) { + if (emitSignals) { + if (directory) + emit directoryChanged(it->originalPath, true); + else + emit fileChanged(it->originalPath, true); + } + it = list.erase(it); + continue; + } else { + qWarning("%s:%d:QFSEventsFileSystemWatcherEngine: stat error on %s:%s", + __FILE__, __LINE__, qPrintable(it->originalPath), strerror(errno)); + + } + } + ++it; + } +} + +void QFSEventsFileSystemWatcherEngine::updateHash(PathHash &pathHash) +{ + PathHash::iterator HashEnd = pathHash.end(); + PathHash::iterator it = pathHash.begin(); + const bool IsDirectory = (&pathHash == &dirPathInfoHash); + while (it != HashEnd) { + updateList(it.value(), IsDirectory, false); + if (it.value().isEmpty()) + it = pathHash.erase(it); + else + ++it; + } +} +#endif + +void QFSEventsFileSystemWatcherEngine::fseventsCallback(ConstFSEventStreamRef , + void *clientCallBackInfo, size_t numEvents, + void *eventPaths, + const FSEventStreamEventFlags eventFlags[], + const FSEventStreamEventId []) +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + QFSEventsFileSystemWatcherEngine *watcher = static_cast(clientCallBackInfo); + QMutexLocker locker(&watcher->mutex); + CFArrayRef paths = static_cast(eventPaths); + for (size_t i = 0; i < numEvents; ++i) { + const QString path = QCFString::toQString( + static_cast(CFArrayGetValueAtIndex(paths, i))); + const FSEventStreamEventFlags pathFlags = eventFlags[i]; + // There are several flags that may be passed, but we really don't care about them ATM. + // Here they are and why we don't care. + // kFSEventStreamEventFlagHistoryDone--(very unlikely to be gotten, but even then, not much changes). + // kFSEventStreamEventFlagMustScanSubDirs--Likely means the data is very much out of date, we + // aren't coalescing our directories, so again not so much of an issue + // kFSEventStreamEventFlagRootChanged | kFSEventStreamEventFlagMount | kFSEventStreamEventFlagUnmount-- + // These three flags indicate something has changed, but the stat will likely show this, so + // there's not really much to worry about. + // (btw, FSEvents is not the correct way of checking for mounts/unmounts, + // there are real CarbonCore events for that.) + Q_UNUSED(pathFlags); + if (watcher->filePathInfoHash.contains(path)) + watcher->updateList(watcher->filePathInfoHash[path], false, true); + + if (watcher->dirPathInfoHash.contains(path)) + watcher->updateList(watcher->dirPathInfoHash[path], true, true); + } +#else + Q_UNUSED(clientCallBackInfo); + Q_UNUSED(numEvents); + Q_UNUSED(eventPaths); + Q_UNUSED(eventFlags); +#endif +} + +void QFSEventsFileSystemWatcherEngine::stop() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + stopFSStream(fsStream); + if (threadsRunLoop) + CFRunLoopStop(threadsRunLoop); +#endif +} + +void QFSEventsFileSystemWatcherEngine::updateFiles() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + QMutexLocker locker(&mutex); + updateHash(filePathInfoHash); + updateHash(dirPathInfoHash); + if (filePathInfoHash.isEmpty() && dirPathInfoHash.isEmpty()) { + // Everything disappeared before we got to start, don't bother. + stop(); + cleanupFSStream(fsStream); + } + waitCondition.wakeAll(); +#endif +} + +void QFSEventsFileSystemWatcherEngine::run() +{ +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + threadsRunLoop = CFRunLoopGetCurrent(); + FSEventStreamScheduleWithRunLoop(fsStream, threadsRunLoop, kCFRunLoopDefaultMode); + bool startedOK = FSEventStreamStart(fsStream); + // It's recommended by Apple that you only update the files after you've started + // the stream, because otherwise you might miss an update in between starting it. + updateFiles(); +#ifdef QT_NO_DEBUG + Q_UNUSED(startedOK); +#else + Q_ASSERT(startedOK); +#endif + // If for some reason we called stop up above (and invalidated our stream), this call will return + // immediately. + CFRunLoopRun(); + threadsRunLoop = 0; +#endif +} + +QT_END_NAMESPACE diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h new file mode 100644 index 0000000..2e8b788 --- /dev/null +++ b/src/corelib/io/qfilesystemwatcher_fsevents_p.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://www.qtsoftware.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#ifndef FILEWATCHER_FSEVENTS_P_H +#define FILEWATCHER_FSEVENTS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of the QLibrary class. This header file may change from +// version to version without notice, or even be removed. +// +// We mean it. +// + +#include "qfilesystemwatcher_p.h" + +#include +#include +#include +#include +#include +#include +#include + +typedef struct __FSEventStream *FSEventStreamRef; +typedef const struct __FSEventStream *ConstFSEventStreamRef; +typedef const struct __CFArray *CFArrayRef; +typedef uint FSEventStreamEventFlags; +typedef uint64_t FSEventStreamEventId; + +QT_BEGIN_NAMESPACE + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +// Yes, I use a stat64 element here. QFileInfo requires too much knowledge about implementation +// details to be used as a long-standing record. Since I'm going to have to store this information, I can +// do the stat myself too. +struct PathInfo { + PathInfo(const QString &path, const QByteArray &absPath) + : originalPath(path), absolutePath(absPath) {} + QString originalPath; // The path we need to emit + QByteArray absolutePath; // The path we need to stat. + struct ::stat64 savedInfo; // All the info for the path so we can compare it. +}; +typedef QLinkedList PathInfoList; +typedef QHash PathHash; +#endif + +class QFSEventsFileSystemWatcherEngine : public QFileSystemWatcherEngine +{ + Q_OBJECT +public: + ~QFSEventsFileSystemWatcherEngine(); + + static QFSEventsFileSystemWatcherEngine *create(); + + QStringList addPaths(const QStringList &paths, QStringList *files, QStringList *directories); + QStringList removePaths(const QStringList &paths, QStringList *files, QStringList *directories); + + void stop(); + +private: + QFSEventsFileSystemWatcherEngine(); + void warmUpFSEvents(); + void updateFiles(); + + static void fseventsCallback(ConstFSEventStreamRef streamRef, void *clientCallBackInfo, size_t numEvents, + void *eventPaths, const FSEventStreamEventFlags eventFlags[], + const FSEventStreamEventId eventIds[]); + void run(); + FSEventStreamRef fsStream; + CFArrayRef pathsToWatch; + CFRunLoopRef threadsRunLoop; + QMutex mutex; + QWaitCondition waitCondition; +#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + PathHash filePathInfoHash; + PathHash dirPathInfoHash; + void updateHash(PathHash &pathHash); + void updateList(PathInfoList &list, bool directory, bool emitSignals); +#endif +}; + +#endif + +QT_END_NAMESPACE diff --git a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp index da06742..c883c63 100644 --- a/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp +++ b/tests/auto/qfilesystemwatcher/tst_qfilesystemwatcher.cpp @@ -73,6 +73,8 @@ private slots: void removePath(); void addPaths(); void removePaths(); + void watchFileAndItsDirectory(); + void watchFileAndItsDirectory_data() { basicTest_data(); } private: QStringList do_force_engines; @@ -397,5 +399,83 @@ void tst_QFileSystemWatcher::removePaths() watcher.removePaths(paths); } +void tst_QFileSystemWatcher::watchFileAndItsDirectory() +{ + QFETCH(QString, backend); + QDir().mkdir("testDir"); + QDir testDir("testDir"); + + QString testFileName = testDir.filePath("testFile.txt"); + QString secondFileName = testDir.filePath("testFile2.txt"); + QFile::remove(secondFileName); + + QFile testFile(testFileName); + testFile.setPermissions(QFile::ReadOwner | QFile::WriteOwner); + testFile.remove(); + + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); + testFile.write(QByteArray("hello")); + testFile.close(); + + QFileSystemWatcher watcher; + watcher.setObjectName(QLatin1String("_qt_autotest_force_engine_") + backend); + + watcher.addPath(testDir.dirName()); + watcher.addPath(testFileName); + + QSignalSpy fileChangedSpy(&watcher, SIGNAL(fileChanged(const QString &))); + QSignalSpy dirChangedSpy(&watcher, SIGNAL(directoryChanged(const QString &))); + QEventLoop eventLoop; + QTimer timer; + connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit())); + + // resolution of the modification time is system dependent, but it's at most 1 second when using + // the polling engine. From what I know, FAT32 has a 2 second resolution. So we have to + // wait before modifying the directory... + QTest::qWait(2000); + + QVERIFY(testFile.open(QIODevice::WriteOnly | QIODevice::Truncate)); + testFile.write(QByteArray("hello again")); + testFile.close(); + + timer.start(3000); + eventLoop.exec(); + QCOMPARE(fileChangedSpy.count(), 1); + QCOMPARE(dirChangedSpy.count(), 0); + + fileChangedSpy.clear(); + QFile secondFile(secondFileName); + secondFile.open(QIODevice::WriteOnly | QIODevice::Truncate); + secondFile.write("Foo"); + secondFile.close(); + + timer.start(3000); + eventLoop.exec(); + QCOMPARE(fileChangedSpy.count(), 0); + QCOMPARE(dirChangedSpy.count(), 1); + + dirChangedSpy.clear(); + + QFile::remove(testFileName); + + timer.start(3000); + eventLoop.exec(); + QCOMPARE(fileChangedSpy.count(), 1); + QCOMPARE(dirChangedSpy.count(), 1); + + fileChangedSpy.clear(); + dirChangedSpy.clear(); + + watcher.removePath(testFileName); + QFile::remove(secondFileName); + + timer.start(3000); + eventLoop.exec(); + QCOMPARE(fileChangedSpy.count(), 0); + QCOMPARE(dirChangedSpy.count(), 1); + + QVERIFY(QDir().rmdir("testDir")); +} + QTEST_MAIN(tst_QFileSystemWatcher) #include "tst_qfilesystemwatcher.moc" -- cgit v0.12 From 2410f261eaa13442baa46537202d31ad26d797e7 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 23 Jul 2009 15:14:34 +0200 Subject: Reverted commits that changed the behavior of the keypresses with modifiers. Apparently it changes the behavior of Qt too much and also breaks the text input in some keyboard layouts (for example in German layout you need to be able to use Ctrl and Alt or AltGr modifiers to type text). Revert "Don't insert text into a text widget when a modifier is pressed." This reverts commit 099a32d121cbc80a1a234c3146f4be9b5237e7e8. Revert "Fixed the qlineedit autotest." This reverts commit 9210e8cdc83b6812d10f5f5847d05703ef2e5f7c. --- src/gui/text/qtextcontrol.cpp | 3 +-- src/gui/widgets/qlineedit.cpp | 3 +-- tests/auto/qlineedit/tst_qlineedit.cpp | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 2a590fd..b2ad686 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1245,8 +1245,7 @@ void QTextControlPrivate::keyPressEvent(QKeyEvent *e) process: { QString text = e->text(); - if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t')) && - ((e->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) { + if (!text.isEmpty() && (text.at(0).isPrint() || text.at(0) == QLatin1Char('\t'))) { if (overwriteMode // no need to call deleteChar() if we have a selection, insertText // does it already diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index d1067a8..c7f3e97 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -2169,8 +2169,7 @@ void QLineEdit::keyPressEvent(QKeyEvent *event) if (unknown && !d->readOnly) { QString t = event->text(); - if (!t.isEmpty() && t.at(0).isPrint() && - ((event->modifiers() & (Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier)) == Qt::NoModifier)) { + if (!t.isEmpty() && t.at(0).isPrint()) { insert(t); #ifndef QT_NO_COMPLETER d->complete(event->key()); diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 7fc8316..3519afa 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -3025,11 +3025,11 @@ void tst_QLineEdit::charWithAltOrCtrlModifier() QTest::keyPress(testWidget, Qt::Key_Plus); QCOMPARE(testWidget->text(), QString("+")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::ControlModifier); - QCOMPARE(testWidget->text(), QString("+")); + QCOMPARE(testWidget->text(), QString("++")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier); - QCOMPARE(testWidget->text(), QString("+")); + QCOMPARE(testWidget->text(), QString("+++")); QTest::keyPress(testWidget, Qt::Key_Plus, Qt::AltModifier | Qt::ControlModifier); - QCOMPARE(testWidget->text(), QString("+")); + QCOMPARE(testWidget->text(), QString("++++")); } void tst_QLineEdit::leftKeyOnSelectedText() -- cgit v0.12 From 1368c210ef9976f68eb9fb1c3e4dc14f4fa4edd2 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Thu, 23 Jul 2009 19:42:51 +0200 Subject: Doc: Clarified that the format used in QImage::fromData() is the image format, not the pixel format. Reviewed-by: Trust Me --- src/gui/image/qimage.cpp | 58 ++++++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 7d7dde1..ec36224 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -612,6 +612,9 @@ bool QImageData::checkForAlphaPixels() const \table \header \o Function \o Description \row + \o setAlphaChannel() + \o Sets the alpha channel of the image. + \row \o setDotsPerMeterX() \o Defines the aspect ratio by setting the number of pixels that fit horizontally in a physical meter. @@ -1688,12 +1691,8 @@ void QImage::setColorTable(const QVector colors) d->colortable = colors; d->has_alpha_clut = false; - for (int i = 0; i < d->colortable.size(); ++i) { - if (qAlpha(d->colortable.at(i)) != 255) { - d->has_alpha_clut = true; - break; - } - } + for (int i = 0; i < d->colortable.size(); ++i) + d->has_alpha_clut |= (qAlpha(d->colortable.at(i)) != 255); } /*! @@ -3948,8 +3947,10 @@ QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Transf if (newSize == size()) return copy(); - QTransform wm = QTransform::fromScale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); - QImage img = transformed(wm, mode); + QImage img; + QTransform wm; + wm.scale((qreal)newSize.width() / width(), (qreal)newSize.height() / height()); + img = transformed(wm, mode); return img; } @@ -3976,8 +3977,9 @@ QImage QImage::scaledToWidth(int w, Qt::TransformationMode mode) const if (w <= 0) return QImage(); + QTransform wm; qreal factor = (qreal) w / width(); - QTransform wm = QTransform::fromScale(factor, factor); + wm.scale(factor, factor); return transformed(wm, mode); } @@ -4004,8 +4006,9 @@ QImage QImage::scaledToHeight(int h, Qt::TransformationMode mode) const if (h <= 0) return QImage(); + QTransform wm; qreal factor = (qreal) h / height(); - QTransform wm = QTransform::fromScale(factor, factor); + wm.scale(factor, factor); return transformed(wm, mode); } @@ -4626,14 +4629,17 @@ bool QImage::loadFromData(const uchar *data, int len, const char *format) \fn QImage QImage::fromData(const uchar *data, int size, const char *format) Constructs a QImage from the first \a size bytes of the given - binary \a data. The loader attempts to read the image using the - specified \a format. If \a format is not specified (which is the default), - the loader probes the file for a header to guess the file format. + binary \a data. The loader attempts to read the image, either using the + optional image \a format specified or by determining the image format from + the data. - If the loading of the image failed, this object is a null image. + If \a format is not specified (which is the default), the loader probes the + file for a header to determine the file format. If \a format is specified, + it must be one of the values returned by QImageReader::supportedImageFormats(). - \sa load(), save(), {QImage#Reading and Writing Image - Files}{Reading and Writing Image Files} + If the loading of the image fails, the image returned will be a null image. + + \sa load(), save(), {QImage#Reading and Writing Image Files}{Reading and Writing Image Files} */ QImage QImage::fromData(const uchar *data, int size, const char *format) { @@ -4761,7 +4767,7 @@ QDataStream &operator>>(QDataStream &s, QImage &image) image = QImageReader(s.device(), 0).read(); return s; } -#endif // QT_NO_DATASTREAM +#endif #ifdef QT3_SUPPORT @@ -4851,6 +4857,8 @@ bool QImage::operator==(const QImage & i) const return false; if (d->format != Format_RGB32) { + if (d->colortable != i.d->colortable) + return false; if (d->format >= Format_ARGB32) { // all bits defined const int n = d->width * d->depth / 8; if (n == d->bytes_per_line && n == i.d->bytes_per_line) { @@ -4863,13 +4871,11 @@ bool QImage::operator==(const QImage & i) const } } } else { - const int w = width(); - const int h = height(); - const QVector &colortable = d->colortable; - const QVector &icolortable = i.d->colortable; + int w = width(); + int h = height(); for (int y=0; y