diff --git a/bin/fixqt4headers.pl b/bin/fixqt4headers.pl index 1905a6b21f..966681fad5 100755 --- a/bin/fixqt4headers.pl +++ b/bin/fixqt4headers.pl @@ -152,6 +152,14 @@ if (-d $qtdir . '/include/QtQuick1') { print "Warning - cannot find QtQuick1 headers\n"; } +# Support porting from "Qt 4.99" QtDeclarative to QtQuick (QQuickItem et al) +if (-d $qtdir . '/include/QtQuick') { + findQtHeaders('QtQuick', $qtdir); +} elsif (-d $qtdir . '/../qtdeclarative' ) { + # This is the case if QTDIR points to a source tree instead of an installed Qt + findQtHeaders('QtQuick', $qtdir . '/../qtdeclarative'); +} + # special case $headerSubst{'QtGui'} = 'QtWidgets/QtWidgets'; diff --git a/bin/syncqt b/bin/syncqt index 566b6e1531..34d518d7a2 100755 --- a/bin/syncqt +++ b/bin/syncqt @@ -1238,7 +1238,7 @@ foreach my $lib (@modules_to_sync) { my $modulepriname = basename($modulepri); make_path($module_fwd, $lib, $verbose_level); my $moduleprifwd = "$module_fwd/$modulepriname"; - my $mod_base = $developer_build ? $basedir : $out_basedir; + my $mod_base = $basedir; my $mod_component_base = $developer_build ? $qtbasedir : $out_basedir; open MODULE_PRI_FILE, ">$moduleprifwd" or die("Could not open $moduleprifwd for writing"); print MODULE_PRI_FILE "QT_MODULE_BASE = $mod_base\n"; diff --git a/configure b/configure index d62d3bd9d0..869e398764 100755 --- a/configure +++ b/configure @@ -762,7 +762,6 @@ CFG_GSTREAMER=auto CFG_QGTKSTYLE=auto CFG_LARGEFILE=auto CFG_OPENSSL=auto -CFG_PTMALLOC=no CFG_STL=auto CFG_PRECOMPILE=auto CFG_SEPARATE_DEBUG_INFO=no @@ -777,7 +776,7 @@ CFG_SSSE3=auto CFG_SSE4_1=auto CFG_SSE4_2=auto CFG_AVX=auto -CFG_REDUCE_RELOCATIONS=no +CFG_REDUCE_RELOCATIONS=auto CFG_NAS=no CFG_QWS_DEPTHS=all CFG_ACCESSIBILITY=auto @@ -1040,7 +1039,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-wayland|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-v8|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-icu|-force-asserts|-testcocoon) + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-xinput2|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-xcb|-wayland|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-v8|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-icu|-force-asserts|-testcocoon) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -2069,14 +2068,6 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; - ptmalloc) - if [ "$VAL" = "yes" ]; then - CFG_PTMALLOC="yes" - else - UNKNOWN_OPT=yes - fi - ;; - xmlpatterns) if [ "$VAL" = "yes" ] || [ "$VAL" = "auto" ]; then CFG_XMLPATTERNS="yes" @@ -3977,9 +3968,6 @@ Third Party Libraries: + -openssl ........... Enable run-time OpenSSL support. -openssl-linked .... Enabled linked OpenSSL support. - -ptmalloc .......... Override the system memory allocator with ptmalloc. - (Experimental.) - Additional options: -make ....... Add part to the list of parts to be built at make time. @@ -4029,6 +4017,9 @@ Additional options: -reduce-relocations ..... Reduce relocations in the libraries through extra linker optimizations (Qt/X11 and Qt for Embedded Linux only; experimental; needs GNU ld >= 2.18). + + -force-asserts ........ Force Q_ASSERT to be enabled even in release builds. + EOF if [ "$CFG_SEPARATE_DEBUG_INFO" = "auto" ]; then @@ -6708,15 +6699,6 @@ if [ -n "$CFG_RUNTIME_SYSTEM" -a "$CFG_GRAPHICS_SYSTEM" != "runtime" ] || [ "$CF CFG_RUNTIME_SYSTEM= fi -if [ "$CFG_PTMALLOC" != "no" ]; then - # build ptmalloc, copy .a file to lib/ - echo "Building ptmalloc. Please wait..." - (cd "$relpath/src/3rdparty/ptmalloc/"; "$MAKE" "clean" ; "$MAKE" "posix" - mkdir "$outpath/lib/" ; cp "libptmalloc3.a" "$outpath/lib/") - - QMakeVar add QMAKE_LFLAGS "$outpath/lib/libptmalloc3.a" -fi - if [ "$CFG_ALSA" = "auto" ]; then if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/alsa "alsa" $L_FLAGS $I_FLAGS $l_FLAGS; then CFG_ALSA=yes @@ -8505,8 +8487,6 @@ if [ "$XPLATFORM_MAEMO" = "yes" ] && [ "$CFG_XCB" = "yes" ]; then fi echo -[ "$CFG_PTMALLOC" != "no" ] && echo "Use ptmalloc ........... $CFG_PTMALLOC" - # complain about not being able to use dynamic plugins if we are using a static build if [ "$CFG_SHARED" = "no" ]; then echo diff --git a/dist/changes-5.0.0 b/dist/changes-5.0.0 index 87397d609a..cec264337f 100644 --- a/dist/changes-5.0.0 +++ b/dist/changes-5.0.0 @@ -59,6 +59,9 @@ information about a particular change. like SkipSingle -- skipping a non-data-driven test function or skipping only the current data row of a data-driven test function. Every skipped data row is now reported in the test log. + * The QTest::qExec(QObject*, const QStringList&) overload has been removed + from the API. This function was not used in any of Qt's autotests and did + not provide significant benefits over QTest::qExec(QObject*, int, char**). - The QSsl::TlsV1 enum value was renamed to QSsl::TlsV1_0 . @@ -85,6 +88,34 @@ information about a particular change. * Refactored to be based on action names. All functions have been changed from using int parameters to strings. +- QSound has been moved from QtGui to QtMultimedia + +- QTouchEvent: + + * The DeviceType enum and deviceType() have been deprecated due to + the introduction of QTouchDevice. + + * The signature of the constructor has changed. It now takes a + QTouchDevice pointer instead of just a DeviceType value. + + * TouchPointState no longer includes TouchPointStateMask and + TouchPointPrimary. The primary flag is now stored together with + other touch point flags and is accessible through + TouchPoint::isPrimary() or TouchPoint::flags(). As a result the + internally used state mask is no longer necessary. + + * QWidget *widget() has been removed and is replaced by QObject + *target() in order to avoid QWidget dependencies. + +- QWindowSystemInterface: + + * The signature of all handleTouchEvent() variants have changed, + taking a QTouchDevice* instead of just a DeviceType value. + Platform or generic plug-ins have to create and register at least + one QTouchDevice before sending the first touch event. + + * The event type parameter is removed from handleTouchEvent(). + **************************************************************************** * General * **************************************************************************** @@ -111,12 +142,20 @@ QtCore * drop a bogus QChar::NoCategory enum value; the proper QChar::Other_NotAssigned value is returned for an unassigned codepoints now. +* layoutAboutToBeChanged is no longer emitted by QAbstractItemModel::beginMoveRows. + layoutChanged is no longer emitted by QAbstractItemModel::endMoveRows. Proxy models + should now also connect to (and disconnect from) the rowsAboutToBeMoved and + rowsMoved signals. + QtGui ----- * Accessibility has been refactored. The hierachy of accessible objects is implemented via proper parent/child functions instead of using navigate which has been deprecated for this purpose. Table and cell interfaces have been added to qaccessible2.h +* Touch events and points have been extended to hold additional + information like capability flags, point-specific flags, velocity, + and raw positions. QtWidgets --------- diff --git a/doc/src/snippets/code/doc_src_qtsql.cpp b/doc/src/snippets/code/doc_src_qtsql.cpp new file mode 100644 index 0000000000..9c0c16e14b --- /dev/null +++ b/doc/src/snippets/code/doc_src_qtsql.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +#include +//! [0] diff --git a/doc/src/snippets/code/doc_src_qtsql.pro b/doc/src/snippets/code/doc_src_qtsql.pro new file mode 100644 index 0000000000..4e31846735 --- /dev/null +++ b/doc/src/snippets/code/doc_src_qtsql.pro @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#! [1] +QT += sql +#! [1] diff --git a/doc/src/snippets/code/doc_src_qtxml.cpp b/doc/src/snippets/code/doc_src_qtxml.cpp new file mode 100644 index 0000000000..5413fd2ccf --- /dev/null +++ b/doc/src/snippets/code/doc_src_qtxml.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +#include +//! [0] diff --git a/doc/src/snippets/code/doc_src_qtxml.pro b/doc/src/snippets/code/doc_src_qtxml.pro new file mode 100644 index 0000000000..d69b2ceadd --- /dev/null +++ b/doc/src/snippets/code/doc_src_qtxml.pro @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor +** the names of its contributors may be used to endorse or promote +** products derived from this software without specific prior written +** permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#! [1] +QT += xml +#! [1] diff --git a/examples/opengl/hellowindow/hellowindow.cpp b/examples/opengl/hellowindow/hellowindow.cpp index 2903ddd743..742de251f4 100644 --- a/examples/opengl/hellowindow/hellowindow.cpp +++ b/examples/opengl/hellowindow/hellowindow.cpp @@ -46,11 +46,13 @@ #include -Renderer::Renderer(const QSurfaceFormat &format, Renderer *share) +Renderer::Renderer(const QSurfaceFormat &format, Renderer *share, QScreen *screen) : m_initialized(false) , m_format(format) { m_context = new QOpenGLContext(this); + if (screen) + m_context->setScreen(screen); m_context->setFormat(format); if (share) m_context->setShareContext(share->m_context); diff --git a/examples/opengl/hellowindow/hellowindow.h b/examples/opengl/hellowindow/hellowindow.h index 82d275aa68..b257cef20f 100644 --- a/examples/opengl/hellowindow/hellowindow.h +++ b/examples/opengl/hellowindow/hellowindow.h @@ -54,7 +54,7 @@ class Renderer : public QObject { Q_OBJECT public: - Renderer(const QSurfaceFormat &format, Renderer *share = 0); + Renderer(const QSurfaceFormat &format, Renderer *share = 0, QScreen *screen = 0); QSurfaceFormat format() const { return m_format; } diff --git a/examples/opengl/hellowindow/main.cpp b/examples/opengl/hellowindow/main.cpp index 4a11aa1c7a..36cbc414dd 100644 --- a/examples/opengl/hellowindow/main.cpp +++ b/examples/opengl/hellowindow/main.cpp @@ -72,15 +72,13 @@ int main(int argc, char **argv) windowA->setWindowTitle(QLatin1String("Thread A - Context A")); windowA->setVisible(true); - QThread *renderThread = 0; + QList renderThreads; if (multipleWindows) { Renderer *rendererB = new Renderer(format, rendererA); - renderThread = new QThread; + QThread *renderThread = new QThread; rendererB->moveToThread(renderThread); - renderThread->start(); - - QObject::connect(qGuiApp, SIGNAL(lastWindowClosed()), renderThread, SLOT(quit())); + renderThreads << renderThread; HelloWindow *windowB = new HelloWindow(rendererA); windowB->setGeometry(QRect(center, windowSize).translated(delta / 2, 0)); @@ -91,10 +89,37 @@ int main(int argc, char **argv) windowC->setGeometry(QRect(center, windowSize).translated(-windowSize.width() / 2, windowSize.height() + delta)); windowC->setWindowTitle(QLatin1String("Thread B - Context B")); windowC->setVisible(true); + + for (int i = 1; i < QGuiApplication::screens().size(); ++i) { + QScreen *screen = QGuiApplication::screens().at(i); + Renderer *renderer = new Renderer(format, rendererA, screen); + + renderThread = new QThread; + renderer->moveToThread(renderThread); + renderThreads << renderThread; + + QRect screenGeometry = screen->availableGeometry(); + QPoint center = screenGeometry.center(); + + QSize windowSize = screenGeometry.size() * 0.8; + + HelloWindow *window = new HelloWindow(renderer); + window->setScreen(screen); + window->setGeometry(QRect(center, windowSize).translated(-windowSize.width() / 2, -windowSize.height() / 2)); + + QChar id = QChar('B' + i); + window->setWindowTitle(QLatin1String("Thread ") + id + QLatin1String(" - Context ") + id); + window->setVisible(true); + } + } + + for (int i = 0; i < renderThreads.size(); ++i) { + QObject::connect(qGuiApp, SIGNAL(lastWindowClosed()), renderThreads.at(i), SLOT(quit())); + renderThreads.at(i)->start(); } app.exec(); - if (multipleWindows) - renderThread->wait(); + for (int i = 0; i < renderThreads.size(); ++i) + renderThreads.at(i)->wait(); } diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf index 04737f5f42..65eec35bfc 100644 --- a/mkspecs/features/qt_functions.prf +++ b/mkspecs/features/qt_functions.prf @@ -76,6 +76,7 @@ defineTest(qtAddModule) { MODULE_INCLUDES = $$eval(QT.$${1}.includes) MODULE_LIBS = $$eval(QT.$${1}.libs) MODULE_CONFIG = $$eval(QT.$${1}.module_config) + MODULE_MAJOR_VERSION = $$eval(QT.$${1}.MAJOR_VERSION) CONFIG += $$eval(QT.$${1}.CONFIG) DEFINES += $$eval(QT.$${1}.DEFINES) @@ -119,6 +120,16 @@ defineTest(qtAddModule) { } } + win32 { + # Make sure we link against the version pulled from the module's .pri + ver_var = QMAKE_$${upper($$MODULE_NAME$$QT_LIBINFIX)}_VERSION_OVERRIDE + dver_var = QMAKE_$${upper($$MODULE_NAME$$QT_LIBINFIX)}D_VERSION_OVERRIDE + $$ver_var = $$MODULE_MAJOR_VERSION + $$dver_var = $$MODULE_MAJOR_VERSION + export($$ver_var) + export($$dver_var) + } + isEmpty(LINKAGE) { # Make sure we can link to uninstalled libraries !isEqual(MODULE_LIBS, $$[QT_INSTALL_LIBS]) { diff --git a/mkspecs/features/qt_module_config.prf b/mkspecs/features/qt_module_config.prf index 3d861279b4..6104362c0b 100644 --- a/mkspecs/features/qt_module_config.prf +++ b/mkspecs/features/qt_module_config.prf @@ -33,19 +33,6 @@ for(include_path, MODULE_INCLUDES):LAST_MODULE_INCLUDE=$${include_path} HEADERS_PRI = $$LAST_MODULE_INCLUDE/headers.pri include($$HEADERS_PRI, "", true)|clear(HEADERS_PRI) -#version overriding -win32 { - #because libnetwork.pro could be qmake'd (qmade?) before libqcore.pro we - #need to override the version of libq* in all other libq*'s just to be - #sure the same version is used - VERSIONS_LIST = $$split(VERSION, ".") - QT_LIBS_OVERRIDE = $$member(VERSIONS_LIST, 0) - for(lib, $$list(qtcore qtgui qtnetwork qtxml qtopengl qtsql qt3support)) { - eval(QMAKE_$${upper($$lib)}_VERSION_OVERRIDE = $$QT_LIBS_OVERRIDE) - eval(QMAKE_$${upper($$lib)}D_VERSION_OVERRIDE = $$QT_LIBS_OVERRIDE) - } -} - #other DESTDIR = $$eval(QT.$${MODULE}.libs) win32:!wince*:DLLDESTDIR = $$[QT_INSTALL_PREFIX]/bin diff --git a/mkspecs/features/win32/thread.prf b/mkspecs/features/win32/thread.prf index 76354a8200..fc832a0990 100644 --- a/mkspecs/features/win32/thread.prf +++ b/mkspecs/features/win32/thread.prf @@ -1,8 +1,4 @@ CONFIG -= thread_off -qt { - target_qt:PRL_EXPORT_DEFINES += QT_THREAD_SUPPORT - else:DEFINES += QT_THREAD_SUPPORT -} # #### These need to go debug { diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 1d4e6cabf3..3ad240db01 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1487,6 +1487,29 @@ MakefileGenerator::createObjectList(const QStringList &sources) int dl = fName.lastIndexOf(Option::dir_sep); if(dl != -1) dir = fName.left(dl + 1); + } else if (project->isActiveConfig("object_parallel_to_source")) { + // The source paths are relative to the output dir, but we need source-relative paths + QString sourceRelativePath = fileFixify(*it, qmake_getpwd(), Option::output_dir); + sourceRelativePath = Option::fixPathToTargetOS(sourceRelativePath, false); + + if (sourceRelativePath.startsWith(".." + Option::dir_sep)) + sourceRelativePath = fileFixify(sourceRelativePath, FileFixifyAbsolute); + + if (QDir::isAbsolutePath(sourceRelativePath)) + sourceRelativePath.remove(0, sourceRelativePath.indexOf(Option::dir_sep) + 1); + + dir = objdir; // We still respect OBJECTS_DIR + + int lastDirSepPosition = sourceRelativePath.lastIndexOf(Option::dir_sep); + if (lastDirSepPosition != -1) + dir += sourceRelativePath.leftRef(lastDirSepPosition + 1); + + if (!noIO()) { + // Ensure that the final output directory of each object exists + QString outRelativePath = fileFixify(dir, qmake_getpwd(), Option::output_dir); + if (!mkdir(outRelativePath)) + warn_msg(WarnLogic, "Cannot create directory '%s'", outRelativePath.toLatin1().constData()); + } } else { dir = objdir; } diff --git a/src/3rdparty/ptmalloc/COPYRIGHT b/src/3rdparty/ptmalloc/COPYRIGHT deleted file mode 100644 index 155e4ddd80..0000000000 --- a/src/3rdparty/ptmalloc/COPYRIGHT +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2001-2006 Wolfram Gloger - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that (i) the above copyright notices and this permission -notice appear in all copies of the software and related documentation, -and (ii) the name of Wolfram Gloger may not be used in any advertising -or publicity relating to the software. - -THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -IN NO EVENT SHALL WOLFRAM GLOGER BE LIABLE FOR ANY SPECIAL, -INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY -OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. diff --git a/src/3rdparty/ptmalloc/ChangeLog b/src/3rdparty/ptmalloc/ChangeLog deleted file mode 100644 index 45f7f463fa..0000000000 --- a/src/3rdparty/ptmalloc/ChangeLog +++ /dev/null @@ -1,33 +0,0 @@ -2006-05-31 Wolfram Gloger - - * sysdeps/pthread/malloc-machine.h (mutex_unlock): Unlock needs - full memory barrier (thanks Bart Robinson). - -2006-03-31 Wolfram Gloger - - * ptmalloc3.c (public_iCALLOc, public_iCOMALLOc): New functions. - -2006-03-30 Wolfram Gloger - - * malloc/malloc.c: Upgrade to version pre-2.8.4-29mar06. - * malloc/malloc-private.h: New fields in malloc_state. - -2004-03-29 Wolfram Gloger - - * malloc/malloc.c (mmap_alloc): Use page_align instead of - granularity_align. - (mmap_resize): Likewise. - - * malloc/ptmalloc3.c (ptmalloc_init): - Add MALLOC_GRANULARITY_ and synonymous MALLOC_TOP_PAD_ environment - parameters. - -2006-03-25 Wolfram Gloger - - * malloc/malloc-private.h: New file. - -2005-12-31 Wolfram Gloger - - * malloc/malloc.c: Imported from Doug Lea's malloc-2.8.3. - * malloc/malloc.h-2.8.3.h: Likewise. - * malloc/ptmalloc3.c: New file. diff --git a/src/3rdparty/ptmalloc/Makefile b/src/3rdparty/ptmalloc/Makefile deleted file mode 100644 index ae7793cc78..0000000000 --- a/src/3rdparty/ptmalloc/Makefile +++ /dev/null @@ -1,211 +0,0 @@ -# Makefile for ptmalloc, version 3 -# by Wolfram Gloger 1996-1999, 2001-2005, 2006 - -DIST_FILES0 = ChangeLog malloc-2.8.3.h malloc.c \ - malloc-private.h ptmalloc3.c \ - sysdeps \ - #tst-mallocstate.c tst-mstats.c -DIST_FILES1 = COPYRIGHT README Makefile \ - $(DIST_FILES0) \ - lran2.h t-test.h t-test1.c t-test2.c \ - tst-independent-alloc.c \ - #debian -DIST_FILES2 = $(DIST_FILES1) \ - m-test1.c \ - RCS/*,v - -TAR_FLAGS = --numeric-owner --exclude "*~" --exclude "debian/tmp*" - -#CC = /pkg/gcc-2.95.2-wg/bin/gcc -CC = gcc - -SYS_FLAGS = -OPT_FLAGS = -g -O2 #-O # -O2 -WARN_FLAGS = -Wall -Wstrict-prototypes -SH_FLAGS = -shared -fpic - -INC_FLAGS = -Isysdeps/generic - -# Flags for the test programs -T_FLAGS = -DUSE_MALLOC=1 -DTEST=1 - -# Flags for the compilation of malloc.c -M_FLAGS = -DTHREAD_STATS=1 #-DMALLOC_DEBUG=1 -DDEBUG=1 - -# Thread flags. -# See the platform-specific targets below. -THR_FLAGS = -DUSE_TSD_DATA_HACK -D_REENTRANT -THR_LIBS = -lpthread - -RM = rm -f -AR = ar -RANLIB = ranlib - -MALLOC_OBJ = ptmalloc3.o malloc.o -LIB_MALLOC = libptmalloc3.a - -T_SUF = -TESTS = t-test1$(T_SUF) t-test2$(T_SUF) \ - tst-independent-alloc$(T_SUF) - #m-test1$(T_SUF) tst-mallocstate$(T_SUF) tst-mstats$(T_SUF) - -CFLAGS = $(SYS_FLAGS) $(OPT_FLAGS) $(WARN_FLAGS) $(THR_FLAGS) $(INC_FLAGS) - -.c.o: - $(CC) -c $(CFLAGS) $< - -all: $(LIB_MALLOC) - -ptmalloc3.o: ptmalloc3.c malloc-2.8.3.h - $(CC) -c $(CFLAGS) $(M_FLAGS) -DMSPACES=1 $< - -malloc.o: malloc.c - $(CC) -c $(CFLAGS) $(M_FLAGS) -DONLY_MSPACES -DUSE_LOCKS=0 $< - -#malloc-stats.o: malloc-stats.c malloc.h -# $(CC) -c $(CFLAGS) $(M_FLAGS) $< - -libptmalloc3.a: $(MALLOC_OBJ) - $(AR) cr $@ $(MALLOC_OBJ) - $(RANLIB) $@ - -libptmalloc3.so: $(MALLOC_OBJ) - $(CC) $(SH_FLAGS) $(CFLAGS) $(M_FLAGS) $(MALLOC_OBJ) -o $@ - -again: - $(RM) $(TESTS) - $(MAKE) $(TESTS) - -clean: - $(RM) $(MALLOC_OBJ) libptmalloc3.a libptmalloc3.so $(TESTS) \ - core core.[0-9]* - -m-test1$(T_SUF): m-test1.c $(LIB_MALLOC) - $(CC) $(CFLAGS) $(T_FLAGS) m-test1.c $(LIB_MALLOC) $(THR_LIBS) -o $@ - -t-test1$(T_SUF): t-test1.c t-test.h $(LIB_MALLOC) - $(CC) $(CFLAGS) $(T_FLAGS) t-test1.c $(LIB_MALLOC) $(THR_LIBS) -o $@ - -t-test2$(T_SUF): t-test2.c t-test.h $(LIB_MALLOC) - $(CC) $(CFLAGS) $(T_FLAGS) t-test2.c $(LIB_MALLOC) $(THR_LIBS) -o $@ - -tst-mallocstate$(T_SUF): tst-mallocstate.c $(LIB_MALLOC) - $(CC) $(CFLAGS) $(T_FLAGS) tst-mallocstate.c $(LIB_MALLOC) \ - $(THR_LIBS) -o $@ - -tst-mstats$(T_SUF): tst-mstats.c $(LIB_MALLOC) - $(CC) $(CFLAGS) $(T_FLAGS) tst-mstats.c $(LIB_MALLOC) \ - $(THR_LIBS) -o $@ - -tst-independent-alloc$(T_SUF): tst-independent-alloc.c $(LIB_MALLOC) - $(CC) $(CFLAGS) $(T_FLAGS) tst-independent-alloc.c $(LIB_MALLOC) \ - $(THR_LIBS) -o $@ - -############################################################################ -# Platform-specific targets. The ones ending in `-libc' are provided -# to enable comparison with the standard malloc implementation from -# the system's native C library. The option USE_TSD_DATA_HACK is now -# the default for pthreads systems, as most (Irix 6, Solaris 2) seem -# to need it. Try with USE_TSD_DATA_HACK undefined only if you're -# confident that your systems's thread specific data functions do _not_ -# use malloc themselves. - -# posix threads with TSD data hack -posix: - $(MAKE) THR_FLAGS='-DUSE_TSD_DATA_HACK -D_REENTRANT' \ - OPT_FLAGS='$(OPT_FLAGS)' SYS_FLAGS='$(SYS_FLAGS)' CC='$(CC)' \ - INC_FLAGS='-Isysdeps/pthread -Isysdeps/generic -I.' - THR_LIBS=-lpthread - -# posix threads with explicit initialization. Known to be needed on HPUX. -posix-explicit: - $(MAKE) THR_FLAGS='-D_REENTRANT -DUSE_TSD_DATA_HACK -DUSE_STARTER=2' \ - THR_LIBS=-lpthread \ - OPT_FLAGS='$(OPT_FLAGS)' SYS_FLAGS='$(SYS_FLAGS)' CC='$(CC)' \ - INC_FLAGS='-Isysdeps/pthread -Isysdeps/generic -I.' \ - M_FLAGS='$(M_FLAGS)' - -# posix threads without TSD data hack -- not known to work -posix-with-tsd: - $(MAKE) THR_FLAGS='-D_REENTRANT' THR_LIBS=-lpthread \ - INC_FLAGS='-Isysdeps/pthread -Isysdeps/generic -I.' \ - M_FLAGS='$(M_FLAGS)' - -posix-libc: - $(MAKE) THR_FLAGS='-D_REENTRANT' THR_LIBS=-lpthread \ - INC_FLAGS='-Isysdeps/pthread -Isysdeps/generic -I.' \ - M_FLAGS='$(M_FLAGS)' LIB_MALLOC= T_FLAGS= T_SUF=-libc - -linux-pthread: - $(MAKE) SYS_FLAGS='-D_GNU_SOURCE=1' \ - WARN_FLAGS='-Wall -Wstrict-prototypes' \ - OPT_FLAGS='$(OPT_FLAGS)' THR_FLAGS='-DUSE_TSD_DATA_HACK' \ - INC_FLAGS='-Isysdeps/pthread -Isysdeps/generic -I.' M_FLAGS='$(M_FLAGS)' \ - TESTS='$(TESTS)' - -linux-shared: - $(MAKE) SYS_FLAGS='-D_GNU_SOURCE=1 -fpic' \ - WARN_FLAGS='-Wall -Wstrict-prototypes' \ - OPT_FLAGS='$(OPT_FLAGS)' THR_FLAGS='-DUSE_TSD_DATA_HACK' \ - INC_FLAGS='-Isysdeps/pthread -Isysdeps/generic -I.' M_FLAGS='$(M_FLAGS)' \ - LIB_MALLOC=libptmalloc3.so - -sproc: - $(MAKE) THR_FLAGS='' THR_LIBS='' OPT_FLAGS='$(OPT_FLAGS)' CC='$(CC)' \ - INC_FLAGS='-Isysdeps/sproc -Isysdeps/generic -I.' \ - M_FLAGS='$(M_FLAGS) -Dmalloc_getpagesize=4096' - -sproc-shared: - $(MAKE) THR_FLAGS='' THR_LIBS= \ - SH_FLAGS='-shared -check_registry /usr/lib/so_locations' \ - INC_FLAGS='-Isysdeps/sproc -Isysdeps/generic -I.' \ - LIB_MALLOC=libptmalloc3.so M_FLAGS='$(M_FLAGS)' - -sproc-libc: - $(MAKE) THR_FLAGS='' THR_LIBS= LIB_MALLOC= T_FLAGS= \ - INC_FLAGS='-Isysdeps/sproc -Isysdeps/generic -I.' \ - T_SUF=-libc M_FLAGS='$(M_FLAGS)' - -solaris: - $(MAKE) THR_FLAGS='-D_REENTRANT' OPT_FLAGS='$(OPT_FLAGS)' \ - INC_FLAGS='-Isysdeps/solaris -Isysdeps/generic -I.' \ - THR_LIBS=-lthread M_FLAGS='$(M_FLAGS)' - -solaris-libc: - $(MAKE) THR_FLAGS='-D_REENTRANT' OPT_FLAGS='$(OPT_FLAGS)' \ - INC_FLAGS='-Isysdeps/solaris -Isysdeps/generic -I.' \ - THR_LIBS=-lthread LIB_MALLOC= T_FLAGS= T_SUF=-libc M_FLAGS='$(M_FLAGS)' - -nothreads: - $(MAKE) OPT_FLAGS='$(OPT_FLAGS)' SYS_FLAGS='$(SYS_FLAGS)' \ - INC_FLAGS='-Isysdeps/generic -I.' \ - THR_FLAGS='' THR_LIBS='' M_FLAGS='$(M_FLAGS)' - -gcc-nothreads: - $(MAKE) CC='gcc' WARN_FLAGS='-Wall' OPT_FLAGS='$(OPT_FLAGS)' \ - INC_FLAGS='-Isysdeps/generic -I.' \ - SYS_FLAGS='$(SYS_FLAGS)' THR_FLAGS='' THR_LIBS='' M_FLAGS='$(M_FLAGS)' - -linux-nothreads: - $(MAKE) CC='gcc' WARN_FLAGS='-Wall' OPT_FLAGS='$(OPT_FLAGS)' \ - INC_FLAGS='-Isysdeps/generic -I.' \ - SYS_FLAGS='-D_GNU_SOURCE' THR_FLAGS='' THR_LIBS='' M_FLAGS='$(M_FLAGS)' - -############################################################################ - -check: $(TESTS) - ./t-test1 - ./t-test2 - #./tst-mallocstate || echo "Test mallocstate failed!" - #./tst-mstats || echo "Test mstats failed!" - -snap: - cd ..; tar $(TAR_FLAGS) -c -f - $(DIST_FILES1:%=ptmalloc3/%) | \ - gzip -9 >ptmalloc3-current.tar.gz - -dist: - cd ..; tar $(TAR_FLAGS) -c -f - $(DIST_FILES2:%=ptmalloc3/%) | \ - gzip -9 >ptmalloc3.tar.gz - -# dependencies -ptmalloc3.o: malloc-private.h diff --git a/src/3rdparty/ptmalloc/README b/src/3rdparty/ptmalloc/README deleted file mode 100644 index 914c745612..0000000000 --- a/src/3rdparty/ptmalloc/README +++ /dev/null @@ -1,186 +0,0 @@ -ptmalloc3 - a multi-thread malloc implementation -================================================ - -Wolfram Gloger (wg@malloc.de) - -Jan 2006 - - -Thanks -====== - -This release was partly funded by Pixar Animation Studios. I would -like to thank David Baraff of Pixar for his support and Doug Lea -(dl@cs.oswego.edu) for the great original malloc implementation. - - -Introduction -============ - -This package is a modified version of Doug Lea's malloc-2.8.3 -implementation (available seperately from ftp://g.oswego.edu/pub/misc) -that I adapted for multiple threads, while trying to avoid lock -contention as much as possible. - -As part of the GNU C library, the source files may be available under -the GNU Library General Public License (see the comments in the -files). But as part of this stand-alone package, the code is also -available under the (probably less restrictive) conditions described -in the file 'COPYRIGHT'. In any case, there is no warranty whatsoever -for this package. - -The current distribution should be available from: - -http://www.malloc.de/malloc/ptmalloc3.tar.gz - - -Compilation -=========== - -It should be possible to build ptmalloc3 on any UN*X-like system that -implements the sbrk(), mmap(), munmap() and mprotect() calls. Since -there are now several source files, a library (libptmalloc3.a) is -generated. See the Makefile for examples of the compile-time options. - -Note that support for non-ANSI compilers is no longer there. - -Several example targets are provided in the Makefile: - - o Posix threads (pthreads), compile with "make posix" - - o Posix threads with explicit initialization, compile with - "make posix-explicit" (known to be required on HPUX) - - o Posix threads without "tsd data hack" (see below), compile with - "make posix-with-tsd" - - o Solaris threads, compile with "make solaris" - - o SGI sproc() threads, compile with "make sproc" - - o no threads, compile with "make nothreads" (currently out of order?) - -For Linux: - - o make "linux-pthread" (almost the same as "make posix") or - make "linux-shared" - -Note that some compilers need special flags for multi-threaded code, -e.g. with Solaris cc with Posix threads, one should use: - -% make posix SYS_FLAGS='-mt' - -Some additional targets, ending in `-libc', are also provided in the -Makefile, to compare performance of the test programs to the case when -linking with the standard malloc implementation in libc. - -A potential problem remains: If any of the system-specific functions -for getting/setting thread-specific data or for locking a mutex call -one of the malloc-related functions internally, the implementation -cannot work at all due to infinite recursion. One example seems to be -Solaris 2.4. I would like to hear if this problem occurs on other -systems, and whether similar workarounds could be applied. - -For Posix threads, too, an optional hack like that has been integrated -(activated when defining USE_TSD_DATA_HACK) which depends on -`pthread_t' being convertible to an integral type (which is of course -not generally guaranteed). USE_TSD_DATA_HACK is now the default -because I haven't yet found a non-glibc pthreads system where this -hack is _not_ needed. - -*NEW* and _important_: In (currently) one place in the ptmalloc3 -source, a write memory barrier is needed, named -atomic_write_barrier(). This macro needs to be defined at the end of -malloc-machine.h. For gcc, a fallback in the form of a full memory -barrier is already defined, but you may need to add another definition -if you don't use gcc. - -Usage -===== - -Just link libptmalloc3 into your application. - -Some wicked systems (e.g. HPUX apparently) won't let malloc call _any_ -thread-related functions before main(). On these systems, -USE_STARTER=2 must be defined during compilation (see "make -posix-explicit" above) and the global initialization function -ptmalloc_init() must be called explicitly, preferably at the start of -main(). - -Otherwise, when using ptmalloc3, no special precautions are necessary. - -Link order is important -======================= - -On some systems, when overriding malloc and linking against shared -libraries, the link order becomes very important. E.g., when linking -C++ programs on Solaris with Solaris threads [this is probably now -obsolete], don't rely on libC being included by default, but instead -put `-lthread' behind `-lC' on the command line: - - CC ... libptmalloc3.a -lC -lthread - -This is because there are global constructors in libC that need -malloc/ptmalloc, which in turn needs to have the thread library to be -already initialized. - -Debugging hooks -=============== - -All calls to malloc(), realloc(), free() and memalign() are routed -through the global function pointers __malloc_hook, __realloc_hook, -__free_hook and __memalign_hook if they are not NULL (see the malloc.h -header file for declarations of these pointers). Therefore the malloc -implementation can be changed at runtime, if care is taken not to call -free() or realloc() on pointers obtained with a different -implementation than the one currently in effect. (The easiest way to -guarantee this is to set up the hooks before any malloc call, e.g. -with a function pointed to by the global variable -__malloc_initialize_hook). - -You can now also tune other malloc parameters (normally adjused via -mallopt() calls from the application) with environment variables: - - MALLOC_TRIM_THRESHOLD_ for deciding to shrink the heap (in bytes) - - MALLOC_GRANULARITY_ The unit for allocating and deallocating - MALLOC_TOP_PAD_ memory from the system. The default - is 64k and this parameter _must_ be a - power of 2. - - MALLOC_MMAP_THRESHOLD_ min. size for chunks allocated via - mmap() (in bytes) - -Tests -===== - -Two testing applications, t-test1 and t-test2, are included in this -source distribution. Both perform pseudo-random sequences of -allocations/frees, and can be given numeric arguments (all arguments -are optional): - -% t-test[12] - - n-total = total number of threads executed (default 10) - n-parallel = number of threads running in parallel (2) - n-allocs = number of malloc()'s / free()'s per thread (10000) - size-max = max. size requested with malloc() in bytes (10000) - bins = number of bins to maintain - -The first test `t-test1' maintains a completely seperate pool of -allocated bins for each thread, and should therefore show full -parallelism. On the other hand, `t-test2' creates only a single pool -of bins, and each thread randomly allocates/frees any bin. Some lock -contention is to be expected in this case, as the threads frequently -cross each others arena. - -Performance results from t-test1 should be quite repeatable, while the -behaviour of t-test2 depends on scheduling variations. - -Conclusion -========== - -I'm always interested in performance data and feedback, just send mail -to ptmalloc@malloc.de. - -Good luck! diff --git a/src/3rdparty/ptmalloc/lran2.h b/src/3rdparty/ptmalloc/lran2.h deleted file mode 100644 index cea9920282..0000000000 --- a/src/3rdparty/ptmalloc/lran2.h +++ /dev/null @@ -1,51 +0,0 @@ -/* lran2.h - * by Wolfram Gloger 1996. - * - * A small, portable pseudo-random number generator. - */ - -#ifndef _LRAN2_H -#define _LRAN2_H - -#define LRAN2_MAX 714025l /* constants for portable */ -#define IA 1366l /* random number generator */ -#define IC 150889l /* (see e.g. `Numerical Recipes') */ - -struct lran2_st { - long x, y, v[97]; -}; - -static void -lran2_init(struct lran2_st* d, long seed) -{ - long x; - int j; - - x = (IC - seed) % LRAN2_MAX; - if(x < 0) x = -x; - for(j=0; j<97; j++) { - x = (IA*x + IC) % LRAN2_MAX; - d->v[j] = x; - } - d->x = (IA*x + IC) % LRAN2_MAX; - d->y = d->x; -} - -#ifdef __GNUC__ -__inline__ -#endif -static long -lran2(struct lran2_st* d) -{ - int j = (d->y % 97); - - d->y = d->v[j]; - d->x = (IA*d->x + IC) % LRAN2_MAX; - d->v[j] = d->x; - return d->y; -} - -#undef IA -#undef IC - -#endif diff --git a/src/3rdparty/ptmalloc/malloc-2.8.3.h b/src/3rdparty/ptmalloc/malloc-2.8.3.h deleted file mode 100644 index 62f597e5f5..0000000000 --- a/src/3rdparty/ptmalloc/malloc-2.8.3.h +++ /dev/null @@ -1,534 +0,0 @@ -/* - Default header file for malloc-2.8.x, written by Doug Lea - and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. - - last update: Mon Aug 15 08:55:52 2005 Doug Lea (dl at gee) - - This header is for ANSI C/C++ only. You can set any of - the following #defines before including: - - * If USE_DL_PREFIX is defined, it is assumed that malloc.c - was also compiled with this option, so all routines - have names starting with "dl". - - * If HAVE_USR_INCLUDE_MALLOC_H is defined, it is assumed that this - file will be #included AFTER . This is needed only if - your system defines a struct mallinfo that is incompatible with the - standard one declared here. Otherwise, you can include this file - INSTEAD of your system system . At least on ANSI, all - declarations should be compatible with system versions - - * If MSPACES is defined, declarations for mspace versions are included. -*/ - -#ifndef MALLOC_280_H -#define MALLOC_280_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include /* for size_t */ - -#if !ONLY_MSPACES - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign memalign -#define dlrealloc realloc -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ - - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -void* dlmalloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cuase the current program to abort. -*/ -void dlfree(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* dlcalloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ - -void* dlrealloc(void*, size_t); - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* dlmemalign(size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* dlvalloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt: - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (-1U disables trimming) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -int dlmallopt(int, int); - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -size_t dlmalloc_footprint(void); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ -#ifndef HAVE_USR_INCLUDE_MALLOC_H -#ifndef _MALLOC_H -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -struct mallinfo { - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; -#endif /* _MALLOC_H */ -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ - -struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -void** dlindependent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -void** dlindependent_comalloc(size_t, size_t*, void**); - - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* dlpvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -int dlmalloc_trim(size_t); - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t dlmalloc_usable_size(void*); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ -void dlmalloc_stats(void); - -#endif /* !ONLY_MSPACES */ - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -mspace create_mspace(size_t capacity, int locked); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ -void* mspace_malloc(mspace msp, size_t bytes); - -/* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ -void mspace_free(mspace msp, void* mem); - -/* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ -void* mspace_realloc(mspace msp, void* mem, size_t newsize); - -/* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - -/* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); - -/* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); - -/* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); - -/* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ -size_t mspace_footprint(mspace msp); - - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ -void mspace_malloc_stats(mspace msp); - -/* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ -int mspace_trim(mspace msp, size_t pad); - -/* - An alias for malloc_usable_size. -*/ -size_t mspace_usable_size(void *mem); - -/* - An alias for mallopt. -*/ -int mspace_mallopt(int, int); - -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif - -#endif /* MALLOC_280_H */ diff --git a/src/3rdparty/ptmalloc/malloc-private.h b/src/3rdparty/ptmalloc/malloc-private.h deleted file mode 100644 index 680c36bac0..0000000000 --- a/src/3rdparty/ptmalloc/malloc-private.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - $Id: malloc-private.h,v 1.4 2006/03/31 12:56:52 wg Exp $ - Private header file for ptmalloc3, created by Wolfram Gloger - and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. -*/ - -/* The following file is replicated from malloc.c */ - -#ifndef MALLOC_PRIVATE_H -#define MALLOC_PRIVATE_H - -#ifndef MALLOC_ALIGNMENT -# define MALLOC_ALIGNMENT ((size_t)8U) -#endif -#ifndef USE_LOCKS -# define USE_LOCKS 0 -#endif - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A)\ - ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ - ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) - -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANON */ -#ifdef MAP_ANONYMOUS -#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) -#define CALL_MMAP(s) mmap(0, (s), PROT_READ|PROT_WRITE, MMAP_FLAGS, -1, 0) -#else /* MAP_ANONYMOUS */ -/* - Nearly all versions of mmap support MAP_ANONYMOUS, so the following - is unlikely to be needed, but is supplied just in case. -*/ -#include /* for O_RDWR */ -#define MMAP_FLAGS (MAP_PRIVATE) -static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ -#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \ - (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap(0, (s), PROT_READ|PROT_WRITE, MMAP_FLAGS, dev_zero_fd, 0)) : \ - mmap(0, (s), PROT_READ|PROT_WRITE, MMAP_FLAGS, dev_zero_fd, 0)) -#endif /* MAP_ANONYMOUS */ -#define CALL_MUNMAP(a, s) munmap((a), (s)) - -struct malloc_chunk { - size_t prev_foot; /* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk* fd; /* double links -- used only if free. */ - struct malloc_chunk* bk; -}; - -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk* mchunkptr; - -typedef unsigned int binmap_t; -typedef unsigned int flag_t; - -struct malloc_tree_chunk; -typedef struct malloc_tree_chunk* tbinptr; - -struct malloc_segment { - char* base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment* next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -typedef struct malloc_segment msegment; - -#define NSMALLBINS (32U) -#define NTREEBINS (32U) - -struct malloc_state { - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char* least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t release_checks; - size_t magic; - mchunkptr smallbins[(NSMALLBINS+1)*2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - flag_t mflags; -#if USE_LOCKS - MLOCK_T mutex; -#endif /* USE_LOCKS */ - msegment seg; - void* extp; - size_t exts; -}; - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE\ - (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) - -/* ------------------- Chunks sizes and alignments ----------------------- */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#define CHUNK_OVERHEAD (SIZE_T_SIZE) - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE\ - ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some platforms */ -#define SIZE_T_ZERO ((size_t)0) -#define SIZE_T_ONE ((size_t)1) -#define SIZE_T_TWO ((size_t)2) -#define SIZE_T_FOUR ((size_t)4) -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) -#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) - -#define IS_MMAPPED_BIT (SIZE_T_ONE) -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|SIZE_T_FOUR) - -/* head field is or'ed with NON_MAIN_ARENA if the chunk was obtained - from a non-main arena. This is only set immediately before handing - the chunk to the user, if necessary. */ -#define NON_MAIN_ARENA (SIZE_T_FOUR) - -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define chunksize(p) ((p)->head & ~(FLAG_BITS)) - -#define is_mmapped(p)\ - (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p)\ - (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -#endif /* MALLOC_PRIVATE_H */ diff --git a/src/3rdparty/ptmalloc/malloc.c b/src/3rdparty/ptmalloc/malloc.c deleted file mode 100644 index 2778b304ad..0000000000 --- a/src/3rdparty/ptmalloc/malloc.c +++ /dev/null @@ -1,5515 +0,0 @@ -/* - $Id: malloc.c,v 1.4 2006/03/30 16:47:29 wg Exp $ - - This version of malloc.c was adapted for ptmalloc3 by Wolfram Gloger - . Therefore, some of the comments below do not apply - for this modified version. However, it is the intention to keep - differences to Doug Lea's original version minimal, hence the - comments were mostly left unchanged. - - ----------------------------------------------------------------------- - - This is a version (aka dlmalloc) of malloc/free/realloc written by - Doug Lea and released to the public domain, as explained at - http://creativecommons.org/licenses/publicdomain. Send questions, - comments, complaints, performance data, etc to dl@cs.oswego.edu - -* Version pre-2.8.4 Wed Mar 29 19:46:29 2006 (dl at gee) - - Note: There may be an updated version of this malloc obtainable at - ftp://gee.cs.oswego.edu/pub/misc/malloc.c - Check before installing! - -* Quickstart - - This library is all in one file to simplify the most common usage: - ftp it, compile it (-O3), and link it into another program. All of - the compile-time options default to reasonable values for use on - most platforms. You might later want to step through various - compile-time and dynamic tuning options. - - For convenience, an include file for code using this malloc is at: - ftp://gee.cs.oswego.edu/pub/misc/malloc-2.8.3.h - You don't really need this .h file unless you call functions not - defined in your system include files. The .h file contains only the - excerpts from this file needed for using this malloc on ANSI C/C++ - systems, so long as you haven't changed compile-time options about - naming and tuning parameters. If you do, then you can create your - own malloc.h that does include all settings by cutting at the point - indicated below. Note that you may already by default be using a C - library containing a malloc that is based on some version of this - malloc (for example in linux). You might still want to use the one - in this file to customize settings or to avoid overheads associated - with library versions. - -* Vital statistics: - - Supported pointer/size_t representation: 4 or 8 bytes - size_t MUST be an unsigned type of the same width as - pointers. (If you are using an ancient system that declares - size_t as a signed type, or need it to be a different width - than pointers, you can use a previous release of this malloc - (e.g. 2.7.2) supporting these.) - - Alignment: 8 bytes (default) - This suffices for nearly all current machines and C compilers. - However, you can define MALLOC_ALIGNMENT to be wider than this - if necessary (up to 128bytes), at the expense of using more space. - - Minimum overhead per allocated chunk: 4 or 8 bytes (if 4byte sizes) - 8 or 16 bytes (if 8byte sizes) - Each malloced chunk has a hidden word of overhead holding size - and status information, and additional cross-check word - if FOOTERS is defined. - - Minimum allocated size: 4-byte ptrs: 16 bytes (including overhead) - 8-byte ptrs: 32 bytes (including overhead) - - Even a request for zero bytes (i.e., malloc(0)) returns a - pointer to something of the minimum allocatable size. - The maximum overhead wastage (i.e., number of extra bytes - allocated than were requested in malloc) is less than or equal - to the minimum size, except for requests >= mmap_threshold that - are serviced via mmap(), where the worst case wastage is about - 32 bytes plus the remainder from a system page (the minimal - mmap unit); typically 4096 or 8192 bytes. - - Security: static-safe; optionally more or less - The "security" of malloc refers to the ability of malicious - code to accentuate the effects of errors (for example, freeing - space that is not currently malloc'ed or overwriting past the - ends of chunks) in code that calls malloc. This malloc - guarantees not to modify any memory locations below the base of - heap, i.e., static variables, even in the presence of usage - errors. The routines additionally detect most improper frees - and reallocs. All this holds as long as the static bookkeeping - for malloc itself is not corrupted by some other means. This - is only one aspect of security -- these checks do not, and - cannot, detect all possible programming errors. - - If FOOTERS is defined nonzero, then each allocated chunk - carries an additional check word to verify that it was malloced - from its space. These check words are the same within each - execution of a program using malloc, but differ across - executions, so externally crafted fake chunks cannot be - freed. This improves security by rejecting frees/reallocs that - could corrupt heap memory, in addition to the checks preventing - writes to statics that are always on. This may further improve - security at the expense of time and space overhead. (Note that - FOOTERS may also be worth using with MSPACES.) - - By default detected errors cause the program to abort (calling - "abort()"). You can override this to instead proceed past - errors by defining PROCEED_ON_ERROR. In this case, a bad free - has no effect, and a malloc that encounters a bad address - caused by user overwrites will ignore the bad address by - dropping pointers and indices to all known memory. This may - be appropriate for programs that should continue if at all - possible in the face of programming errors, although they may - run out of memory because dropped memory is never reclaimed. - - If you don't like either of these options, you can define - CORRUPTION_ERROR_ACTION and USAGE_ERROR_ACTION to do anything - else. And if if you are sure that your program using malloc has - no errors or vulnerabilities, you can define INSECURE to 1, - which might (or might not) provide a small performance improvement. - - Thread-safety: NOT thread-safe unless USE_LOCKS defined - When USE_LOCKS is defined, each public call to malloc, free, - etc is surrounded with either a pthread mutex or a win32 - spinlock (depending on WIN32). This is not especially fast, and - can be a major bottleneck. It is designed only to provide - minimal protection in concurrent environments, and to provide a - basis for extensions. If you are using malloc in a concurrent - program, consider instead using nedmalloc - (http://www.nedprod.com/programs/portable/nedmalloc/) or - ptmalloc (See http://www.malloc.de), which are derived - from versions of this malloc. - - System requirements: Any combination of MORECORE and/or MMAP/MUNMAP - This malloc can use unix sbrk or any emulation (invoked using - the CALL_MORECORE macro) and/or mmap/munmap or any emulation - (invoked using CALL_MMAP/CALL_MUNMAP) to get and release system - memory. On most unix systems, it tends to work best if both - MORECORE and MMAP are enabled. On Win32, it uses emulations - based on VirtualAlloc. It also uses common C library functions - like memset. - - Compliance: I believe it is compliant with the Single Unix Specification - (See http://www.unix.org). Also SVID/XPG, ANSI C, and probably - others as well. - -* Overview of algorithms - - This is not the fastest, most space-conserving, most portable, or - most tunable malloc ever written. However it is among the fastest - while also being among the most space-conserving, portable and - tunable. Consistent balance across these factors results in a good - general-purpose allocator for malloc-intensive programs. - - In most ways, this malloc is a best-fit allocator. Generally, it - chooses the best-fitting existing chunk for a request, with ties - broken in approximately least-recently-used order. (This strategy - normally maintains low fragmentation.) However, for requests less - than 256bytes, it deviates from best-fit when there is not an - exactly fitting available chunk by preferring to use space adjacent - to that used for the previous small request, as well as by breaking - ties in approximately most-recently-used order. (These enhance - locality of series of small allocations.) And for very large requests - (>= 256Kb by default), it relies on system memory mapping - facilities, if supported. (This helps avoid carrying around and - possibly fragmenting memory used only for large chunks.) - - All operations (except malloc_stats and mallinfo) have execution - times that are bounded by a constant factor of the number of bits in - a size_t, not counting any clearing in calloc or copying in realloc, - or actions surrounding MORECORE and MMAP that have times - proportional to the number of non-contiguous regions returned by - system allocation routines, which is often just 1. In real-time - applications, you can optionally suppress segment traversals using - NO_SEGMENT_TRAVERSAL, which assures bounded execution even when - system allocators return non-contiguous spaces, at the typical - expense of carrying around more memory and increased fragmentation. - - The implementation is not very modular and seriously overuses - macros. Perhaps someday all C compilers will do as good a job - inlining modular code as can now be done by brute-force expansion, - but now, enough of them seem not to. - - Some compilers issue a lot of warnings about code that is - dead/unreachable only on some platforms, and also about intentional - uses of negation on unsigned types. All known cases of each can be - ignored. - - For a longer but out of date high-level description, see - http://gee.cs.oswego.edu/dl/html/malloc.html - -* MSPACES - If MSPACES is defined, then in addition to malloc, free, etc., - this file also defines mspace_malloc, mspace_free, etc. These - are versions of malloc routines that take an "mspace" argument - obtained using create_mspace, to control all internal bookkeeping. - If ONLY_MSPACES is defined, only these versions are compiled. - So if you would like to use this allocator for only some allocations, - and your system malloc for others, you can compile with - ONLY_MSPACES and then do something like... - static mspace mymspace = create_mspace(0,0); // for example - #define mymalloc(bytes) mspace_malloc(mymspace, bytes) - - (Note: If you only need one instance of an mspace, you can instead - use "USE_DL_PREFIX" to relabel the global malloc.) - - You can similarly create thread-local allocators by storing - mspaces as thread-locals. For example: - static __thread mspace tlms = 0; - void* tlmalloc(size_t bytes) { - if (tlms == 0) tlms = create_mspace(0, 0); - return mspace_malloc(tlms, bytes); - } - void tlfree(void* mem) { mspace_free(tlms, mem); } - - Unless FOOTERS is defined, each mspace is completely independent. - You cannot allocate from one and free to another (although - conformance is only weakly checked, so usage errors are not always - caught). If FOOTERS is defined, then each chunk carries around a tag - indicating its originating mspace, and frees are directed to their - originating spaces. - - ------------------------- Compile-time options --------------------------- - -Be careful in setting #define values for numerical constants of type -size_t. On some systems, literal values are not automatically extended -to size_t precision unless they are explicitly casted. You can also -use the symbolic values MAX_SIZE_T, SIZE_T_ONE, etc below. - -WIN32 default: defined if _WIN32 defined - Defining WIN32 sets up defaults for MS environment and compilers. - Otherwise defaults are for unix. - -MALLOC_ALIGNMENT default: (size_t)8 - Controls the minimum alignment for malloc'ed chunks. It must be a - power of two and at least 8, even on machines for which smaller - alignments would suffice. It may be defined as larger than this - though. Note however that code and data structures are optimized for - the case of 8-byte alignment. - -MSPACES default: 0 (false) - If true, compile in support for independent allocation spaces. - This is only supported if HAVE_MMAP is true. - -ONLY_MSPACES default: 0 (false) - If true, only compile in mspace versions, not regular versions. - -USE_LOCKS default: 0 (false) - Causes each call to each public routine to be surrounded with - pthread or WIN32 mutex lock/unlock. (If set true, this can be - overridden on a per-mspace basis for mspace versions.) If set to a - non-zero value other than 1, locks are used, but their - implementation is left out, so lock functions must be supplied manually. - -USE_SPIN_LOCKS default: 1 iff USE_LOCKS and on x86 using gcc or MSC - If true, uses custom spin locks for locking. This is currently - supported only for x86 platforms using gcc or recent MS compilers. - Otherwise, posix locks or win32 critical sections are used. - -FOOTERS default: 0 - If true, provide extra checking and dispatching by placing - information in the footers of allocated chunks. This adds - space and time overhead. - -INSECURE default: 0 - If true, omit checks for usage errors and heap space overwrites. - -USE_DL_PREFIX default: NOT defined - Causes compiler to prefix all public routines with the string 'dl'. - This can be useful when you only want to use this malloc in one part - of a program, using your regular system malloc elsewhere. - -ABORT default: defined as abort() - Defines how to abort on failed checks. On most systems, a failed - check cannot die with an "assert" or even print an informative - message, because the underlying print routines in turn call malloc, - which will fail again. Generally, the best policy is to simply call - abort(). It's not very useful to do more than this because many - errors due to overwriting will show up as address faults (null, odd - addresses etc) rather than malloc-triggered checks, so will also - abort. Also, most compilers know that abort() does not return, so - can better optimize code conditionally calling it. - -PROCEED_ON_ERROR default: defined as 0 (false) - Controls whether detected bad addresses cause them to bypassed - rather than aborting. If set, detected bad arguments to free and - realloc are ignored. And all bookkeeping information is zeroed out - upon a detected overwrite of freed heap space, thus losing the - ability to ever return it from malloc again, but enabling the - application to proceed. If PROCEED_ON_ERROR is defined, the - static variable malloc_corruption_error_count is compiled in - and can be examined to see if errors have occurred. This option - generates slower code than the default abort policy. - -DEBUG default: NOT defined - The DEBUG setting is mainly intended for people trying to modify - this code or diagnose problems when porting to new platforms. - However, it may also be able to better isolate user errors than just - using runtime checks. The assertions in the check routines spell - out in more detail the assumptions and invariants underlying the - algorithms. The checking is fairly extensive, and will slow down - execution noticeably. Calling malloc_stats or mallinfo with DEBUG - set will attempt to check every non-mmapped allocated and free chunk - in the course of computing the summaries. - -ABORT_ON_ASSERT_FAILURE default: defined as 1 (true) - Debugging assertion failures can be nearly impossible if your - version of the assert macro causes malloc to be called, which will - lead to a cascade of further failures, blowing the runtime stack. - ABORT_ON_ASSERT_FAILURE cause assertions failures to call abort(), - which will usually make debugging easier. - -MALLOC_FAILURE_ACTION default: sets errno to ENOMEM, or no-op on win32 - The action to take before "return 0" when malloc fails to be able to - return memory because there is none available. - -HAVE_MORECORE default: 1 (true) unless win32 or ONLY_MSPACES - True if this system supports sbrk or an emulation of it. - -MORECORE default: sbrk - The name of the sbrk-style system routine to call to obtain more - memory. See below for guidance on writing custom MORECORE - functions. The type of the argument to sbrk/MORECORE varies across - systems. It cannot be size_t, because it supports negative - arguments, so it is normally the signed type of the same width as - size_t (sometimes declared as "intptr_t"). It doesn't much matter - though. Internally, we only call it with arguments less than half - the max value of a size_t, which should work across all reasonable - possibilities, although sometimes generating compiler warnings. See - near the end of this file for guidelines for creating a custom - version of MORECORE. - -MORECORE_CONTIGUOUS default: 1 (true) if HAVE_MORECORE - If true, take advantage of fact that consecutive calls to MORECORE - with positive arguments always return contiguous increasing - addresses. This is true of unix sbrk. It does not hurt too much to - set it true anyway, since malloc copes with non-contiguities. - Setting it false when definitely non-contiguous saves time - and possibly wasted space it would take to discover this though. - -MORECORE_CANNOT_TRIM default: NOT defined - True if MORECORE cannot release space back to the system when given - negative arguments. This is generally necessary only if you are - using a hand-crafted MORECORE function that cannot handle negative - arguments. - -NO_SEGMENT_TRAVERSAL default: 0 - If non-zero, suppresses traversals of memory segments - returned by either MORECORE or CALL_MMAP. This disables - merging of segments that are contiguous, and selectively - releasing them to the OS if unused, but bounds execution times. - -HAVE_MMAP default: 1 (true) - True if this system supports mmap or an emulation of it. If so, and - HAVE_MORECORE is not true, MMAP is used for all system - allocation. If set and HAVE_MORECORE is true as well, MMAP is - primarily used to directly allocate very large blocks. It is also - used as a backup strategy in cases where MORECORE fails to provide - space from system. Note: A single call to MUNMAP is assumed to be - able to unmap memory that may have be allocated using multiple calls - to MMAP, so long as they are adjacent. - -HAVE_MREMAP default: 1 on linux, else 0 - If true realloc() uses mremap() to re-allocate large blocks and - extend or shrink allocation spaces. - -MMAP_CLEARS default: 1 except on WINCE. - True if mmap clears memory so calloc doesn't need to. This is true - for standard unix mmap using /dev/zero and on WIN32 except for WINCE. - -USE_BUILTIN_FFS default: 0 (i.e., not used) - Causes malloc to use the builtin ffs() function to compute indices. - Some compilers may recognize and intrinsify ffs to be faster than the - supplied C version. Also, the case of x86 using gcc is special-cased - to an asm instruction, so is already as fast as it can be, and so - this setting has no effect. Similarly for Win32 under recent MS compilers. - (On most x86s, the asm version is only slightly faster than the C version.) - -malloc_getpagesize default: derive from system includes, or 4096. - The system page size. To the extent possible, this malloc manages - memory from the system in page-size units. This may be (and - usually is) a function rather than a constant. This is ignored - if WIN32, where page size is determined using getSystemInfo during - initialization. - -USE_DEV_RANDOM default: 0 (i.e., not used) - Causes malloc to use /dev/random to initialize secure magic seed for - stamping footers. Otherwise, the current time is used. - -NO_MALLINFO default: 0 - If defined, don't compile "mallinfo". This can be a simple way - of dealing with mismatches between system declarations and - those in this file. - -MALLINFO_FIELD_TYPE default: size_t - The type of the fields in the mallinfo struct. This was originally - defined as "int" in SVID etc, but is more usefully defined as - size_t. The value is used only if HAVE_USR_INCLUDE_MALLOC_H is not set - -REALLOC_ZERO_BYTES_FREES default: not defined - This should be set if a call to realloc with zero bytes should - be the same as a call to free. Some people think it should. Otherwise, - since this malloc returns a unique pointer for malloc(0), so does - realloc(p, 0). - -LACKS_UNISTD_H, LACKS_FCNTL_H, LACKS_SYS_PARAM_H, LACKS_SYS_MMAN_H -LACKS_STRINGS_H, LACKS_STRING_H, LACKS_SYS_TYPES_H, LACKS_ERRNO_H -LACKS_STDLIB_H default: NOT defined unless on WIN32 - Define these if your system does not have these header files. - You might need to manually insert some of the declarations they provide. - -DEFAULT_GRANULARITY default: page size if MORECORE_CONTIGUOUS, - system_info.dwAllocationGranularity in WIN32, - otherwise 64K. - Also settable using mallopt(M_GRANULARITY, x) - The unit for allocating and deallocating memory from the system. On - most systems with contiguous MORECORE, there is no reason to - make this more than a page. However, systems with MMAP tend to - either require or encourage larger granularities. You can increase - this value to prevent system allocation functions to be called so - often, especially if they are slow. The value must be at least one - page and must be a power of two. Setting to 0 causes initialization - to either page size or win32 region size. (Note: In previous - versions of malloc, the equivalent of this option was called - "TOP_PAD") - -DEFAULT_TRIM_THRESHOLD default: 2MB - Also settable using mallopt(M_TRIM_THRESHOLD, x) - The maximum amount of unused top-most memory to keep before - releasing via malloc_trim in free(). Automatic trimming is mainly - useful in long-lived programs using contiguous MORECORE. Because - trimming via sbrk can be slow on some systems, and can sometimes be - wasteful (in cases where programs immediately afterward allocate - more large chunks) the value should be high enough so that your - overall system performance would improve by releasing this much - memory. As a rough guide, you might set to a value close to the - average size of a process (program) running on your system. - Releasing this much memory would allow such a process to run in - memory. Generally, it is worth tuning trim thresholds when a - program undergoes phases where several large chunks are allocated - and released in ways that can reuse each other's storage, perhaps - mixed with phases where there are no such chunks at all. The trim - value must be greater than page size to have any useful effect. To - disable trimming completely, you can set to MAX_SIZE_T. Note that the trick - some people use of mallocing a huge space and then freeing it at - program startup, in an attempt to reserve system memory, doesn't - have the intended effect under automatic trimming, since that memory - will immediately be returned to the system. - -DEFAULT_MMAP_THRESHOLD default: 256K - Also settable using mallopt(M_MMAP_THRESHOLD, x) - The request size threshold for using MMAP to directly service a - request. Requests of at least this size that cannot be allocated - using already-existing space will be serviced via mmap. (If enough - normal freed space already exists it is used instead.) Using mmap - segregates relatively large chunks of memory so that they can be - individually obtained and released from the host system. A request - serviced through mmap is never reused by any other request (at least - not directly; the system may just so happen to remap successive - requests to the same locations). Segregating space in this way has - the benefits that: Mmapped space can always be individually released - back to the system, which helps keep the system level memory demands - of a long-lived program low. Also, mapped memory doesn't become - `locked' between other chunks, as can happen with normally allocated - chunks, which means that even trimming via malloc_trim would not - release them. However, it has the disadvantage that the space - cannot be reclaimed, consolidated, and then used to service later - requests, as happens with normal chunks. The advantages of mmap - nearly always outweigh disadvantages for "large" chunks, but the - value of "large" may vary across systems. The default is an - empirically derived value that works well in most systems. You can - disable mmap by setting to MAX_SIZE_T. - -MAX_RELEASE_CHECK_RATE default: 255 unless not HAVE_MMAP - The number of consolidated frees between checks to release - unused segments when freeing. When using non-contiguous segments, - especially with multiple mspaces, checking only for topmost space - doesn't always suffice to trigger trimming. To compensate for this, - free() will, with a period of MAX_RELEASE_CHECK_RATE (or the - current number of segments, if greater) try to release unused - segments to the OS when freeing chunks that result in - consolidation. The best value for this parameter is a compromise - between slowing down frees with relatively costly checks that - rarely trigger versus holding on to unused memory. To effectively - disable, set to MAX_SIZE_T. This may lead to a very slight speed - improvement at the expense of carrying around more memory. -*/ - -#ifndef WIN32 -#ifdef _WIN32 -#define WIN32 1 -#endif /* _WIN32 */ -#endif /* WIN32 */ -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include -#define HAVE_MMAP 1 -#define HAVE_MORECORE 0 -#define LACKS_UNISTD_H -#define LACKS_SYS_PARAM_H -#define LACKS_SYS_MMAN_H -#define LACKS_STRING_H -#define LACKS_STRINGS_H -#define LACKS_SYS_TYPES_H -#define LACKS_ERRNO_H -#define MALLOC_FAILURE_ACTION -#ifdef _WIN32_WCE /* WINCE reportedly does not clear */ -#define MMAP_CLEARS 0 -#else -#define MMAP_CLEARS 1 -#endif /* _WIN32_WCE */ -#endif /* WIN32 */ - -#if defined(DARWIN) || defined(_DARWIN) -/* Mac OSX docs advise not to use sbrk; it seems better to use mmap */ -#ifndef HAVE_MORECORE -#define HAVE_MORECORE 0 -#define HAVE_MMAP 1 -#endif /* HAVE_MORECORE */ -#endif /* DARWIN */ - -#ifndef LACKS_SYS_TYPES_H -#include /* For size_t */ -#endif /* LACKS_SYS_TYPES_H */ - -/* The maximum possible size_t value has all bits set */ -#define MAX_SIZE_T (~(size_t)0) - -#ifndef ONLY_MSPACES -#define ONLY_MSPACES 0 -#endif /* ONLY_MSPACES */ -#ifndef MSPACES -#if ONLY_MSPACES -#define MSPACES 1 -#else /* ONLY_MSPACES */ -#define MSPACES 0 -#endif /* ONLY_MSPACES */ -#endif /* MSPACES */ -#ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT ((size_t)8U) -#endif /* MALLOC_ALIGNMENT */ -#ifndef FOOTERS -#define FOOTERS 0 -#endif /* FOOTERS */ -#ifndef ABORT -#define ABORT abort() -#endif /* ABORT */ -#ifndef ABORT_ON_ASSERT_FAILURE -#define ABORT_ON_ASSERT_FAILURE 1 -#endif /* ABORT_ON_ASSERT_FAILURE */ -#ifndef PROCEED_ON_ERROR -#define PROCEED_ON_ERROR 0 -#endif /* PROCEED_ON_ERROR */ -#ifndef USE_LOCKS -#define USE_LOCKS 0 -#endif /* USE_LOCKS */ -#ifndef USE_SPIN_LOCKS -#if USE_LOCKS && (defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))) || (defined(_MSC_VER) && _MSC_VER>=1310) -#define USE_SPIN_LOCKS 1 -#else -#define USE_SPIN_LOCKS 0 -#endif /* USE_LOCKS && ... */ -#endif /* USE_SPIN_LOCKS */ -#ifndef INSECURE -#define INSECURE 0 -#endif /* INSECURE */ -#ifndef HAVE_MMAP -#define HAVE_MMAP 1 -#endif /* HAVE_MMAP */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif /* MMAP_CLEARS */ -#ifndef HAVE_MREMAP -#ifdef linux -#define HAVE_MREMAP 1 -#else /* linux */ -#define HAVE_MREMAP 0 -#endif /* linux */ -#endif /* HAVE_MREMAP */ -#ifndef MALLOC_FAILURE_ACTION -#define MALLOC_FAILURE_ACTION errno = ENOMEM; -#endif /* MALLOC_FAILURE_ACTION */ -#ifndef HAVE_MORECORE -#if ONLY_MSPACES -#define HAVE_MORECORE 0 -#else /* ONLY_MSPACES */ -#define HAVE_MORECORE 1 -#endif /* ONLY_MSPACES */ -#endif /* HAVE_MORECORE */ -#if !HAVE_MORECORE -#define MORECORE_CONTIGUOUS 0 -#else /* !HAVE_MORECORE */ -#ifndef MORECORE -#define MORECORE sbrk -#endif /* MORECORE */ -#ifndef MORECORE_CONTIGUOUS -#define MORECORE_CONTIGUOUS 1 -#endif /* MORECORE_CONTIGUOUS */ -#endif /* HAVE_MORECORE */ -#ifndef DEFAULT_GRANULARITY -#if MORECORE_CONTIGUOUS -#define DEFAULT_GRANULARITY (0) /* 0 means to compute in init_mparams */ -#else /* MORECORE_CONTIGUOUS */ -#define DEFAULT_GRANULARITY ((size_t)64U * (size_t)1024U) -#endif /* MORECORE_CONTIGUOUS */ -#endif /* DEFAULT_GRANULARITY */ -#ifndef DEFAULT_TRIM_THRESHOLD -#ifndef MORECORE_CANNOT_TRIM -#define DEFAULT_TRIM_THRESHOLD ((size_t)2U * (size_t)1024U * (size_t)1024U) -#else /* MORECORE_CANNOT_TRIM */ -#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T -#endif /* MORECORE_CANNOT_TRIM */ -#endif /* DEFAULT_TRIM_THRESHOLD */ -#ifndef DEFAULT_MMAP_THRESHOLD -#if HAVE_MMAP -#define DEFAULT_MMAP_THRESHOLD ((size_t)256U * (size_t)1024U) -#else /* HAVE_MMAP */ -#define DEFAULT_MMAP_THRESHOLD MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* DEFAULT_MMAP_THRESHOLD */ -#ifndef MAX_RELEASE_CHECK_RATE -#if HAVE_MMAP -#define MAX_RELEASE_CHECK_RATE 255 -#else -#define MAX_RELEASE_CHECK_RATE MAX_SIZE_T -#endif /* HAVE_MMAP */ -#endif /* MAX_RELEASE_CHECK_RATE */ -#ifndef USE_BUILTIN_FFS -#define USE_BUILTIN_FFS 0 -#endif /* USE_BUILTIN_FFS */ -#ifndef USE_DEV_RANDOM -#define USE_DEV_RANDOM 0 -#endif /* USE_DEV_RANDOM */ -#ifndef NO_MALLINFO -#define NO_MALLINFO 0 -#endif /* NO_MALLINFO */ -#ifndef MALLINFO_FIELD_TYPE -#define MALLINFO_FIELD_TYPE size_t -#endif /* MALLINFO_FIELD_TYPE */ -#ifndef NO_SEGMENT_TRAVERSAL -#define NO_SEGMENT_TRAVERSAL 0 -#endif /* NO_SEGMENT_TRAVERSAL */ - -/* - mallopt tuning options. SVID/XPG defines four standard parameter - numbers for mallopt, normally defined in malloc.h. None of these - are used in this malloc, so setting them has no effect. But this - malloc does support the following options. -*/ - -#define M_TRIM_THRESHOLD (-1) -#define M_GRANULARITY (-2) -#define M_MMAP_THRESHOLD (-3) - -/* ------------------------ Mallinfo declarations ------------------------ */ - -#if !NO_MALLINFO -/* - This version of malloc supports the standard SVID/XPG mallinfo - routine that returns a struct containing usage properties and - statistics. It should work on any system that has a - /usr/include/malloc.h defining struct mallinfo. The main - declaration needed is the mallinfo struct that is returned (by-copy) - by mallinfo(). The malloinfo struct contains a bunch of fields that - are not even meaningful in this version of malloc. These fields are - are instead filled by mallinfo() with other numbers that might be of - interest. - - HAVE_USR_INCLUDE_MALLOC_H should be set if you have a - /usr/include/malloc.h file that includes a declaration of struct - mallinfo. If so, it is included; else a compliant version is - declared below. These must be precisely the same for mallinfo() to - work. The original SVID version of this struct, defined on most - systems with mallinfo, declares all fields as ints. But some others - define as unsigned long. If your system defines the fields using a - type of different width than listed here, you MUST #include your - system version and #define HAVE_USR_INCLUDE_MALLOC_H. -*/ - -/* #define HAVE_USR_INCLUDE_MALLOC_H */ - -#ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" -#else /* HAVE_USR_INCLUDE_MALLOC_H */ - -struct mallinfo { - MALLINFO_FIELD_TYPE arena; /* non-mmapped space allocated from system */ - MALLINFO_FIELD_TYPE ordblks; /* number of free chunks */ - MALLINFO_FIELD_TYPE smblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblks; /* always 0 */ - MALLINFO_FIELD_TYPE hblkhd; /* space in mmapped regions */ - MALLINFO_FIELD_TYPE usmblks; /* maximum total allocated space */ - MALLINFO_FIELD_TYPE fsmblks; /* always 0 */ - MALLINFO_FIELD_TYPE uordblks; /* total allocated space */ - MALLINFO_FIELD_TYPE fordblks; /* total free space */ - MALLINFO_FIELD_TYPE keepcost; /* releasable (via malloc_trim) space */ -}; - -#endif /* HAVE_USR_INCLUDE_MALLOC_H */ -#endif /* NO_MALLINFO */ - -/* - Try to persuade compilers to inline. The most critical functions for - inlining are defined as macros, so these aren't used for them. -*/ - -#ifndef FORCEINLINE - #if defined(__GNUC__) -#define FORCEINLINE __inline __attribute__ ((always_inline)) - #elif defined(_MSC_VER) - #define FORCEINLINE __forceinline - #endif -#endif -#ifndef NOINLINE - #if defined(__GNUC__) - #define NOINLINE __attribute__ ((noinline)) - #elif defined(_MSC_VER) - #define NOINLINE __declspec(noinline) - #else - #define NOINLINE - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#ifndef FORCEINLINE - #define FORCEINLINE inline -#endif -#endif /* __cplusplus */ -#ifndef FORCEINLINE - #define FORCEINLINE -#endif - -#if !ONLY_MSPACES - -/* ------------------- Declarations of public routines ------------------- */ - -#ifndef USE_DL_PREFIX -#define dlcalloc calloc -#define dlfree free -#define dlmalloc malloc -#define dlmemalign memalign -#define dlrealloc realloc -#define dlvalloc valloc -#define dlpvalloc pvalloc -#define dlmallinfo mallinfo -#define dlmallopt mallopt -#define dlmalloc_trim malloc_trim -#define dlmalloc_stats malloc_stats -#define dlmalloc_usable_size malloc_usable_size -#define dlmalloc_footprint malloc_footprint -#define dlmalloc_max_footprint malloc_max_footprint -#define dlindependent_calloc independent_calloc -#define dlindependent_comalloc independent_comalloc -#endif /* USE_DL_PREFIX */ - - -/* - malloc(size_t n) - Returns a pointer to a newly allocated chunk of at least n bytes, or - null if no space is available, in which case errno is set to ENOMEM - on ANSI C systems. - - If n is zero, malloc returns a minimum-sized chunk. (The minimum - size is 16 bytes on most 32bit systems, and 32 bytes on 64bit - systems.) Note that size_t is an unsigned type, so calls with - arguments that would be negative if signed are interpreted as - requests for huge amounts of space, which will often fail. The - maximum supported value of n differs across systems, but is in all - cases less than the maximum representable value of a size_t. -*/ -void* dlmalloc(size_t); - -/* - free(void* p) - Releases the chunk of memory pointed to by p, that had been previously - allocated using malloc or a related routine such as realloc. - It has no effect if p is null. If p was not malloced or already - freed, free(p) will by default cause the current program to abort. -*/ -void dlfree(void*); - -/* - calloc(size_t n_elements, size_t element_size); - Returns a pointer to n_elements * element_size bytes, with all locations - set to zero. -*/ -void* dlcalloc(size_t, size_t); - -/* - realloc(void* p, size_t n) - Returns a pointer to a chunk of size n that contains the same data - as does chunk p up to the minimum of (n, p's size) bytes, or null - if no space is available. - - The returned pointer may or may not be the same as p. The algorithm - prefers extending p in most cases when possible, otherwise it - employs the equivalent of a malloc-copy-free sequence. - - If p is null, realloc is equivalent to malloc. - - If space is not available, realloc returns null, errno is set (if on - ANSI) and p is NOT freed. - - if n is for fewer bytes than already held by p, the newly unused - space is lopped off and freed if possible. realloc with a size - argument of zero (re)allocates a minimum-sized chunk. - - The old unix realloc convention of allowing the last-free'd chunk - to be used as an argument to realloc is not supported. -*/ - -void* dlrealloc(void*, size_t); - -/* - memalign(size_t alignment, size_t n); - Returns a pointer to a newly allocated chunk of n bytes, aligned - in accord with the alignment argument. - - The alignment argument should be a power of two. If the argument is - not a power of two, the nearest greater power is used. - 8-byte alignment is guaranteed by normal malloc calls, so don't - bother calling memalign with an argument of 8 or less. - - Overreliance on memalign is a sure way to fragment space. -*/ -void* dlmemalign(size_t, size_t); - -/* - valloc(size_t n); - Equivalent to memalign(pagesize, n), where pagesize is the page - size of the system. If the pagesize is unknown, 4096 is used. -*/ -void* dlvalloc(size_t); - -/* - mallopt(int parameter_number, int parameter_value) - Sets tunable parameters The format is to provide a - (parameter-number, parameter-value) pair. mallopt then sets the - corresponding parameter to the argument value if it can (i.e., so - long as the value is meaningful), and returns 1 if successful else - 0. SVID/XPG/ANSI defines four standard param numbers for mallopt, - normally defined in malloc.h. None of these are use in this malloc, - so setting them has no effect. But this malloc also supports other - options in mallopt. See below for details. Briefly, supported - parameters are as follows (listed defaults are for "typical" - configurations). - - Symbol param # default allowed param values - M_TRIM_THRESHOLD -1 2*1024*1024 any (MAX_SIZE_T disables) - M_GRANULARITY -2 page size any power of 2 >= page size - M_MMAP_THRESHOLD -3 256*1024 any (or 0 if no MMAP support) -*/ -int dlmallopt(int, int); - -/* - malloc_footprint(); - Returns the number of bytes obtained from the system. The total - number of bytes allocated by malloc, realloc etc., is less than this - value. Unlike mallinfo, this function returns only a precomputed - result, so can be called frequently to monitor memory consumption. - Even if locks are otherwise defined, this function does not use them, - so results might not be up to date. -*/ -size_t dlmalloc_footprint(void); - -/* - malloc_max_footprint(); - Returns the maximum number of bytes obtained from the system. This - value will be greater than current footprint if deallocated space - has been reclaimed by the system. The peak number of bytes allocated - by malloc, realloc etc., is less than this value. Unlike mallinfo, - this function returns only a precomputed result, so can be called - frequently to monitor memory consumption. Even if locks are - otherwise defined, this function does not use them, so results might - not be up to date. -*/ -size_t dlmalloc_max_footprint(void); - -#if !NO_MALLINFO -/* - mallinfo() - Returns (by copy) a struct containing various summary statistics: - - arena: current total non-mmapped bytes allocated from system - ordblks: the number of free chunks - smblks: always zero. - hblks: current number of mmapped regions - hblkhd: total bytes held in mmapped regions - usmblks: the maximum total allocated space. This will be greater - than current total if trimming has occurred. - fsmblks: always zero - uordblks: current total allocated space (normal or mmapped) - fordblks: total free space - keepcost: the maximum number of bytes that could ideally be released - back to system via malloc_trim. ("ideally" means that - it ignores page restrictions etc.) - - Because these fields are ints, but internal bookkeeping may - be kept as longs, the reported values may wrap around zero and - thus be inaccurate. -*/ -struct mallinfo dlmallinfo(void); -#endif /* NO_MALLINFO */ - -/* - independent_calloc(size_t n_elements, size_t element_size, void* chunks[]); - - independent_calloc is similar to calloc, but instead of returning a - single cleared space, it returns an array of pointers to n_elements - independent elements that can hold contents of size elem_size, each - of which starts out cleared, and can be independently freed, - realloc'ed etc. The elements are guaranteed to be adjacently - allocated (this is not guaranteed to occur with multiple callocs or - mallocs), which may also improve cache locality in some - applications. - - The "chunks" argument is optional (i.e., may be null, which is - probably the most typical usage). If it is null, the returned array - is itself dynamically allocated and should also be freed when it is - no longer needed. Otherwise, the chunks array must be of at least - n_elements in length. It is filled in with the pointers to the - chunks. - - In either case, independent_calloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and "chunks" - is null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use regular calloc and assign pointers into this - space to represent elements. (In this case though, you cannot - independently free elements.) - - independent_calloc simplifies and speeds up implementations of many - kinds of pools. It may also be useful when constructing large data - structures that initially have a fixed number of fixed-sized nodes, - but the number is not known at compile time, and some of the nodes - may later need to be freed. For example: - - struct Node { int item; struct Node* next; }; - - struct Node* build_list() { - struct Node** pool; - int n = read_number_of_nodes_needed(); - if (n <= 0) return 0; - pool = (struct Node**)(independent_calloc(n, sizeof(struct Node), 0); - if (pool == 0) die(); - // organize into a linked list... - struct Node* first = pool[0]; - for (i = 0; i < n-1; ++i) - pool[i]->next = pool[i+1]; - free(pool); // Can now free the array (or not, if it is needed later) - return first; - } -*/ -void** dlindependent_calloc(size_t, size_t, void**); - -/* - independent_comalloc(size_t n_elements, size_t sizes[], void* chunks[]); - - independent_comalloc allocates, all at once, a set of n_elements - chunks with sizes indicated in the "sizes" array. It returns - an array of pointers to these elements, each of which can be - independently freed, realloc'ed etc. The elements are guaranteed to - be adjacently allocated (this is not guaranteed to occur with - multiple callocs or mallocs), which may also improve cache locality - in some applications. - - The "chunks" argument is optional (i.e., may be null). If it is null - the returned array is itself dynamically allocated and should also - be freed when it is no longer needed. Otherwise, the chunks array - must be of at least n_elements in length. It is filled in with the - pointers to the chunks. - - In either case, independent_comalloc returns this pointer array, or - null if the allocation failed. If n_elements is zero and chunks is - null, it returns a chunk representing an array with zero elements - (which should be freed if not wanted). - - Each element must be individually freed when it is no longer - needed. If you'd like to instead be able to free all at once, you - should instead use a single regular malloc, and assign pointers at - particular offsets in the aggregate space. (In this case though, you - cannot independently free elements.) - - independent_comallac differs from independent_calloc in that each - element may have a different size, and also that it does not - automatically clear elements. - - independent_comalloc can be used to speed up allocation in cases - where several structs or objects must always be allocated at the - same time. For example: - - struct Head { ... } - struct Foot { ... } - - void send_message(char* msg) { - int msglen = strlen(msg); - size_t sizes[3] = { sizeof(struct Head), msglen, sizeof(struct Foot) }; - void* chunks[3]; - if (independent_comalloc(3, sizes, chunks) == 0) - die(); - struct Head* head = (struct Head*)(chunks[0]); - char* body = (char*)(chunks[1]); - struct Foot* foot = (struct Foot*)(chunks[2]); - // ... - } - - In general though, independent_comalloc is worth using only for - larger values of n_elements. For small values, you probably won't - detect enough difference from series of malloc calls to bother. - - Overuse of independent_comalloc can increase overall memory usage, - since it cannot reuse existing noncontiguous small chunks that - might be available for some of the elements. -*/ -void** dlindependent_comalloc(size_t, size_t*, void**); - - -/* - pvalloc(size_t n); - Equivalent to valloc(minimum-page-that-holds(n)), that is, - round up n to nearest pagesize. - */ -void* dlpvalloc(size_t); - -/* - malloc_trim(size_t pad); - - If possible, gives memory back to the system (via negative arguments - to sbrk) if there is unused memory at the `high' end of the malloc - pool or in unused MMAP segments. You can call this after freeing - large blocks of memory to potentially reduce the system-level memory - requirements of a program. However, it cannot guarantee to reduce - memory. Under some allocation patterns, some large free blocks of - memory will be locked between two used chunks, so they cannot be - given back to the system. - - The `pad' argument to malloc_trim represents the amount of free - trailing space to leave untrimmed. If this argument is zero, only - the minimum amount of memory to maintain internal data structures - will be left. Non-zero arguments can be supplied to maintain enough - trailing space to service future expected allocations without having - to re-obtain memory from the system. - - Malloc_trim returns 1 if it actually released any memory, else 0. -*/ -int dlmalloc_trim(size_t); - -/* - malloc_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. malloc_usable_size can be more useful in - debugging and assertions, for example: - - p = malloc(n); - assert(malloc_usable_size(p) >= 256); -*/ -size_t dlmalloc_usable_size(void*); - -/* - malloc_stats(); - Prints on stderr the amount of space obtained from the system (both - via sbrk and mmap), the maximum amount (which may be more than - current if malloc_trim and/or munmap got called), and the current - number of bytes allocated via malloc (or realloc, etc) but not yet - freed. Note that this is the number of bytes allocated, not the - number requested. It will be larger than the number requested - because of alignment and bookkeeping overhead. Because it includes - alignment wastage as being in use, this figure may be greater than - zero even when no user-level chunks are allocated. - - The reported current and maximum system memory can be inaccurate if - a program makes other calls to system memory allocation functions - (normally sbrk) outside of malloc. - - malloc_stats prints only the most commonly interesting statistics. - More information can be obtained by calling mallinfo. -*/ -void dlmalloc_stats(void); - -#endif /* ONLY_MSPACES */ - -#if MSPACES - -/* - mspace is an opaque type representing an independent - region of space that supports mspace_malloc, etc. -*/ -typedef void* mspace; - -/* - create_mspace creates and returns a new independent space with the - given initial capacity, or, if 0, the default granularity size. It - returns null if there is no system memory available to create the - space. If argument locked is non-zero, the space uses a separate - lock to control access. The capacity of the space will grow - dynamically as needed to service mspace_malloc requests. You can - control the sizes of incremental increases of this space by - compiling with a different DEFAULT_GRANULARITY or dynamically - setting with mallopt(M_GRANULARITY, value). -*/ -mspace create_mspace(size_t capacity, int locked); - -/* - destroy_mspace destroys the given space, and attempts to return all - of its memory back to the system, returning the total number of - bytes freed. After destruction, the results of access to all memory - used by the space become undefined. -*/ -size_t destroy_mspace(mspace msp); - -/* - create_mspace_with_base uses the memory supplied as the initial base - of a new mspace. Part (less than 128*sizeof(size_t) bytes) of this - space is used for bookkeeping, so the capacity must be at least this - large. (Otherwise 0 is returned.) When this initial space is - exhausted, additional memory will be obtained from the system. - Destroying this space will deallocate all additionally allocated - space (if possible) but not the initial base. -*/ -mspace create_mspace_with_base(void* base, size_t capacity, int locked); - -/* - mspace_malloc behaves as malloc, but operates within - the given space. -*/ -void* mspace_malloc(mspace msp, size_t bytes); - -/* - mspace_free behaves as free, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_free is not actually needed. - free may be called instead of mspace_free because freed chunks from - any space are handled by their originating spaces. -*/ -void mspace_free(mspace msp, void* mem); - -/* - mspace_realloc behaves as realloc, but operates within - the given space. - - If compiled with FOOTERS==1, mspace_realloc is not actually - needed. realloc may be called instead of mspace_realloc because - realloced chunks from any space are handled by their originating - spaces. -*/ -void* mspace_realloc(mspace msp, void* mem, size_t newsize); - -/* - mspace_calloc behaves as calloc, but operates within - the given space. -*/ -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size); - -/* - mspace_memalign behaves as memalign, but operates within - the given space. -*/ -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes); - -/* - mspace_independent_calloc behaves as independent_calloc, but - operates within the given space. -*/ -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]); - -/* - mspace_independent_comalloc behaves as independent_comalloc, but - operates within the given space. -*/ -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]); - -/* - mspace_footprint() returns the number of bytes obtained from the - system for this space. -*/ -size_t mspace_footprint(mspace msp); - -/* - mspace_max_footprint() returns the peak number of bytes obtained from the - system for this space. -*/ -size_t mspace_max_footprint(mspace msp); - - -#if !NO_MALLINFO -/* - mspace_mallinfo behaves as mallinfo, but reports properties of - the given space. -*/ -struct mallinfo mspace_mallinfo(mspace msp); -#endif /* NO_MALLINFO */ - -/* - mspace_malloc_stats behaves as malloc_stats, but reports - properties of the given space. -*/ -void mspace_malloc_stats(mspace msp); - -/* - mspace_trim behaves as malloc_trim, but - operates within the given space. -*/ -int mspace_trim(mspace msp, size_t pad); - -/* - An alias for mallopt. -*/ -int mspace_mallopt(int, int); - -#endif /* MSPACES */ - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif /* __cplusplus */ - -/* - ======================================================================== - To make a fully customizable malloc.h header file, cut everything - above this line, put into file malloc.h, edit to suit, and #include it - on the next line, as well as in programs that use this malloc. - ======================================================================== -*/ - -/* #include "malloc.h" */ - -/*------------------------------ internal #includes ---------------------- */ - -#ifdef WIN32 -#pragma warning( disable : 4146 ) /* no "unsigned" warnings */ -#endif /* WIN32 */ - -#include /* for printing in malloc_stats */ - -#ifndef LACKS_ERRNO_H -#include /* for MALLOC_FAILURE_ACTION */ -#endif /* LACKS_ERRNO_H */ -#if FOOTERS -#include /* for magic initialization */ -#endif /* FOOTERS */ -#ifndef LACKS_STDLIB_H -#include /* for abort() */ -#endif /* LACKS_STDLIB_H */ -#ifdef DEBUG -#if ABORT_ON_ASSERT_FAILURE -#define assert(x) if(!(x)) ABORT -#else /* ABORT_ON_ASSERT_FAILURE */ -#include -#endif /* ABORT_ON_ASSERT_FAILURE */ -#else /* DEBUG */ -#define assert(x) -#endif /* DEBUG */ -#ifndef LACKS_STRING_H -#include /* for memset etc */ -#endif /* LACKS_STRING_H */ -#if USE_BUILTIN_FFS -#ifndef LACKS_STRINGS_H -#include /* for ffs */ -#endif /* LACKS_STRINGS_H */ -#endif /* USE_BUILTIN_FFS */ -#if HAVE_MMAP -#ifndef LACKS_SYS_MMAN_H -#include /* for mmap */ -#endif /* LACKS_SYS_MMAN_H */ -#ifndef LACKS_FCNTL_H -#include -#endif /* LACKS_FCNTL_H */ -#endif /* HAVE_MMAP */ -#if HAVE_MORECORE -#ifndef LACKS_UNISTD_H -#include /* for sbrk */ -#else /* LACKS_UNISTD_H */ -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -extern void* sbrk(ptrdiff_t); -#endif /* FreeBSD etc */ -#endif /* LACKS_UNISTD_H */ -#endif /* HAVE_MMAP */ - -/* Declarations for locking */ -#if USE_LOCKS -#ifndef WIN32 -#include -#if defined (__SVR4) && defined (__sun) /* solaris */ -#include -#endif /* solaris */ -#else -#ifndef _M_AMD64 -/* These are already defined on AMD64 builds */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -LONG __cdecl _InterlockedCompareExchange(LPLONG volatile Dest, LONG Exchange, LONG Comp); -LONG __cdecl _InterlockedExchange(LPLONG volatile Target, LONG Value); -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* _M_AMD64 */ -#pragma intrinsic (_InterlockedCompareExchange) -#pragma intrinsic (_InterlockedExchange) -#define interlockedcompareexchange _InterlockedCompareExchange -#define interlockedexchange _InterlockedExchange -#endif /* Win32 */ -#endif /* USE_LOCKS */ - -/* Declarations for bit scanning on win32 */ -#if defined(_MSC_VER) && _MSC_VER>=1300 -#ifndef BitScanForward /* Try to avoid pulling in WinNT.h */ -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -unsigned char _BitScanForward(unsigned long *index, unsigned long mask); -unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#define BitScanForward _BitScanForward -#define BitScanReverse _BitScanReverse -#pragma intrinsic(_BitScanForward) -#pragma intrinsic(_BitScanReverse) -#endif /* BitScanForward */ -#endif /* defined(_MSC_VER) && _MSC_VER>=1300 */ - -#ifndef WIN32 -#ifndef malloc_getpagesize -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -# ifndef _SC_PAGE_SIZE -# define _SC_PAGE_SIZE _SC_PAGESIZE -# endif -# endif -# ifdef _SC_PAGE_SIZE -# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -# else -# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) - extern size_t getpagesize(); -# define malloc_getpagesize getpagesize() -# else -# ifdef WIN32 /* use supplied emulation of getpagesize */ -# define malloc_getpagesize getpagesize() -# else -# ifndef LACKS_SYS_PARAM_H -# include -# endif -# ifdef EXEC_PAGESIZE -# define malloc_getpagesize EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define malloc_getpagesize NBPG -# else -# define malloc_getpagesize (NBPG * CLSIZE) -# endif -# else -# ifdef NBPC -# define malloc_getpagesize NBPC -# else -# ifdef PAGESIZE -# define malloc_getpagesize PAGESIZE -# else /* just guess */ -# define malloc_getpagesize ((size_t)4096U) -# endif -# endif -# endif -# endif -# endif -# endif -# endif -#endif -#endif - - - -/* ------------------- size_t and alignment properties -------------------- */ - -/* The byte and bit size of a size_t */ -#define SIZE_T_SIZE (sizeof(size_t)) -#define SIZE_T_BITSIZE (sizeof(size_t) << 3) - -/* Some constants coerced to size_t */ -/* Annoying but necessary to avoid errors on some platforms */ -#define SIZE_T_ZERO ((size_t)0) -#define SIZE_T_ONE ((size_t)1) -#define SIZE_T_TWO ((size_t)2) -#define SIZE_T_FOUR ((size_t)4) -#define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) -#define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) -#define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) -#define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) - -/* The bit mask value corresponding to MALLOC_ALIGNMENT */ -#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) - -/* True if address a has acceptable alignment */ -#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0) - -/* the number of bytes to offset an address to align it */ -#define align_offset(A)\ - ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ - ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) - -/* -------------------------- MMAP preliminaries ------------------------- */ - -/* - If HAVE_MORECORE or HAVE_MMAP are false, we just define calls and - checks to fail so compiler optimizer can delete code rather than - using so many "#if"s. -*/ - - -/* MORECORE and MMAP must return MFAIL on failure */ -#define MFAIL ((void*)(MAX_SIZE_T)) -#define CMFAIL ((char*)(MFAIL)) /* defined for convenience */ - -#if !HAVE_MMAP -#define IS_MMAPPED_BIT (SIZE_T_ZERO) -#define USE_MMAP_BIT (SIZE_T_ZERO) -#define CALL_MMAP(s) MFAIL -#define CALL_MUNMAP(a, s) (-1) -#define DIRECT_MMAP(s) MFAIL - -#else /* HAVE_MMAP */ -#define IS_MMAPPED_BIT (SIZE_T_ONE) -#define USE_MMAP_BIT (SIZE_T_ONE) - -#ifndef WIN32 -#define CALL_MUNMAP(a, s) munmap((a), (s)) -#define MMAP_PROT (PROT_READ|PROT_WRITE) -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif /* MAP_ANON */ -#ifdef MAP_ANONYMOUS -#define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) -#define CALL_MMAP(s) mmap(0, (s), MMAP_PROT, MMAP_FLAGS, -1, 0) -#else /* MAP_ANONYMOUS */ -/* - Nearly all versions of mmap support MAP_ANONYMOUS, so the following - is unlikely to be needed, but is supplied just in case. -*/ -#define MMAP_FLAGS (MAP_PRIVATE) -static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ -#define CALL_MMAP(s) ((dev_zero_fd < 0) ? \ - (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) : \ - mmap(0, (s), MMAP_PROT, MMAP_FLAGS, dev_zero_fd, 0)) -#endif /* MAP_ANONYMOUS */ - -#define DIRECT_MMAP(s) CALL_MMAP(s) -#else /* WIN32 */ - -/* Win32 MMAP via VirtualAlloc */ -static FORCEINLINE void* win32mmap(size_t size) { - void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); - return (ptr != 0)? ptr: MFAIL; -} - -/* For direct MMAP, use MEM_TOP_DOWN to minimize interference */ -static FORCEINLINE void* win32direct_mmap(size_t size) { - void* ptr = VirtualAlloc(0, size, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, - PAGE_READWRITE); - return (ptr != 0)? ptr: MFAIL; -} - -/* This function supports releasing coalesed segments */ -static FORCEINLINE int win32munmap(void* ptr, size_t size) { - MEMORY_BASIC_INFORMATION minfo; - char* cptr = (char*)ptr; - while (size) { - if (VirtualQuery(cptr, &minfo, sizeof(minfo)) == 0) - return -1; - if (minfo.BaseAddress != cptr || minfo.AllocationBase != cptr || - minfo.State != MEM_COMMIT || minfo.RegionSize > size) - return -1; - if (VirtualFree(cptr, 0, MEM_RELEASE) == 0) - return -1; - cptr += minfo.RegionSize; - size -= minfo.RegionSize; - } - return 0; -} - -#define CALL_MMAP(s) win32mmap(s) -#define CALL_MUNMAP(a, s) win32munmap((a), (s)) -#define DIRECT_MMAP(s) win32direct_mmap(s) -#endif /* WIN32 */ -#endif /* HAVE_MMAP */ - -#if HAVE_MMAP && HAVE_MREMAP -#define CALL_MREMAP(addr, osz, nsz, mv) mremap((addr), (osz), (nsz), (mv)) -#else /* HAVE_MMAP && HAVE_MREMAP */ -#define CALL_MREMAP(addr, osz, nsz, mv) ((void)(addr),(void)(osz), \ - (void)(nsz), (void)(mv),MFAIL) -#endif /* HAVE_MMAP && HAVE_MREMAP */ - -#if HAVE_MORECORE -#define CALL_MORECORE(S) MORECORE(S) -#else /* HAVE_MORECORE */ -#define CALL_MORECORE(S) MFAIL -#endif /* HAVE_MORECORE */ - -/* mstate bit set if continguous morecore disabled or failed */ -#define USE_NONCONTIGUOUS_BIT (4U) - -/* segment bit set in create_mspace_with_base */ -#define EXTERN_BIT (8U) - - -/* --------------------------- Lock preliminaries ------------------------ */ - -/* - When locks are defined, there are up to two global locks: - - * If HAVE_MORECORE, morecore_mutex protects sequences of calls to - MORECORE. In many cases sys_alloc requires two calls, that should - not be interleaved with calls by other threads. This does not - protect against direct calls to MORECORE by other threads not - using this lock, so there is still code to cope the best we can on - interference. - - * magic_init_mutex ensures that mparams.magic and other - unique mparams values are initialized only once. - - To enable use in layered extensions, locks are reentrant. - - Because lock-protected regions generally have bounded times, we use - the supplied simple spinlocks in the custom versions for x86. - - If USE_LOCKS is > 1, the definitions of lock routines here are - bypassed, in which case you will need to define at least - INITIAL_LOCK, ACQUIRE_LOCK, RELEASE_LOCK, and - NULL_LOCK_INITIALIZER, and possibly TRY_LOCK and IS_LOCKED - (The latter two are not used in this malloc, but are - commonly needed in extensions.) -*/ - -#if USE_LOCKS == 1 - -#if USE_SPIN_LOCKS -#ifndef WIN32 -/* Custom pthread-style spin locks on x86 and x64 for gcc */ -struct pthread_mlock_t -{ - volatile pthread_t threadid; - volatile unsigned int c; - volatile unsigned int l; -}; -#define MLOCK_T struct pthread_mlock_t -#define CURRENT_THREAD pthread_self() -#define SPINS_PER_YIELD 63 -static FORCEINLINE int pthread_acquire_lock (MLOCK_T *sl) { - if(CURRENT_THREAD==sl->threadid) - ++sl->c; - else { - int spins = 0; - for (;;) { - int ret; - __asm__ __volatile__ ("lock cmpxchgl %2,(%1)" : "=a" (ret) : "r" (&sl->l), "r" (1), "a" (0)); - if(!ret) { - assert(!sl->threadid); - sl->threadid=CURRENT_THREAD; - sl->c=1; - break; - } - if ((++spins & SPINS_PER_YIELD) == 0) { -#if defined (__SVR4) && defined (__sun) /* solaris */ - thr_yield(); -#else -#ifdef linux - sched_yield(); -#else /* no-op yield on unknown systems */ - ; -#endif /* linux */ -#endif /* solaris */ - } - } - } - - return 0; -} - -static FORCEINLINE void pthread_release_lock (MLOCK_T *sl) { - int ret; - assert(CURRENT_THREAD==sl->threadid); - if (!--sl->c) { - sl->threadid=0; - __asm__ __volatile__ ("xchgl %2,(%1)" : "=r" (ret) : "r" (&sl->l), "0" (0)); - } -} - -static FORCEINLINE int pthread_try_lock (MLOCK_T *sl) { - int ret; - __asm__ __volatile__ ("lock cmpxchgl %2,(%1)" : "=a" (ret) : "r" (&sl->l), "r" (1), "a" (0)); - if(!ret){ - assert(!sl->threadid); - sl->threadid=CURRENT_THREAD; - sl->c=1; - return 1; - } - return 0; -} - -#define INITIAL_LOCK(sl) (memset((sl), 0, sizeof(MLOCK_T)), 0) -#define ACQUIRE_LOCK(sl) pthread_acquire_lock(sl) -#define RELEASE_LOCK(sl) pthread_release_lock(sl) -#define TRY_LOCK(sl) pthread_try_lock(sl) -#define IS_LOCKED(sl) ((sl)->l) - -static MLOCK_T magic_init_mutex = {0, 0, 0 }; -#if HAVE_MORECORE -static MLOCK_T morecore_mutex = {0, 0, 0 }; -#endif /* HAVE_MORECORE */ - -#else /* WIN32 */ -/* Custom win32-style spin locks on x86 and x64 for MSC */ -struct win32_mlock_t -{ - volatile long threadid; - volatile unsigned int c; - long l; -}; -#define MLOCK_T struct win32_mlock_t -#define CURRENT_THREAD GetCurrentThreadId() -#define SPINS_PER_YIELD 63 -static FORCEINLINE int win32_acquire_lock (MLOCK_T *sl) { - long mythreadid=CURRENT_THREAD; - if(mythreadid==sl->threadid) - ++sl->c; - else { - int spins = 0; - for (;;) { - if (!interlockedexchange(&sl->l, 1)) { - assert(!sl->threadid); - sl->threadid=mythreadid; - sl->c=1; - break; - } - if ((++spins & SPINS_PER_YIELD) == 0) - SleepEx(0, FALSE); - } - } - return 0; -} - -static FORCEINLINE void win32_release_lock (MLOCK_T *sl) { - assert(CURRENT_THREAD==sl->threadid); - if (!--sl->c) { - sl->threadid=0; - interlockedexchange (&sl->l, 0); - } -} - -static FORCEINLINE int win32_try_lock (MLOCK_T *sl) { - if (!interlockedexchange(&sl->l, 1)){ - assert(!sl->threadid); - sl->threadid=CURRENT_THREAD; - sl->c=1; - return 1; - } - return 0; -} - -#define INITIAL_LOCK(sl) (memset(sl, 0, sizeof(MLOCK_T)), 0) -#define ACQUIRE_LOCK(sl) win32_acquire_lock(sl) -#define RELEASE_LOCK(sl) win32_release_lock(sl) -#define TRY_LOCK(sl) win32_try_lock(sl) -#define IS_LOCKED(sl) ((sl)->l) - -static MLOCK_T magic_init_mutex = {0, 0 }; -#if HAVE_MORECORE -static MLOCK_T morecore_mutex = {0, 0 }; -#endif /* HAVE_MORECORE */ - -#endif /* WIN32 */ -#else /* USE_SPIN_LOCKS */ - -#ifndef WIN32 -/* pthreads-based locks */ -struct pthread_mlock_t -{ - volatile unsigned int c; - pthread_mutex_t l; -}; -#define MLOCK_T struct pthread_mlock_t -#define CURRENT_THREAD pthread_self() -static FORCEINLINE int pthread_acquire_lock (MLOCK_T *sl) { - if(!pthread_mutex_lock(&(sl)->l)){ - sl->c++; - return 0; - } - return 1; -} - -static FORCEINLINE void pthread_release_lock (MLOCK_T *sl) { - --sl->c; - pthread_mutex_unlock(&(sl)->l); -} - -static FORCEINLINE int pthread_try_lock (MLOCK_T *sl) { - if(!pthread_mutex_trylock(&(sl)->l)){ - sl->c++; - return 1; - } - return 0; -} - -static FORCEINLINE int pthread_init_lock (MLOCK_T *sl) { - pthread_mutexattr_t attr; - sl->c=0; - if(pthread_mutexattr_init(&attr)) return 1; - if(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) return 1; - if(pthread_mutex_init(&sl->l, &attr)) return 1; - pthread_mutexattr_destroy(&attr); - return 0; -} - -static FORCEINLINE int pthread_islocked (MLOCK_T *sl) { - if(!pthread_try_lock(sl)){ - int ret = (sl->c != 0); - pthread_mutex_unlock(sl); - return ret; - } - return 0; -} - -#define INITIAL_LOCK(sl) pthread_init_lock(sl) -#define ACQUIRE_LOCK(sl) pthread_acquire_lock(sl) -#define RELEASE_LOCK(sl) pthread_release_lock(sl) -#define TRY_LOCK(sl) pthread_try_lock(sl) -#define IS_LOCKED(sl) pthread_islocked(sl) - -static MLOCK_T magic_init_mutex = {0, PTHREAD_MUTEX_INITIALIZER }; -#if HAVE_MORECORE -static MLOCK_T morecore_mutex = {0, PTHREAD_MUTEX_INITIALIZER }; -#endif /* HAVE_MORECORE */ - -#else /* WIN32 */ -/* Win32 critical sections */ -#define MLOCK_T CRITICAL_SECTION -#define CURRENT_THREAD GetCurrentThreadId() -#define INITIAL_LOCK(s) (!InitializeCriticalSectionAndSpinCount((s), 4000) -#define ACQUIRE_LOCK(s) ( (!((s))->DebugInfo ? INITIAL_LOCK((s)) : 0), !EnterCriticalSection((s)), 0) -#define RELEASE_LOCK(s) ( LeaveCriticalSection((s)), 0 ) -#define TRY_LOCK(s) ( TryEnterCriticalSection((s)) ) -#define IS_LOCKED(s) ( (s)->LockCount >= 0 ) -#define NULL_LOCK_INITIALIZER -static MLOCK_T magic_init_mutex; -#if HAVE_MORECORE -static MLOCK_T morecore_mutex; -#endif /* HAVE_MORECORE */ -#endif /* WIN32 */ -#endif /* USE_SPIN_LOCKS */ -#endif /* USE_LOCKS == 1 */ - -/* ----------------------- User-defined locks ------------------------ */ - -#if USE_LOCKS > 1 -/* Define your own lock implementation here */ -/* #define INITIAL_LOCK(sl) ... */ -/* #define ACQUIRE_LOCK(sl) ... */ -/* #define RELEASE_LOCK(sl) ... */ -/* #define TRY_LOCK(sl) ... */ -/* #define IS_LOCKED(sl) ... */ -/* #define NULL_LOCK_INITIALIZER ... */ - -static MLOCK_T magic_init_mutex = NULL_LOCK_INITIALIZER; -#if HAVE_MORECORE -static MLOCK_T morecore_mutex = NULL_LOCK_INITIALIZER; -#endif /* HAVE_MORECORE */ -#endif /* USE_LOCKS > 1 */ - -/* ----------------------- Lock-based state ------------------------ */ - - -#if USE_LOCKS -#define USE_LOCK_BIT (2U) -#else /* USE_LOCKS */ -#define USE_LOCK_BIT (0U) -#define INITIAL_LOCK(l) -#endif /* USE_LOCKS */ - -#if USE_LOCKS && HAVE_MORECORE -#define ACQUIRE_MORECORE_LOCK() ACQUIRE_LOCK(&morecore_mutex); -#define RELEASE_MORECORE_LOCK() RELEASE_LOCK(&morecore_mutex); -#else /* USE_LOCKS && HAVE_MORECORE */ -#define ACQUIRE_MORECORE_LOCK() -#define RELEASE_MORECORE_LOCK() -#endif /* USE_LOCKS && HAVE_MORECORE */ - -#if USE_LOCKS -#define ACQUIRE_MAGIC_INIT_LOCK() ACQUIRE_LOCK(&magic_init_mutex); -#define RELEASE_MAGIC_INIT_LOCK() RELEASE_LOCK(&magic_init_mutex); -#else /* USE_LOCKS */ -#define ACQUIRE_MAGIC_INIT_LOCK() -#define RELEASE_MAGIC_INIT_LOCK() -#endif /* USE_LOCKS */ - - -/* ----------------------- Chunk representations ------------------------ */ - -/* - (The following includes lightly edited explanations by Colin Plumb.) - - The malloc_chunk declaration below is misleading (but accurate and - necessary). It declares a "view" into memory allowing access to - necessary fields at known offsets from a given base. - - Chunks of memory are maintained using a `boundary tag' method as - originally described by Knuth. (See the paper by Paul Wilson - ftp://ftp.cs.utexas.edu/pub/garbage/allocsrv.ps for a survey of such - techniques.) Sizes of free chunks are stored both in the front of - each chunk and at the end. This makes consolidating fragmented - chunks into bigger chunks fast. The head fields also hold bits - representing whether chunks are free or in use. - - Here are some pictures to make it clearer. They are "exploded" to - show that the state of a chunk can be thought of as extending from - the high 31 bits of the head field of its header through the - prev_foot and PINUSE_BIT bit of the following chunk header. - - A chunk that's in use looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk (if P = 1) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 1| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | - +- -+ - | | - +- -+ - | : - +- size - sizeof(size_t) available payload bytes -+ - : | - chunk-> +- -+ - | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |1| - | Size of next chunk (may or may not be in use) | +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - And if it's free, it looks like this: - - chunk-> +- -+ - | User payload (must be in use, or we would have merged!) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |P| - | Size of this chunk 0| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Next pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Prev pointer | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- size - sizeof(struct chunk) unused bytes -+ - : | - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |0| - | Size of next chunk (must be in use, or we would have merged)| +-+ - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | : - +- User payload -+ - : | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |0| - +-+ - Note that since we always merge adjacent free chunks, the chunks - adjacent to a free chunk must be in use. - - Given a pointer to a chunk (which can be derived trivially from the - payload pointer) we can, in O(1) time, find out whether the adjacent - chunks are free, and if so, unlink them from the lists that they - are on and merge them with the current chunk. - - Chunks always begin on even word boundaries, so the mem portion - (which is returned to the user) is also on an even word boundary, and - thus at least double-word aligned. - - The P (PINUSE_BIT) bit, stored in the unused low-order bit of the - chunk size (which is always a multiple of two words), is an in-use - bit for the *previous* chunk. If that bit is *clear*, then the - word before the current chunk size contains the previous chunk - size, and can be used to find the front of the previous chunk. - The very first chunk allocated always has this bit set, preventing - access to non-existent (or non-owned) memory. If pinuse is set for - any given chunk, then you CANNOT determine the size of the - previous chunk, and might even get a memory addressing fault when - trying to do so. - - The C (CINUSE_BIT) bit, stored in the unused second-lowest bit of - the chunk size redundantly records whether the current chunk is - inuse. This redundancy enables usage checks within free and realloc, - and reduces indirection when freeing and consolidating chunks. - - Each freshly allocated chunk must have both cinuse and pinuse set. - That is, each allocated chunk borders either a previously allocated - and still in-use chunk, or the base of its memory arena. This is - ensured by making all allocations from the the `lowest' part of any - found chunk. Further, no free chunk physically borders another one, - so each free chunk is known to be preceded and followed by either - inuse chunks or the ends of memory. - - Note that the `foot' of the current chunk is actually represented - as the prev_foot of the NEXT chunk. This makes it easier to - deal with alignments etc but can be very confusing when trying - to extend or adapt this code. - - The exceptions to all this are - - 1. The special chunk `top' is the top-most available chunk (i.e., - the one bordering the end of available memory). It is treated - specially. Top is never included in any bin, is used only if - no other chunk is available, and is released back to the - system if it is very large (see M_TRIM_THRESHOLD). In effect, - the top chunk is treated as larger (and thus less well - fitting) than any other available chunk. The top chunk - doesn't update its trailing size field since there is no next - contiguous chunk that would have to index off it. However, - space is still allocated for it (TOP_FOOT_SIZE) to enable - separation or merging when space is extended. - - 3. Chunks allocated via mmap, which have the lowest-order bit - (IS_MMAPPED_BIT) set in their prev_foot fields, and do not set - PINUSE_BIT in their head fields. Because they are allocated - one-by-one, each must carry its own prev_foot field, which is - also used to hold the offset this chunk has within its mmapped - region, which is needed to preserve alignment. Each mmapped - chunk is trailed by the first two fields of a fake next-chunk - for sake of usage checks. - -*/ - -struct malloc_chunk { - size_t prev_foot; /* Size of previous chunk (if free). */ - size_t head; /* Size and inuse bits. */ - struct malloc_chunk* fd; /* double links -- used only if free. */ - struct malloc_chunk* bk; -}; - -typedef struct malloc_chunk mchunk; -typedef struct malloc_chunk* mchunkptr; -typedef struct malloc_chunk* sbinptr; /* The type of bins of chunks */ -typedef unsigned int bindex_t; /* Described below */ -typedef unsigned int binmap_t; /* Described below */ -typedef unsigned int flag_t; /* The type of various bit flag sets */ - -/* ------------------- Chunks sizes and alignments ----------------------- */ - -#define MCHUNK_SIZE (sizeof(mchunk)) - -#if FOOTERS -#define CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -#else /* FOOTERS */ -#define CHUNK_OVERHEAD (SIZE_T_SIZE) -#endif /* FOOTERS */ - -/* MMapped chunks need a second word of overhead ... */ -#define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) -/* ... and additional padding for fake next-chunk at foot */ -#define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) - -/* The smallest size we can malloc is an aligned minimal chunk */ -#define MIN_CHUNK_SIZE\ - ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) -/* chunk associated with aligned address A */ -#define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) - -/* Bounds on request (not chunk) sizes. */ -#define MAX_REQUEST ((-MIN_CHUNK_SIZE) << 2) -#define MIN_REQUEST (MIN_CHUNK_SIZE - CHUNK_OVERHEAD - SIZE_T_ONE) - -/* pad request bytes into a usable size */ -#define pad_request(req) \ - (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) - -/* pad request, checking for minimum (but not maximum) */ -#define request2size(req) \ - (((req) < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(req)) - - -/* ------------------ Operations on head and foot fields ----------------- */ - -/* - The head field of a chunk is or'ed with PINUSE_BIT when previous - adjacent chunk in use, and or'ed with CINUSE_BIT if this chunk is in - use. If the chunk was obtained with mmap, the prev_foot field has - IS_MMAPPED_BIT set, otherwise holding the offset of the base of the - mmapped region to the base of the chunk. - - FLAG4_BIT is not used by this malloc, but might be useful in extensions. -*/ - -#define PINUSE_BIT (SIZE_T_ONE) -#define CINUSE_BIT (SIZE_T_TWO) -#define FLAG4_BIT (SIZE_T_FOUR) -#define INUSE_BITS (PINUSE_BIT|CINUSE_BIT) -#define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|FLAG4_BIT) - -/* Head value for fenceposts */ -#define FENCEPOST_HEAD (INUSE_BITS|SIZE_T_SIZE) - -/* extraction of fields from head words */ -#define cinuse(p) ((p)->head & CINUSE_BIT) -#define pinuse(p) ((p)->head & PINUSE_BIT) -#define chunksize(p) ((p)->head & ~(FLAG_BITS)) - -#define clear_pinuse(p) ((p)->head &= ~PINUSE_BIT) -#define clear_cinuse(p) ((p)->head &= ~CINUSE_BIT) - -/* Treat space at ptr +/- offset as a chunk */ -#define chunk_plus_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) -#define chunk_minus_offset(p, s) ((mchunkptr)(((char*)(p)) - (s))) - -/* Ptr to next or previous physical malloc_chunk. */ -#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->head & ~FLAG_BITS))) -#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_foot) )) - -/* extract next chunk's pinuse bit */ -#define next_pinuse(p) ((next_chunk(p)->head) & PINUSE_BIT) - -/* Get/set size at footer */ -#define get_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot) -#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_foot = (s)) - -/* Set size, pinuse bit, and foot */ -#define set_size_and_pinuse_of_free_chunk(p, s)\ - ((p)->head = (s|PINUSE_BIT), set_foot(p, s)) - -/* Set size, pinuse bit, foot, and clear next pinuse */ -#define set_free_with_pinuse(p, s, n)\ - (clear_pinuse(n), set_size_and_pinuse_of_free_chunk(p, s)) - -#define is_mmapped(p)\ - (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) - -/* Get the internal overhead associated with chunk p */ -#define overhead_for(p)\ - (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) - -/* Return true if malloced space is not necessarily cleared */ -#if MMAP_CLEARS -#define calloc_must_clear(p) (!is_mmapped(p)) -#else /* MMAP_CLEARS */ -#define calloc_must_clear(p) (1) -#endif /* MMAP_CLEARS */ - -/* ---------------------- Overlaid data structures ----------------------- */ - -/* - When chunks are not in use, they are treated as nodes of either - lists or trees. - - "Small" chunks are stored in circular doubly-linked lists, and look - like this: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk in list | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space (may be 0 bytes long) . - . . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Larger chunks are kept in a form of bitwise digital trees (aka - tries) keyed on chunksizes. Because malloc_tree_chunks are only for - free chunks greater than 256 bytes, their size doesn't impose any - constraints on user chunk sizes. Each node looks like: - - chunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Size of previous chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `head:' | Size of chunk, in bytes |P| - mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Forward pointer to next chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Back pointer to previous chunk of same size | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to left child (child[0]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to right child (child[1]) | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Pointer to parent | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | bin index of this chunk | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Unused space . - . | -nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - `foot:' | Size of chunk, in bytes | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Each tree holding treenodes is a tree of unique chunk sizes. Chunks - of the same size are arranged in a circularly-linked list, with only - the oldest chunk (the next to be used, in our FIFO ordering) - actually in the tree. (Tree members are distinguished by a non-null - parent pointer.) If a chunk with the same size an an existing node - is inserted, it is linked off the existing node using pointers that - work in the same way as fd/bk pointers of small chunks. - - Each tree contains a power of 2 sized range of chunk sizes (the - smallest is 0x100 <= x < 0x180), which is is divided in half at each - tree level, with the chunks in the smaller half of the range (0x100 - <= x < 0x140 for the top nose) in the left subtree and the larger - half (0x140 <= x < 0x180) in the right subtree. This is, of course, - done by inspecting individual bits. - - Using these rules, each node's left subtree contains all smaller - sizes than its right subtree. However, the node at the root of each - subtree has no particular ordering relationship to either. (The - dividing line between the subtree sizes is based on trie relation.) - If we remove the last chunk of a given size from the interior of the - tree, we need to replace it with a leaf node. The tree ordering - rules permit a node to be replaced by any leaf below it. - - The smallest chunk in a tree (a common operation in a best-fit - allocator) can be found by walking a path to the leftmost leaf in - the tree. Unlike a usual binary tree, where we follow left child - pointers until we reach a null, here we follow the right child - pointer any time the left one is null, until we reach a leaf with - both child pointers null. The smallest chunk in the tree will be - somewhere along that path. - - The worst case number of steps to add, find, or remove a node is - bounded by the number of bits differentiating chunks within - bins. Under current bin calculations, this ranges from 6 up to 21 - (for 32 bit sizes) or up to 53 (for 64 bit sizes). The typical case - is of course much better. -*/ - -struct malloc_tree_chunk { - /* The first four fields must be compatible with malloc_chunk */ - size_t prev_foot; - size_t head; - struct malloc_tree_chunk* fd; - struct malloc_tree_chunk* bk; - - struct malloc_tree_chunk* child[2]; - struct malloc_tree_chunk* parent; - bindex_t index; -}; - -typedef struct malloc_tree_chunk tchunk; -typedef struct malloc_tree_chunk* tchunkptr; -typedef struct malloc_tree_chunk* tbinptr; /* The type of bins of trees */ - -/* A little helper macro for trees */ -#define leftmost_child(t) ((t)->child[0] != 0? (t)->child[0] : (t)->child[1]) - -/* ----------------------------- Segments -------------------------------- */ - -/* - Each malloc space may include non-contiguous segments, held in a - list headed by an embedded malloc_segment record representing the - top-most space. Segments also include flags holding properties of - the space. Large chunks that are directly allocated by mmap are not - included in this list. They are instead independently created and - destroyed without otherwise keeping track of them. - - Segment management mainly comes into play for spaces allocated by - MMAP. Any call to MMAP might or might not return memory that is - adjacent to an existing segment. MORECORE normally contiguously - extends the current space, so this space is almost always adjacent, - which is simpler and faster to deal with. (This is why MORECORE is - used preferentially to MMAP when both are available -- see - sys_alloc.) When allocating using MMAP, we don't use any of the - hinting mechanisms (inconsistently) supported in various - implementations of unix mmap, or distinguish reserving from - committing memory. Instead, we just ask for space, and exploit - contiguity when we get it. It is probably possible to do - better than this on some systems, but no general scheme seems - to be significantly better. - - Management entails a simpler variant of the consolidation scheme - used for chunks to reduce fragmentation -- new adjacent memory is - normally prepended or appended to an existing segment. However, - there are limitations compared to chunk consolidation that mostly - reflect the fact that segment processing is relatively infrequent - (occurring only when getting memory from system) and that we - don't expect to have huge numbers of segments: - - * Segments are not indexed, so traversal requires linear scans. (It - would be possible to index these, but is not worth the extra - overhead and complexity for most programs on most platforms.) - * New segments are only appended to old ones when holding top-most - memory; if they cannot be prepended to others, they are held in - different segments. - - Except for the top-most segment of an mstate, each segment record - is kept at the tail of its segment. Segments are added by pushing - segment records onto the list headed by &mstate.seg for the - containing mstate. - - Segment flags control allocation/merge/deallocation policies: - * If EXTERN_BIT set, then we did not allocate this segment, - and so should not try to deallocate or merge with others. - (This currently holds only for the initial segment passed - into create_mspace_with_base.) - * If IS_MMAPPED_BIT set, the segment may be merged with - other surrounding mmapped segments and trimmed/de-allocated - using munmap. - * If neither bit is set, then the segment was obtained using - MORECORE so can be merged with surrounding MORECORE'd segments - and deallocated/trimmed using MORECORE with negative arguments. -*/ - -struct malloc_segment { - char* base; /* base address */ - size_t size; /* allocated size */ - struct malloc_segment* next; /* ptr to next segment */ - flag_t sflags; /* mmap and extern flag */ -}; - -#define is_mmapped_segment(S) ((S)->sflags & IS_MMAPPED_BIT) -#define is_extern_segment(S) ((S)->sflags & EXTERN_BIT) - -typedef struct malloc_segment msegment; -typedef struct malloc_segment* msegmentptr; - -/* ---------------------------- malloc_state ----------------------------- */ - -/* - A malloc_state holds all of the bookkeeping for a space. - The main fields are: - - Top - The topmost chunk of the currently active segment. Its size is - cached in topsize. The actual size of topmost space is - topsize+TOP_FOOT_SIZE, which includes space reserved for adding - fenceposts and segment records if necessary when getting more - space from the system. The size at which to autotrim top is - cached from mparams in trim_check, except that it is disabled if - an autotrim fails. - - Designated victim (dv) - This is the preferred chunk for servicing small requests that - don't have exact fits. It is normally the chunk split off most - recently to service another small request. Its size is cached in - dvsize. The link fields of this chunk are not maintained since it - is not kept in a bin. - - SmallBins - An array of bin headers for free chunks. These bins hold chunks - with sizes less than MIN_LARGE_SIZE bytes. Each bin contains - chunks of all the same size, spaced 8 bytes apart. To simplify - use in double-linked lists, each bin header acts as a malloc_chunk - pointing to the real first node, if it exists (else pointing to - itself). This avoids special-casing for headers. But to avoid - waste, we allocate only the fd/bk pointers of bins, and then use - repositioning tricks to treat these as the fields of a chunk. - - TreeBins - Treebins are pointers to the roots of trees holding a range of - sizes. There are 2 equally spaced treebins for each power of two - from TREE_SHIFT to TREE_SHIFT+16. The last bin holds anything - larger. - - Bin maps - There is one bit map for small bins ("smallmap") and one for - treebins ("treemap). Each bin sets its bit when non-empty, and - clears the bit when empty. Bit operations are then used to avoid - bin-by-bin searching -- nearly all "search" is done without ever - looking at bins that won't be selected. The bit maps - conservatively use 32 bits per map word, even if on 64bit system. - For a good description of some of the bit-based techniques used - here, see Henry S. Warren Jr's book "Hacker's Delight" (and - supplement at http://hackersdelight.org/). Many of these are - intended to reduce the branchiness of paths through malloc etc, as - well as to reduce the number of memory locations read or written. - - Segments - A list of segments headed by an embedded malloc_segment record - representing the initial space. - - Address check support - The least_addr field is the least address ever obtained from - MORECORE or MMAP. Attempted frees and reallocs of any address less - than this are trapped (unless INSECURE is defined). - - Magic tag - A cross-check field that should always hold same value as mparams.magic. - - Flags - Bits recording whether to use MMAP, locks, or contiguous MORECORE - - Statistics - Each space keeps track of current and maximum system memory - obtained via MORECORE or MMAP. - - Trim support - Fields holding the amount of unused topmost memory that should trigger - timming, and a counter to force periodic scanning to release unused - non-topmost segments. - - Locking - If USE_LOCKS is defined, the "mutex" lock is acquired and released - around every public call using this mspace. - - Extension support - A void* pointer and a size_t field that can be used to help implement - extensions to this malloc. -*/ - -/* Bin types, widths and sizes */ -#define NSMALLBINS (32U) -#define NTREEBINS (32U) -#define SMALLBIN_SHIFT (3U) -#define SMALLBIN_WIDTH (SIZE_T_ONE << SMALLBIN_SHIFT) -#define TREEBIN_SHIFT (8U) -#define MIN_LARGE_SIZE (SIZE_T_ONE << TREEBIN_SHIFT) -#define MAX_SMALL_SIZE (MIN_LARGE_SIZE - SIZE_T_ONE) -#define MAX_SMALL_REQUEST (MAX_SMALL_SIZE - CHUNK_ALIGN_MASK - CHUNK_OVERHEAD) - -struct malloc_state { - binmap_t smallmap; - binmap_t treemap; - size_t dvsize; - size_t topsize; - char* least_addr; - mchunkptr dv; - mchunkptr top; - size_t trim_check; - size_t release_checks; - size_t magic; - mchunkptr smallbins[(NSMALLBINS+1)*2]; - tbinptr treebins[NTREEBINS]; - size_t footprint; - size_t max_footprint; - flag_t mflags; -#if USE_LOCKS - MLOCK_T mutex; /* locate lock among fields that rarely change */ -#endif /* USE_LOCKS */ - msegment seg; - void* extp; /* Unused but available for extensions */ - size_t exts; -}; - -typedef struct malloc_state* mstate; - -/* ------------- Global malloc_state and malloc_params ------------------- */ - -/* - malloc_params holds global properties, including those that can be - dynamically set using mallopt. There is a single instance, mparams, - initialized in init_mparams. -*/ - -struct malloc_params { - size_t magic; - size_t page_size; - size_t granularity; - size_t mmap_threshold; - size_t trim_threshold; - flag_t default_mflags; -}; - -static struct malloc_params mparams; - -#if !ONLY_MSPACES - -/* The global malloc_state used for all non-"mspace" calls */ -static struct malloc_state _gm_; -#define gm (&_gm_) -#define is_global(M) ((M) == &_gm_) - -#endif /* !ONLY_MSPACES */ - -#define is_initialized(M) ((M)->top != 0) - -/* -------------------------- system alloc setup ------------------------- */ - -/* Operations on mflags */ - -#define use_lock(M) ((M)->mflags & USE_LOCK_BIT) -#define enable_lock(M) ((M)->mflags |= USE_LOCK_BIT) -#define disable_lock(M) ((M)->mflags &= ~USE_LOCK_BIT) - -#define use_mmap(M) ((M)->mflags & USE_MMAP_BIT) -#define enable_mmap(M) ((M)->mflags |= USE_MMAP_BIT) -#define disable_mmap(M) ((M)->mflags &= ~USE_MMAP_BIT) - -#define use_noncontiguous(M) ((M)->mflags & USE_NONCONTIGUOUS_BIT) -#define disable_contiguous(M) ((M)->mflags |= USE_NONCONTIGUOUS_BIT) - -#define set_lock(M,L)\ - ((M)->mflags = (L)?\ - ((M)->mflags | USE_LOCK_BIT) :\ - ((M)->mflags & ~USE_LOCK_BIT)) - -/* page-align a size */ -#define page_align(S)\ - (((S) + (mparams.page_size - SIZE_T_ONE)) & ~(mparams.page_size - SIZE_T_ONE)) - -/* granularity-align a size */ -#define granularity_align(S)\ - (((S) + (mparams.granularity - SIZE_T_ONE))\ - & ~(mparams.granularity - SIZE_T_ONE)) - - -/* For mmap, use granularity alignment on windows, else page-align */ -#ifdef WIN32 -#define mmap_align(S) granularity_align(S) -#else -#define mmap_align(S) page_align(S) -#endif - -#define is_page_aligned(S)\ - (((size_t)(S) & (mparams.page_size - SIZE_T_ONE)) == 0) -#define is_granularity_aligned(S)\ - (((size_t)(S) & (mparams.granularity - SIZE_T_ONE)) == 0) - -/* True if segment S holds address A */ -#define segment_holds(S, A)\ - ((char*)(A) >= S->base && (char*)(A) < S->base + S->size) - -/* Return segment holding given address */ -static msegmentptr segment_holding(mstate m, char* addr) { - msegmentptr sp = &m->seg; - for (;;) { - if (addr >= sp->base && addr < sp->base + sp->size) - return sp; - if ((sp = sp->next) == 0) - return 0; - } -} - -/* Return true if segment contains a segment link */ -static int has_segment_link(mstate m, msegmentptr ss) { - msegmentptr sp = &m->seg; - for (;;) { - if ((char*)sp >= ss->base && (char*)sp < ss->base + ss->size) - return 1; - if ((sp = sp->next) == 0) - return 0; - } -} - -#ifndef MORECORE_CANNOT_TRIM -#define should_trim(M,s) ((s) > (M)->trim_check) -#else /* MORECORE_CANNOT_TRIM */ -#define should_trim(M,s) (0) -#endif /* MORECORE_CANNOT_TRIM */ - -/* - TOP_FOOT_SIZE is padding at the end of a segment, including space - that may be needed to place segment records and fenceposts when new - noncontiguous segments are added. -*/ -#define TOP_FOOT_SIZE\ - (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) - - -/* ------------------------------- Hooks -------------------------------- */ - -/* - PREACTION should be defined to return 0 on success, and nonzero on - failure. If you are not using locking, you can redefine these to do - anything you like. -*/ - -#if USE_LOCKS - -/* Ensure locks are initialized */ -#define GLOBALLY_INITIALIZE() (mparams.page_size == 0 && init_mparams()) - -#define PREACTION(M) ((GLOBALLY_INITIALIZE() || use_lock(M))? ACQUIRE_LOCK(&(M)->mutex) : 0) -#define POSTACTION(M) { if (use_lock(M)) RELEASE_LOCK(&(M)->mutex); } -#else /* USE_LOCKS */ - -#ifndef PREACTION -#define PREACTION(M) (0) -#endif /* PREACTION */ - -#ifndef POSTACTION -#define POSTACTION(M) -#endif /* POSTACTION */ - -#endif /* USE_LOCKS */ - -/* - CORRUPTION_ERROR_ACTION is triggered upon detected bad addresses. - USAGE_ERROR_ACTION is triggered on detected bad frees and - reallocs. The argument p is an address that might have triggered the - fault. It is ignored by the two predefined actions, but might be - useful in custom actions that try to help diagnose errors. -*/ - -#if PROCEED_ON_ERROR - -/* A count of the number of corruption errors causing resets */ -int malloc_corruption_error_count; - -/* default corruption action */ -static void reset_on_error(mstate m); - -#define CORRUPTION_ERROR_ACTION(m) reset_on_error(m) -#define USAGE_ERROR_ACTION(m, p) - -#else /* PROCEED_ON_ERROR */ - -#ifndef CORRUPTION_ERROR_ACTION -#define CORRUPTION_ERROR_ACTION(m) ABORT -#endif /* CORRUPTION_ERROR_ACTION */ - -#ifndef USAGE_ERROR_ACTION -#define USAGE_ERROR_ACTION(m,p) ABORT -#endif /* USAGE_ERROR_ACTION */ - -#endif /* PROCEED_ON_ERROR */ - -/* -------------------------- Debugging setup ---------------------------- */ - -#if ! DEBUG - -#define check_free_chunk(M,P) -#define check_inuse_chunk(M,P) -#define check_malloced_chunk(M,P,N) -#define check_mmapped_chunk(M,P) -#define check_malloc_state(M) -#define check_top_chunk(M,P) - -#else /* DEBUG */ -#define check_free_chunk(M,P) do_check_free_chunk(M,P) -#define check_inuse_chunk(M,P) do_check_inuse_chunk(M,P) -#define check_top_chunk(M,P) do_check_top_chunk(M,P) -#define check_malloced_chunk(M,P,N) do_check_malloced_chunk(M,P,N) -#define check_mmapped_chunk(M,P) do_check_mmapped_chunk(M,P) -#define check_malloc_state(M) do_check_malloc_state(M) - -static void do_check_any_chunk(mstate m, mchunkptr p); -static void do_check_top_chunk(mstate m, mchunkptr p); -static void do_check_mmapped_chunk(mstate m, mchunkptr p); -static void do_check_inuse_chunk(mstate m, mchunkptr p); -static void do_check_free_chunk(mstate m, mchunkptr p); -static void do_check_malloced_chunk(mstate m, void* mem, size_t s); -static void do_check_tree(mstate m, tchunkptr t); -static void do_check_treebin(mstate m, bindex_t i); -static void do_check_smallbin(mstate m, bindex_t i); -static void do_check_malloc_state(mstate m); -static int bin_find(mstate m, mchunkptr x); -static size_t traverse_and_check(mstate m); -#endif /* DEBUG */ - -/* ---------------------------- Indexing Bins ---------------------------- */ - -#define is_small(s) (((s) >> SMALLBIN_SHIFT) < NSMALLBINS) -#define small_index(s) ((s) >> SMALLBIN_SHIFT) -#define small_index2size(i) ((i) << SMALLBIN_SHIFT) -#define MIN_SMALL_INDEX (small_index(MIN_CHUNK_SIZE)) - -/* addressing by index. See above about smallbin repositioning */ -#define smallbin_at(M, i) ((sbinptr)((char*)&((M)->smallbins[(i)<<1]))) -#define treebin_at(M,i) (&((M)->treebins[i])) - -/* assign tree index for size S to variable I */ -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_tree_index(S, I)\ -{\ - unsigned int X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K;\ - __asm__("bsrl\t%1, %0\n\t" : "=r" (K) : "g" (X));\ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} - -#elif defined(_MSC_VER) && _MSC_VER>=1300 -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int K;\ - _BitScanReverse((DWORD *) &K, X);\ - I = (bindex_t)((K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1)));\ - }\ -} -#else /* GNUC */ -#define compute_tree_index(S, I)\ -{\ - size_t X = S >> TREEBIN_SHIFT;\ - if (X == 0)\ - I = 0;\ - else if (X > 0xFFFF)\ - I = NTREEBINS-1;\ - else {\ - unsigned int Y = (unsigned int)X;\ - unsigned int N = ((Y - 0x100) >> 16) & 8;\ - unsigned int K = (((Y <<= N) - 0x1000) >> 16) & 4;\ - N += K;\ - N += K = (((Y <<= K) - 0x4000) >> 16) & 2;\ - K = 14 - N + ((Y <<= K) >> 15);\ - I = (K << 1) + ((S >> (K + (TREEBIN_SHIFT-1)) & 1));\ - }\ -} -#endif /* GNUC */ - -/* Bit representing maximum resolved size in a treebin at i */ -#define bit_for_tree_index(i) \ - (i == NTREEBINS-1)? (SIZE_T_BITSIZE-1) : (((i) >> 1) + TREEBIN_SHIFT - 2) - -/* Shift placing maximum resolved bit in a treebin at i as sign bit */ -#define leftshift_for_tree_index(i) \ - ((i == NTREEBINS-1)? 0 : \ - ((SIZE_T_BITSIZE-SIZE_T_ONE) - (((i) >> 1) + TREEBIN_SHIFT - 2))) - -/* The size of the smallest chunk held in bin with index i */ -#define minsize_for_tree_index(i) \ - ((SIZE_T_ONE << (((i) >> 1) + TREEBIN_SHIFT)) | \ - (((size_t)((i) & SIZE_T_ONE)) << (((i) >> 1) + TREEBIN_SHIFT - 1))) - - -/* ------------------------ Operations on bin maps ----------------------- */ - -/* bit corresponding to given index */ -#define idx2bit(i) ((binmap_t)(1) << (i)) - -/* Mark/Clear bits with given index */ -#define mark_smallmap(M,i) ((M)->smallmap |= idx2bit(i)) -#define clear_smallmap(M,i) ((M)->smallmap &= ~idx2bit(i)) -#define smallmap_is_marked(M,i) ((M)->smallmap & idx2bit(i)) - -#define mark_treemap(M,i) ((M)->treemap |= idx2bit(i)) -#define clear_treemap(M,i) ((M)->treemap &= ~idx2bit(i)) -#define treemap_is_marked(M,i) ((M)->treemap & idx2bit(i)) - -/* index corresponding to given bit */ - -#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - __asm__("bsfl\t%1, %0\n\t" : "=r" (J) : "g" (X));\ - I = (bindex_t)J;\ -} -#elif defined(_MSC_VER) && _MSC_VER>=1300 -#define compute_bit2idx(X, I)\ -{\ - unsigned int J;\ - _BitScanForward((DWORD *) &J, X);\ - I = (bindex_t)J;\ -} - -#else /* GNUC */ -#if USE_BUILTIN_FFS -#define compute_bit2idx(X, I) I = ffs(X)-1 - -#else /* USE_BUILTIN_FFS */ -#define compute_bit2idx(X, I)\ -{\ - unsigned int Y = X - 1;\ - unsigned int K = Y >> (16-4) & 16;\ - unsigned int N = K; Y >>= K;\ - N += K = Y >> (8-3) & 8; Y >>= K;\ - N += K = Y >> (4-2) & 4; Y >>= K;\ - N += K = Y >> (2-1) & 2; Y >>= K;\ - N += K = Y >> (1-0) & 1; Y >>= K;\ - I = (bindex_t)(N + Y);\ -} -#endif /* USE_BUILTIN_FFS */ -#endif /* GNUC */ - -/* isolate the least set bit of a bitmap */ -#define least_bit(x) ((x) & -(x)) - -/* mask with all bits to left of least bit of x on */ -#define left_bits(x) ((x<<1) | -(x<<1)) - -/* mask with all bits to left of or equal to least bit of x on */ -#define same_or_left_bits(x) ((x) | -(x)) - - -/* ----------------------- Runtime Check Support ------------------------- */ - -/* - For security, the main invariant is that malloc/free/etc never - writes to a static address other than malloc_state, unless static - malloc_state itself has been corrupted, which cannot occur via - malloc (because of these checks). In essence this means that we - believe all pointers, sizes, maps etc held in malloc_state, but - check all of those linked or offsetted from other embedded data - structures. These checks are interspersed with main code in a way - that tends to minimize their run-time cost. - - When FOOTERS is defined, in addition to range checking, we also - verify footer fields of inuse chunks, which can be used guarantee - that the mstate controlling malloc/free is intact. This is a - streamlined version of the approach described by William Robertson - et al in "Run-time Detection of Heap-based Overflows" LISA'03 - http://www.usenix.org/events/lisa03/tech/robertson.html The footer - of an inuse chunk holds the xor of its mstate and a random seed, - that is checked upon calls to free() and realloc(). This is - (probablistically) unguessable from outside the program, but can be - computed by any code successfully malloc'ing any chunk, so does not - itself provide protection against code that has already broken - security through some other means. Unlike Robertson et al, we - always dynamically check addresses of all offset chunks (previous, - next, etc). This turns out to be cheaper than relying on hashes. -*/ - -#if !INSECURE -/* Check if address a is at least as high as any from MORECORE or MMAP */ -#define ok_address(M, a) ((char*)(a) >= (M)->least_addr) -/* Check if address of next chunk n is higher than base chunk p */ -#define ok_next(p, n) ((char*)(p) < (char*)(n)) -/* Check if p has its cinuse bit on */ -#define ok_cinuse(p) cinuse(p) -/* Check if p has its pinuse bit on */ -#define ok_pinuse(p) pinuse(p) - -#else /* !INSECURE */ -#define ok_address(M, a) (1) -#define ok_next(b, n) (1) -#define ok_cinuse(p) (1) -#define ok_pinuse(p) (1) -#endif /* !INSECURE */ - -#if (FOOTERS && !INSECURE) -/* Check if (alleged) mstate m has expected magic field */ -#define ok_magic(M) ((M)->magic == mparams.magic) -#else /* (FOOTERS && !INSECURE) */ -#define ok_magic(M) (1) -#endif /* (FOOTERS && !INSECURE) */ - - -/* In gcc, use __builtin_expect to minimize impact of checks */ -#if !INSECURE -#if defined(__GNUC__) && __GNUC__ >= 3 -#define RTCHECK(e) __builtin_expect(e, 1) -#else /* GNUC */ -#define RTCHECK(e) (e) -#endif /* GNUC */ -#else /* !INSECURE */ -#define RTCHECK(e) (1) -#endif /* !INSECURE */ - -/* macros to set up inuse chunks with or without footers */ - -#if !FOOTERS - -#define mark_inuse_foot(M,p,s) - -/* Set cinuse bit and pinuse bit of next chunk */ -#define set_inuse(M,p,s)\ - ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set cinuse and pinuse of this chunk and pinuse of next chunk */ -#define set_inuse_and_pinuse(M,p,s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - ((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT) - -/* Set size, cinuse and pinuse bit of this chunk */ -#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT)) - -#else /* FOOTERS */ - -/* Set foot of inuse chunk to be xor of mstate and seed */ -#define mark_inuse_foot(M,p,s)\ - (((mchunkptr)((char*)(p) + (s)))->prev_foot = ((size_t)(M) ^ mparams.magic)) - -#define get_mstate_for(p)\ - ((mstate)(((mchunkptr)((char*)(p) +\ - (chunksize(p))))->prev_foot ^ mparams.magic)) - -#define set_inuse(M,p,s)\ - ((p)->head = (((p)->head & PINUSE_BIT)|s|CINUSE_BIT),\ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT), \ - mark_inuse_foot(M,p,s)) - -#define set_inuse_and_pinuse(M,p,s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - (((mchunkptr)(((char*)(p)) + (s)))->head |= PINUSE_BIT),\ - mark_inuse_foot(M,p,s)) - -#define set_size_and_pinuse_of_inuse_chunk(M, p, s)\ - ((p)->head = (s|PINUSE_BIT|CINUSE_BIT),\ - mark_inuse_foot(M, p, s)) - -#endif /* !FOOTERS */ - -/* ---------------------------- setting mparams -------------------------- */ - -/* Initialize mparams */ -static int init_mparams(void) { - if (mparams.page_size == 0) { - size_t s; - - mparams.mmap_threshold = DEFAULT_MMAP_THRESHOLD; - mparams.trim_threshold = DEFAULT_TRIM_THRESHOLD; -#if MORECORE_CONTIGUOUS - mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT; -#else /* MORECORE_CONTIGUOUS */ - mparams.default_mflags = USE_LOCK_BIT|USE_MMAP_BIT|USE_NONCONTIGUOUS_BIT; -#endif /* MORECORE_CONTIGUOUS */ - -#if (FOOTERS && !INSECURE) - { -#if USE_DEV_RANDOM - int fd; - unsigned char buf[sizeof(size_t)]; - /* Try to use /dev/urandom, else fall back on using time */ - if ((fd = open("/dev/urandom", O_RDONLY)) >= 0 && - read(fd, buf, sizeof(buf)) == sizeof(buf)) { - s = *((size_t *) buf); - close(fd); - } - else -#endif /* USE_DEV_RANDOM */ - s = (size_t)(time(0) ^ (size_t)0x55555555U); - - s |= (size_t)8U; /* ensure nonzero */ - s &= ~(size_t)7U; /* improve chances of fault for bad values */ - - } -#else /* (FOOTERS && !INSECURE) */ - s = (size_t)0x58585858U; -#endif /* (FOOTERS && !INSECURE) */ - ACQUIRE_MAGIC_INIT_LOCK(); - if (mparams.magic == 0) { - mparams.magic = s; -#if !ONLY_MSPACES - /* Set up lock for main malloc area */ - INITIAL_LOCK(&gm->mutex); - gm->mflags = mparams.default_mflags; -#endif - } - RELEASE_MAGIC_INIT_LOCK(); - -#ifndef WIN32 - mparams.page_size = malloc_getpagesize; - mparams.granularity = ((DEFAULT_GRANULARITY != 0)? - DEFAULT_GRANULARITY : mparams.page_size); -#else /* WIN32 */ - { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - mparams.page_size = system_info.dwPageSize; - mparams.granularity = system_info.dwAllocationGranularity; - } -#endif /* WIN32 */ - - /* Sanity-check configuration: - size_t must be unsigned and as wide as pointer type. - ints must be at least 4 bytes. - alignment must be at least 8. - Alignment, min chunk size, and page size must all be powers of 2. - */ - if ((sizeof(size_t) != sizeof(char*)) || - (MAX_SIZE_T < MIN_CHUNK_SIZE) || - (sizeof(int) < 4) || - (MALLOC_ALIGNMENT < (size_t)8U) || - ((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-SIZE_T_ONE)) != 0) || - ((MCHUNK_SIZE & (MCHUNK_SIZE-SIZE_T_ONE)) != 0) || - ((mparams.granularity & (mparams.granularity-SIZE_T_ONE)) != 0) || - ((mparams.page_size & (mparams.page_size-SIZE_T_ONE)) != 0)) - ABORT; - } - return 0; -} - -/* support for mallopt */ -static int change_mparam(int param_number, int value) { - size_t val = (size_t)value; - init_mparams(); - switch(param_number) { - case M_TRIM_THRESHOLD: - mparams.trim_threshold = val; - return 1; - case M_GRANULARITY: - if (val >= mparams.page_size && ((val & (val-1)) == 0)) { - mparams.granularity = val; - return 1; - } - else - return 0; - case M_MMAP_THRESHOLD: - mparams.mmap_threshold = val; - return 1; - default: - return 0; - } -} - -#if DEBUG -/* ------------------------- Debugging Support --------------------------- */ - -/* Check properties of any chunk, whether free, inuse, mmapped etc */ -static void do_check_any_chunk(mstate m, mchunkptr p) { - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); -} - -/* Check properties of top chunk */ -static void do_check_top_chunk(mstate m, mchunkptr p) { - msegmentptr sp = segment_holding(m, (char*)p); - size_t sz = p->head & ~INUSE_BITS; /* third-lowest bit can be set! */ - assert(sp != 0); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(sz == m->topsize); - assert(sz > 0); - assert(sz == ((sp->base + sp->size) - (char*)p) - TOP_FOOT_SIZE); - assert(pinuse(p)); - assert(!pinuse(chunk_plus_offset(p, sz))); -} - -/* Check properties of (inuse) mmapped chunks */ -static void do_check_mmapped_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - size_t len = (sz + (p->prev_foot & ~IS_MMAPPED_BIT) + MMAP_FOOT_PAD); - assert(is_mmapped(p)); - assert(use_mmap(m)); - assert((is_aligned(chunk2mem(p))) || (p->head == FENCEPOST_HEAD)); - assert(ok_address(m, p)); - assert(!is_small(sz)); - assert((len & (mparams.page_size-SIZE_T_ONE)) == 0); - assert(chunk_plus_offset(p, sz)->head == FENCEPOST_HEAD); - assert(chunk_plus_offset(p, sz+SIZE_T_SIZE)->head == 0); -} - -/* Check properties of inuse chunks */ -static void do_check_inuse_chunk(mstate m, mchunkptr p) { - do_check_any_chunk(m, p); - assert(cinuse(p)); - assert(next_pinuse(p)); - /* If not pinuse and not mmapped, previous chunk has OK offset */ - assert(is_mmapped(p) || pinuse(p) || next_chunk(prev_chunk(p)) == p); - if (is_mmapped(p)) - do_check_mmapped_chunk(m, p); -} - -/* Check properties of free chunks */ -static void do_check_free_chunk(mstate m, mchunkptr p) { - size_t sz = chunksize(p); - mchunkptr next = chunk_plus_offset(p, sz); - do_check_any_chunk(m, p); - assert(!cinuse(p)); - assert(!next_pinuse(p)); - assert (!is_mmapped(p)); - if (p != m->dv && p != m->top) { - if (sz >= MIN_CHUNK_SIZE) { - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(is_aligned(chunk2mem(p))); - assert(next->prev_foot == sz); - assert(pinuse(p)); - assert (next == m->top || cinuse(next)); - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } - else /* markers are always of size SIZE_T_SIZE */ - assert(sz == SIZE_T_SIZE); - } -} - -/* Check properties of malloced chunks at the point they are malloced */ -static void do_check_malloced_chunk(mstate m, void* mem, size_t s) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - size_t sz = p->head & ~(PINUSE_BIT|CINUSE_BIT); - do_check_inuse_chunk(m, p); - assert((sz & CHUNK_ALIGN_MASK) == 0); - assert(sz >= MIN_CHUNK_SIZE); - assert(sz >= s); - /* unless mmapped, size is less than MIN_CHUNK_SIZE more than request */ - assert(is_mmapped(p) || sz < (s + MIN_CHUNK_SIZE)); - } -} - -/* Check a tree and its subtrees. */ -static void do_check_tree(mstate m, tchunkptr t) { - tchunkptr head = 0; - tchunkptr u = t; - bindex_t tindex = t->index; - size_t tsize = chunksize(t); - bindex_t idx; - compute_tree_index(tsize, idx); - assert(tindex == idx); - assert(tsize >= MIN_LARGE_SIZE); - assert(tsize >= minsize_for_tree_index(idx)); - assert((idx == NTREEBINS-1) || (tsize < minsize_for_tree_index((idx+1)))); - - do { /* traverse through chain of same-sized nodes */ - do_check_any_chunk(m, ((mchunkptr)u)); - assert(u->index == tindex); - assert(chunksize(u) == tsize); - assert(!cinuse(u)); - assert(!next_pinuse(u)); - assert(u->fd->bk == u); - assert(u->bk->fd == u); - if (u->parent == 0) { - assert(u->child[0] == 0); - assert(u->child[1] == 0); - } - else { - assert(head == 0); /* only one node on chain has parent */ - head = u; - assert(u->parent != u); - assert (u->parent->child[0] == u || - u->parent->child[1] == u || - *((tbinptr*)(u->parent)) == u); - if (u->child[0] != 0) { - assert(u->child[0]->parent == u); - assert(u->child[0] != u); - do_check_tree(m, u->child[0]); - } - if (u->child[1] != 0) { - assert(u->child[1]->parent == u); - assert(u->child[1] != u); - do_check_tree(m, u->child[1]); - } - if (u->child[0] != 0 && u->child[1] != 0) { - assert(chunksize(u->child[0]) < chunksize(u->child[1])); - } - } - u = u->fd; - } while (u != t); - assert(head != 0); -} - -/* Check all the chunks in a treebin. */ -static void do_check_treebin(mstate m, bindex_t i) { - tbinptr* tb = treebin_at(m, i); - tchunkptr t = *tb; - int empty = (m->treemap & (1U << i)) == 0; - if (t == 0) - assert(empty); - if (!empty) - do_check_tree(m, t); -} - -/* Check all the chunks in a smallbin. */ -static void do_check_smallbin(mstate m, bindex_t i) { - sbinptr b = smallbin_at(m, i); - mchunkptr p = b->bk; - unsigned int empty = (m->smallmap & (1U << i)) == 0; - if (p == b) - assert(empty); - if (!empty) { - for (; p != b; p = p->bk) { - size_t size = chunksize(p); - mchunkptr q; - /* each chunk claims to be free */ - do_check_free_chunk(m, p); - /* chunk belongs in bin */ - assert(small_index(size) == i); - assert(p->bk == b || chunksize(p->bk) == chunksize(p)); - /* chunk is followed by an inuse chunk */ - q = next_chunk(p); - if (q->head != FENCEPOST_HEAD) - do_check_inuse_chunk(m, q); - } - } -} - -/* Find x in a bin. Used in other check functions. */ -static int bin_find(mstate m, mchunkptr x) { - size_t size = chunksize(x); - if (is_small(size)) { - bindex_t sidx = small_index(size); - sbinptr b = smallbin_at(m, sidx); - if (smallmap_is_marked(m, sidx)) { - mchunkptr p = b; - do { - if (p == x) - return 1; - } while ((p = p->fd) != b); - } - } - else { - bindex_t tidx; - compute_tree_index(size, tidx); - if (treemap_is_marked(m, tidx)) { - tchunkptr t = *treebin_at(m, tidx); - size_t sizebits = size << leftshift_for_tree_index(tidx); - while (t != 0 && chunksize(t) != size) { - t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; - sizebits <<= 1; - } - if (t != 0) { - tchunkptr u = t; - do { - if (u == (tchunkptr)x) - return 1; - } while ((u = u->fd) != t); - } - } - } - return 0; -} - -/* Traverse each chunk and check it; return total */ -static size_t traverse_and_check(mstate m) { - size_t sum = 0; - if (is_initialized(m)) { - msegmentptr s = &m->seg; - sum += m->topsize + TOP_FOOT_SIZE; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - mchunkptr lastq = 0; - assert(pinuse(q)); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - sum += chunksize(q); - if (cinuse(q)) { - assert(!bin_find(m, q)); - do_check_inuse_chunk(m, q); - } - else { - assert(q == m->dv || bin_find(m, q)); - assert(lastq == 0 || cinuse(lastq)); /* Not 2 consecutive free */ - do_check_free_chunk(m, q); - } - lastq = q; - q = next_chunk(q); - } - s = s->next; - } - } - return sum; -} - -/* Check all properties of malloc_state. */ -static void do_check_malloc_state(mstate m) { - bindex_t i; - size_t total; - /* check bins */ - for (i = 0; i < NSMALLBINS; ++i) - do_check_smallbin(m, i); - for (i = 0; i < NTREEBINS; ++i) - do_check_treebin(m, i); - - if (m->dvsize != 0) { /* check dv chunk */ - do_check_any_chunk(m, m->dv); - assert(m->dvsize == chunksize(m->dv)); - assert(m->dvsize >= MIN_CHUNK_SIZE); - assert(bin_find(m, m->dv) == 0); - } - - if (m->top != 0) { /* check top chunk */ - do_check_top_chunk(m, m->top); - /*assert(m->topsize == chunksize(m->top)); redundant */ - assert(m->topsize > 0); - assert(bin_find(m, m->top) == 0); - } - - total = traverse_and_check(m); - assert(total <= m->footprint); - assert(m->footprint <= m->max_footprint); -} -#endif /* DEBUG */ - -/* ----------------------------- statistics ------------------------------ */ - -#if !NO_MALLINFO -static struct mallinfo internal_mallinfo(mstate m) { - struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - if (!PREACTION(m)) { - check_malloc_state(m); - if (is_initialized(m)) { - size_t nfree = SIZE_T_ONE; /* top always free */ - size_t mfree = m->topsize + TOP_FOOT_SIZE; - size_t sum = mfree; - msegmentptr s = &m->seg; - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - size_t sz = chunksize(q); - sum += sz; - if (!cinuse(q)) { - mfree += sz; - ++nfree; - } - q = next_chunk(q); - } - s = s->next; - } - - nm.arena = sum; - nm.ordblks = nfree; - nm.hblkhd = m->footprint - sum; - nm.usmblks = m->max_footprint; - nm.uordblks = m->footprint - mfree; - nm.fordblks = mfree; - nm.keepcost = m->topsize; - } - - POSTACTION(m); - } - return nm; -} -#endif /* !NO_MALLINFO */ - -static void internal_malloc_stats(mstate m) { - if (!PREACTION(m)) { - size_t maxfp = 0; - size_t fp = 0; - size_t used = 0; - check_malloc_state(m); - if (is_initialized(m)) { - msegmentptr s = &m->seg; - maxfp = m->max_footprint; - fp = m->footprint; - used = fp - (m->topsize + TOP_FOOT_SIZE); - - while (s != 0) { - mchunkptr q = align_as_chunk(s->base); - while (segment_holds(s, q) && - q != m->top && q->head != FENCEPOST_HEAD) { - if (!cinuse(q)) - used -= chunksize(q); - q = next_chunk(q); - } - s = s->next; - } - } - - fprintf(stderr, "max system bytes = %10lu\n", (unsigned long)(maxfp)); - fprintf(stderr, "system bytes = %10lu\n", (unsigned long)(fp)); - fprintf(stderr, "in use bytes = %10lu\n", (unsigned long)(used)); - - POSTACTION(m); - } -} - -/* ----------------------- Operations on smallbins ----------------------- */ - -/* - Various forms of linking and unlinking are defined as macros. Even - the ones for trees, which are very long but have very short typical - paths. This is ugly but reduces reliance on inlining support of - compilers. -*/ - -/* Link a free chunk into a smallbin */ -#define insert_small_chunk(M, P, S) {\ - bindex_t I = small_index(S);\ - mchunkptr B = smallbin_at(M, I);\ - mchunkptr F = B;\ - assert(S >= MIN_CHUNK_SIZE);\ - if (!smallmap_is_marked(M, I))\ - mark_smallmap(M, I);\ - else if (RTCHECK(ok_address(M, B->fd)))\ - F = B->fd;\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - B->fd = P;\ - F->bk = P;\ - P->fd = F;\ - P->bk = B;\ -} - -/* Unlink a chunk from a smallbin */ -#define unlink_small_chunk(M, P, S) {\ - mchunkptr F = P->fd;\ - mchunkptr B = P->bk;\ - bindex_t I = small_index(S);\ - assert(P != B);\ - assert(P != F);\ - assert(chunksize(P) == small_index2size(I));\ - if (F == B)\ - clear_smallmap(M, I);\ - else if (RTCHECK((F == smallbin_at(M,I) || ok_address(M, F)) &&\ - (B == smallbin_at(M,I) || ok_address(M, B)))) {\ - F->bk = B;\ - B->fd = F;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ -} - -/* Unlink the first chunk from a smallbin */ -#define unlink_first_small_chunk(M, B, P, I) {\ - mchunkptr F = P->fd;\ - assert(P != B);\ - assert(P != F);\ - assert(chunksize(P) == small_index2size(I));\ - if (B == F)\ - clear_smallmap(M, I);\ - else if (RTCHECK(ok_address(M, F))) {\ - B->fd = F;\ - F->bk = B;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ -} - -/* Replace dv node, binning the old one */ -/* Used only when dvsize known to be small */ -#define replace_dv(M, P, S) {\ - size_t DVS = M->dvsize;\ - if (DVS != 0) {\ - mchunkptr DV = M->dv;\ - assert(is_small(DVS));\ - insert_small_chunk(M, DV, DVS);\ - }\ - M->dvsize = S;\ - M->dv = P;\ -} - -/* ------------------------- Operations on trees ------------------------- */ - -/* Insert chunk into tree */ -#define insert_large_chunk(M, X, S) {\ - tbinptr* H;\ - bindex_t I;\ - compute_tree_index(S, I);\ - H = treebin_at(M, I);\ - X->index = I;\ - X->child[0] = X->child[1] = 0;\ - if (!treemap_is_marked(M, I)) {\ - mark_treemap(M, I);\ - *H = X;\ - X->parent = (tchunkptr)H;\ - X->fd = X->bk = X;\ - }\ - else {\ - tchunkptr T = *H;\ - size_t K = S << leftshift_for_tree_index(I);\ - for (;;) {\ - if (chunksize(T) != S) {\ - tchunkptr* C = &(T->child[(K >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]);\ - K <<= 1;\ - if (*C != 0)\ - T = *C;\ - else if (RTCHECK(ok_address(M, C))) {\ - *C = X;\ - X->parent = T;\ - X->fd = X->bk = X;\ - break;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - break;\ - }\ - }\ - else {\ - tchunkptr F = T->fd;\ - if (RTCHECK(ok_address(M, T) && ok_address(M, F))) {\ - T->fd = F->bk = X;\ - X->fd = F;\ - X->bk = T;\ - X->parent = 0;\ - break;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - break;\ - }\ - }\ - }\ - }\ -} - -/* - Unlink steps: - - 1. If x is a chained node, unlink it from its same-sized fd/bk links - and choose its bk node as its replacement. - 2. If x was the last node of its size, but not a leaf node, it must - be replaced with a leaf node (not merely one with an open left or - right), to make sure that lefts and rights of descendents - correspond properly to bit masks. We use the rightmost descendent - of x. We could use any other leaf, but this is easy to locate and - tends to counteract removal of leftmosts elsewhere, and so keeps - paths shorter than minimally guaranteed. This doesn't loop much - because on average a node in a tree is near the bottom. - 3. If x is the base of a chain (i.e., has parent links) relink - x's parent and children to x's replacement (or null if none). -*/ - -#define unlink_large_chunk(M, X) {\ - tchunkptr XP = X->parent;\ - tchunkptr R;\ - if (X->bk != X) {\ - tchunkptr F = X->fd;\ - R = X->bk;\ - if (RTCHECK(ok_address(M, F))) {\ - F->bk = R;\ - R->fd = F;\ - }\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - else {\ - tchunkptr* RP;\ - if (((R = *(RP = &(X->child[1]))) != 0) ||\ - ((R = *(RP = &(X->child[0]))) != 0)) {\ - tchunkptr* CP;\ - while ((*(CP = &(R->child[1])) != 0) ||\ - (*(CP = &(R->child[0])) != 0)) {\ - R = *(RP = CP);\ - }\ - if (RTCHECK(ok_address(M, RP)))\ - *RP = 0;\ - else {\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - }\ - if (XP != 0) {\ - tbinptr* H = treebin_at(M, X->index);\ - if (X == *H) {\ - if ((*H = R) == 0) \ - clear_treemap(M, X->index);\ - }\ - else if (RTCHECK(ok_address(M, XP))) {\ - if (XP->child[0] == X) \ - XP->child[0] = R;\ - else \ - XP->child[1] = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - if (R != 0) {\ - if (RTCHECK(ok_address(M, R))) {\ - tchunkptr C0, C1;\ - R->parent = XP;\ - if ((C0 = X->child[0]) != 0) {\ - if (RTCHECK(ok_address(M, C0))) {\ - R->child[0] = C0;\ - C0->parent = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - if ((C1 = X->child[1]) != 0) {\ - if (RTCHECK(ok_address(M, C1))) {\ - R->child[1] = C1;\ - C1->parent = R;\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ - else\ - CORRUPTION_ERROR_ACTION(M);\ - }\ - }\ -} - -/* Relays to large vs small bin operations */ - -#define insert_chunk(M, P, S)\ - if (is_small(S)) insert_small_chunk(M, P, S)\ - else { tchunkptr TP = (tchunkptr)(P); insert_large_chunk(M, TP, S); } - -#define unlink_chunk(M, P, S)\ - if (is_small(S)) unlink_small_chunk(M, P, S)\ - else { tchunkptr TP = (tchunkptr)(P); unlink_large_chunk(M, TP); } - - -/* Relays to internal calls to malloc/free from realloc, memalign etc */ - -#if ONLY_MSPACES -#define internal_malloc(m, b) mspace_malloc(m, b) -#define internal_free(m, mem) mspace_free(m,mem); -#else /* ONLY_MSPACES */ -#if MSPACES -#define internal_malloc(m, b)\ - (m == gm)? dlmalloc(b) : mspace_malloc(m, b) -#define internal_free(m, mem)\ - if (m == gm) dlfree(mem); else mspace_free(m,mem); -#else /* MSPACES */ -#define internal_malloc(m, b) dlmalloc(b) -#define internal_free(m, mem) dlfree(mem) -#endif /* MSPACES */ -#endif /* ONLY_MSPACES */ - -/* ----------------------- Direct-mmapping chunks ----------------------- */ - -/* - Directly mmapped chunks are set up with an offset to the start of - the mmapped region stored in the prev_foot field of the chunk. This - allows reconstruction of the required argument to MUNMAP when freed, - and also allows adjustment of the returned chunk to meet alignment - requirements (especially in memalign). There is also enough space - allocated to hold a fake next chunk of size SIZE_T_SIZE to maintain - the PINUSE bit so frees can be checked. -*/ - -/* Malloc using mmap */ -static void* mmap_alloc(mstate m, size_t nb) { - size_t mmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - if (mmsize > nb) { /* Check for wrap around 0 */ - char* mm = (char*)(DIRECT_MMAP(mmsize)); - if (mm != CMFAIL) { - size_t offset = align_offset(chunk2mem(mm)); - size_t psize = mmsize - offset - MMAP_FOOT_PAD; - mchunkptr p = (mchunkptr)(mm + offset); - p->prev_foot = offset | IS_MMAPPED_BIT; - (p)->head = (psize|CINUSE_BIT); - mark_inuse_foot(m, p, psize); - chunk_plus_offset(p, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(p, psize+SIZE_T_SIZE)->head = 0; - - if (mm < m->least_addr) - m->least_addr = mm; - if ((m->footprint += mmsize) > m->max_footprint) - m->max_footprint = m->footprint; - assert(is_aligned(chunk2mem(p))); - check_mmapped_chunk(m, p); - return chunk2mem(p); - } - } - return 0; -} - -/* Realloc using mmap */ -static mchunkptr mmap_resize(mstate m, mchunkptr oldp, size_t nb) { - size_t oldsize = chunksize(oldp); - if (is_small(nb)) /* Can't shrink mmap regions below small size */ - return 0; - /* Keep old chunk if big enough but not too big */ - if (oldsize >= nb + SIZE_T_SIZE && - (oldsize - nb) <= (mparams.granularity << 1)) - return oldp; - else { - size_t offset = oldp->prev_foot & ~IS_MMAPPED_BIT; - size_t oldmmsize = oldsize + offset + MMAP_FOOT_PAD; - size_t newmmsize = mmap_align(nb + SIX_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - char* cp = (char*)CALL_MREMAP((char*)oldp - offset, - oldmmsize, newmmsize, 1); - if (cp != CMFAIL) { - mchunkptr newp = (mchunkptr)(cp + offset); - size_t psize = newmmsize - offset - MMAP_FOOT_PAD; - newp->head = (psize|CINUSE_BIT); - mark_inuse_foot(m, newp, psize); - chunk_plus_offset(newp, psize)->head = FENCEPOST_HEAD; - chunk_plus_offset(newp, psize+SIZE_T_SIZE)->head = 0; - - if (cp < m->least_addr) - m->least_addr = cp; - if ((m->footprint += newmmsize - oldmmsize) > m->max_footprint) - m->max_footprint = m->footprint; - check_mmapped_chunk(m, newp); - return newp; - } - } - return 0; -} - -/* -------------------------- mspace management -------------------------- */ - -/* Initialize top chunk and its size */ -static void init_top(mstate m, mchunkptr p, size_t psize) { - /* Ensure alignment */ - size_t offset = align_offset(chunk2mem(p)); - p = (mchunkptr)((char*)p + offset); - psize -= offset; - - m->top = p; - m->topsize = psize; - p->head = psize | PINUSE_BIT; - /* set size of fake trailing chunk holding overhead space only once */ - chunk_plus_offset(p, psize)->head = TOP_FOOT_SIZE; - m->trim_check = mparams.trim_threshold; /* reset on each update */ -} - -/* Initialize bins for a new mstate that is otherwise zeroed out */ -static void init_bins(mstate m) { - /* Establish circular links for smallbins */ - bindex_t i; - for (i = 0; i < NSMALLBINS; ++i) { - sbinptr bin = smallbin_at(m,i); - bin->fd = bin->bk = bin; - } -} - -#if PROCEED_ON_ERROR - -/* default corruption action */ -static void reset_on_error(mstate m) { - int i; - ++malloc_corruption_error_count; - /* Reinitialize fields to forget about all memory */ - m->smallbins = m->treebins = 0; - m->dvsize = m->topsize = 0; - m->seg.base = 0; - m->seg.size = 0; - m->seg.next = 0; - m->top = m->dv = 0; - for (i = 0; i < NTREEBINS; ++i) - *treebin_at(m, i) = 0; - init_bins(m); -} -#endif /* PROCEED_ON_ERROR */ - -/* Allocate chunk and prepend remainder with chunk in successor base. */ -static void* prepend_alloc(mstate m, char* newbase, char* oldbase, - size_t nb) { - mchunkptr p = align_as_chunk(newbase); - mchunkptr oldfirst = align_as_chunk(oldbase); - size_t psize = (char*)oldfirst - (char*)p; - mchunkptr q = chunk_plus_offset(p, nb); - size_t qsize = psize - nb; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - - assert((char*)oldfirst > (char*)q); - assert(pinuse(oldfirst)); - assert(qsize >= MIN_CHUNK_SIZE); - - /* consolidate remainder with first chunk of old base */ - if (oldfirst == m->top) { - size_t tsize = m->topsize += qsize; - m->top = q; - q->head = tsize | PINUSE_BIT; - check_top_chunk(m, q); - } - else if (oldfirst == m->dv) { - size_t dsize = m->dvsize += qsize; - m->dv = q; - set_size_and_pinuse_of_free_chunk(q, dsize); - } - else { - if (!cinuse(oldfirst)) { - size_t nsize = chunksize(oldfirst); - unlink_chunk(m, oldfirst, nsize); - oldfirst = chunk_plus_offset(oldfirst, nsize); - qsize += nsize; - } - set_free_with_pinuse(q, qsize, oldfirst); - insert_chunk(m, q, qsize); - check_free_chunk(m, q); - } - - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); -} - -/* Add a segment to hold a new noncontiguous region */ -static void add_segment(mstate m, char* tbase, size_t tsize, flag_t mmapped) { - /* Determine locations and sizes of segment, fenceposts, old top */ - char* old_top = (char*)m->top; - msegmentptr oldsp = segment_holding(m, old_top); - char* old_end = oldsp->base + oldsp->size; - size_t ssize = pad_request(sizeof(struct malloc_segment)); - char* rawsp = old_end - (ssize + FOUR_SIZE_T_SIZES + CHUNK_ALIGN_MASK); - size_t offset = align_offset(chunk2mem(rawsp)); - char* asp = rawsp + offset; - char* csp = (asp < (old_top + MIN_CHUNK_SIZE))? old_top : asp; - mchunkptr sp = (mchunkptr)csp; - msegmentptr ss = (msegmentptr)(chunk2mem(sp)); - mchunkptr tnext = chunk_plus_offset(sp, ssize); - mchunkptr p = tnext; - int nfences = 0; - - /* reset top to new space */ - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - - /* Set up segment record */ - assert(is_aligned(ss)); - set_size_and_pinuse_of_inuse_chunk(m, sp, ssize); - *ss = m->seg; /* Push current record */ - m->seg.base = tbase; - m->seg.size = tsize; - m->seg.sflags = mmapped; - m->seg.next = ss; - - /* Insert trailing fenceposts */ - for (;;) { - mchunkptr nextp = chunk_plus_offset(p, SIZE_T_SIZE); - p->head = FENCEPOST_HEAD; - ++nfences; - if ((char*)(&(nextp->head)) < old_end) - p = nextp; - else - break; - } - assert(nfences >= 2); - - /* Insert the rest of old top into a bin as an ordinary free chunk */ - if (csp != old_top) { - mchunkptr q = (mchunkptr)old_top; - size_t psize = csp - old_top; - mchunkptr tn = chunk_plus_offset(q, psize); - set_free_with_pinuse(q, psize, tn); - insert_chunk(m, q, psize); - } - - check_top_chunk(m, m->top); -} - -/* -------------------------- System allocation -------------------------- */ - -/* Get memory from system using MORECORE or MMAP */ -static void* sys_alloc(mstate m, size_t nb) { - char* tbase = CMFAIL; - size_t tsize = 0; - flag_t mmap_flag = 0; - - init_mparams(); - - /* Directly map large chunks */ - if (use_mmap(m) && nb >= mparams.mmap_threshold) { - void* mem = mmap_alloc(m, nb); - if (mem != 0) - return mem; - } - - /* - Try getting memory in any of three ways (in most-preferred to - least-preferred order): - 1. A call to MORECORE that can normally contiguously extend memory. - (disabled if not MORECORE_CONTIGUOUS or not HAVE_MORECORE or - or main space is mmapped or a previous contiguous call failed) - 2. A call to MMAP new space (disabled if not HAVE_MMAP). - Note that under the default settings, if MORECORE is unable to - fulfill a request, and HAVE_MMAP is true, then mmap is - used as a noncontiguous system allocator. This is a useful backup - strategy for systems with holes in address spaces -- in this case - sbrk cannot contiguously expand the heap, but mmap may be able to - find space. - 3. A call to MORECORE that cannot usually contiguously extend memory. - (disabled if not HAVE_MORECORE) - */ - - if (MORECORE_CONTIGUOUS && !use_noncontiguous(m)) { - char* br = CMFAIL; - msegmentptr ss = (m->top == 0)? 0 : segment_holding(m, (char*)m->top); - size_t asize = 0; - ACQUIRE_MORECORE_LOCK(); - - if (ss == 0) { /* First time through or recovery */ - char* base = (char*)CALL_MORECORE(0); - if (base != CMFAIL) { - asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); - /* Adjust to end on a page boundary */ - if (!is_page_aligned(base)) - asize += (page_align((size_t)base) - (size_t)base); - /* Can't call MORECORE if size is negative when treated as signed */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == base) { - tbase = base; - tsize = asize; - } - } - } - else { - /* Subtract out existing available top space from MORECORE request. */ - asize = granularity_align(nb - m->topsize + TOP_FOOT_SIZE + SIZE_T_ONE); - /* Use mem here only if it did continuously extend old space */ - if (asize < HALF_MAX_SIZE_T && - (br = (char*)(CALL_MORECORE(asize))) == ss->base+ss->size) { - tbase = br; - tsize = asize; - } - } - - if (tbase == CMFAIL) { /* Cope with partial failure */ - if (br != CMFAIL) { /* Try to use/extend the space we did get */ - if (asize < HALF_MAX_SIZE_T && - asize < nb + TOP_FOOT_SIZE + SIZE_T_ONE) { - size_t esize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE - asize); - if (esize < HALF_MAX_SIZE_T) { - char* end = (char*)CALL_MORECORE(esize); - if (end != CMFAIL) - asize += esize; - else { /* Can't use; try to release */ - (void) CALL_MORECORE(-asize); - br = CMFAIL; - } - } - } - } - if (br != CMFAIL) { /* Use the space we did get */ - tbase = br; - tsize = asize; - } - else - disable_contiguous(m); /* Don't try contiguous path in the future */ - } - - RELEASE_MORECORE_LOCK(); - } - - if (HAVE_MMAP && tbase == CMFAIL) { /* Try MMAP */ - size_t req = nb + TOP_FOOT_SIZE + SIZE_T_ONE; - size_t rsize = granularity_align(req); - if (rsize > nb) { /* Fail if wraps around zero */ - char* mp = (char*)(CALL_MMAP(rsize)); - if (mp != CMFAIL) { - tbase = mp; - tsize = rsize; - mmap_flag = IS_MMAPPED_BIT; - } - } - } - - if (HAVE_MORECORE && tbase == CMFAIL) { /* Try noncontiguous MORECORE */ - size_t asize = granularity_align(nb + TOP_FOOT_SIZE + SIZE_T_ONE); - if (asize < HALF_MAX_SIZE_T) { - char* br = CMFAIL; - char* end = CMFAIL; - ACQUIRE_MORECORE_LOCK(); - br = (char*)(CALL_MORECORE(asize)); - end = (char*)(CALL_MORECORE(0)); - RELEASE_MORECORE_LOCK(); - if (br != CMFAIL && end != CMFAIL && br < end) { - size_t ssize = end - br; - if (ssize > nb + TOP_FOOT_SIZE) { - tbase = br; - tsize = ssize; - } - } - } - } - - if (tbase != CMFAIL) { - - if ((m->footprint += tsize) > m->max_footprint) - m->max_footprint = m->footprint; - - if (!is_initialized(m)) { /* first-time initialization */ - m->seg.base = m->least_addr = tbase; - m->seg.size = tsize; - m->seg.sflags = mmap_flag; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - init_bins(m); -#if !ONLY_MSPACES - if (is_global(m)) - init_top(m, (mchunkptr)tbase, tsize - TOP_FOOT_SIZE); - else -#endif - { - /* Offset top by embedded malloc_state */ - mchunkptr mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) -TOP_FOOT_SIZE); - } - } - - else { - /* Try to merge with an existing segment */ - msegmentptr sp = &m->seg; - /* Only consider most recent segment if traversal suppressed */ - while (sp != 0 && tbase != sp->base + sp->size) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & IS_MMAPPED_BIT) == mmap_flag && - segment_holds(sp, m->top)) { /* append */ - sp->size += tsize; - init_top(m, m->top, m->topsize + tsize); - } - else { - if (tbase < m->least_addr) - m->least_addr = tbase; - sp = &m->seg; - while (sp != 0 && sp->base != tbase + tsize) - sp = (NO_SEGMENT_TRAVERSAL) ? 0 : sp->next; - if (sp != 0 && - !is_extern_segment(sp) && - (sp->sflags & IS_MMAPPED_BIT) == mmap_flag) { - char* oldbase = sp->base; - sp->base = tbase; - sp->size += tsize; - return prepend_alloc(m, tbase, oldbase, nb); - } - else - add_segment(m, tbase, tsize, mmap_flag); - } - } - - if (nb < m->topsize) { /* Allocate from new or extended top space */ - size_t rsize = m->topsize -= nb; - mchunkptr p = m->top; - mchunkptr r = m->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(m, p, nb); - check_top_chunk(m, m->top); - check_malloced_chunk(m, chunk2mem(p), nb); - return chunk2mem(p); - } - } - - MALLOC_FAILURE_ACTION; - return 0; -} - -/* ----------------------- system deallocation -------------------------- */ - -/* Unmap and unlink any mmapped segments that don't contain used chunks */ -static size_t release_unused_segments(mstate m) { - size_t released = 0; - int nsegs = 0; - msegmentptr pred = &m->seg; - msegmentptr sp = pred->next; - while (sp != 0) { - char* base = sp->base; - size_t size = sp->size; - msegmentptr next = sp->next; - ++nsegs; - if (is_mmapped_segment(sp) && !is_extern_segment(sp)) { - mchunkptr p = align_as_chunk(base); - size_t psize = chunksize(p); - /* Can unmap if first chunk holds entire segment and not pinned */ - if (!cinuse(p) && (char*)p + psize >= base + size - TOP_FOOT_SIZE) { - tchunkptr tp = (tchunkptr)p; - assert(segment_holds(sp, (char*)sp)); - if (p == m->dv) { - m->dv = 0; - m->dvsize = 0; - } - else { - unlink_large_chunk(m, tp); - } - if (CALL_MUNMAP(base, size) == 0) { - released += size; - m->footprint -= size; - /* unlink obsoleted record */ - sp = pred; - sp->next = next; - } - else { /* back out if cannot unmap */ - insert_large_chunk(m, tp, psize); - } - } - } - if (NO_SEGMENT_TRAVERSAL) /* scan only first segment */ - break; - pred = sp; - sp = next; - } - /* Reset check counter */ - m->release_checks = ((nsegs > MAX_RELEASE_CHECK_RATE)? - nsegs : MAX_RELEASE_CHECK_RATE); - return released; -} - -static int sys_trim(mstate m, size_t pad) { - size_t released = 0; - if (pad < MAX_REQUEST && is_initialized(m)) { - pad += TOP_FOOT_SIZE; /* ensure enough room for segment overhead */ - - if (m->topsize > pad) { - /* Shrink top space in granularity-size units, keeping at least one */ - size_t unit = mparams.granularity; - size_t extra = ((m->topsize - pad + (unit - SIZE_T_ONE)) / unit - - SIZE_T_ONE) * unit; - msegmentptr sp = segment_holding(m, (char*)m->top); - - if (!is_extern_segment(sp)) { - if (is_mmapped_segment(sp)) { - if (HAVE_MMAP && - sp->size >= extra && - !has_segment_link(m, sp)) { /* can't shrink if pinned */ - size_t newsize = sp->size - extra; - /* Prefer mremap, fall back to munmap */ - if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) || - (CALL_MUNMAP(sp->base + newsize, extra) == 0)) { - released = extra; - } - } - } - else if (HAVE_MORECORE) { - if (extra >= HALF_MAX_SIZE_T) /* Avoid wrapping negative */ - extra = (HALF_MAX_SIZE_T) + SIZE_T_ONE - unit; - ACQUIRE_MORECORE_LOCK(); - { - /* Make sure end of memory is where we last set it. */ - char* old_br = (char*)(CALL_MORECORE(0)); - if (old_br == sp->base + sp->size) { - char* rel_br = (char*)(CALL_MORECORE(-extra)); - char* new_br = (char*)(CALL_MORECORE(0)); - if (rel_br != CMFAIL && new_br < old_br) - released = old_br - new_br; - } - } - RELEASE_MORECORE_LOCK(); - } - } - - if (released != 0) { - sp->size -= released; - m->footprint -= released; - init_top(m, m->top, m->topsize - released); - check_top_chunk(m, m->top); - } - } - - /* Unmap any unused mmapped segments */ - if (HAVE_MMAP) - released += release_unused_segments(m); - - /* On failure, disable autotrim to avoid repeated failed future calls */ - if (released == 0 && m->topsize > m->trim_check) - m->trim_check = MAX_SIZE_T; - } - - return (released != 0)? 1 : 0; -} - -/* ---------------------------- malloc support --------------------------- */ - -/* allocate a large request from the best fitting chunk in a treebin */ -static void* tmalloc_large(mstate m, size_t nb) { - tchunkptr v = 0; - size_t rsize = -nb; /* Unsigned negation */ - tchunkptr t; - bindex_t idx; - compute_tree_index(nb, idx); - - if ((t = *treebin_at(m, idx)) != 0) { - /* Traverse tree for this bin looking for node with size == nb */ - size_t sizebits = nb << leftshift_for_tree_index(idx); - tchunkptr rst = 0; /* The deepest untaken right subtree */ - for (;;) { - tchunkptr rt; - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - v = t; - if ((rsize = trem) == 0) - break; - } - rt = t->child[1]; - t = t->child[(sizebits >> (SIZE_T_BITSIZE-SIZE_T_ONE)) & 1]; - if (rt != 0 && rt != t) - rst = rt; - if (t == 0) { - t = rst; /* set t to least subtree holding sizes > nb */ - break; - } - sizebits <<= 1; - } - } - - if (t == 0 && v == 0) { /* set t to root of next non-empty treebin */ - binmap_t leftbits = left_bits(idx2bit(idx)) & m->treemap; - if (leftbits != 0) { - bindex_t i; - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - t = *treebin_at(m, i); - } - } - - while (t != 0) { /* find smallest of tree or subtree */ - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - t = leftmost_child(t); - } - - /* If dv is a better fit, return 0 so malloc will use it */ - if (v != 0 && rsize < (size_t)(m->dvsize - nb)) { - if (RTCHECK(ok_address(m, v))) { /* split */ - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - insert_chunk(m, r, rsize); - } - return chunk2mem(v); - } - } - CORRUPTION_ERROR_ACTION(m); - } - return 0; -} - -/* allocate a small request from the best fitting chunk in a treebin */ -static void* tmalloc_small(mstate m, size_t nb) { - tchunkptr t, v; - size_t rsize; - bindex_t i; - binmap_t leastbit = least_bit(m->treemap); - compute_bit2idx(leastbit, i); - - v = t = *treebin_at(m, i); - rsize = chunksize(t) - nb; - - while ((t = leftmost_child(t)) != 0) { - size_t trem = chunksize(t) - nb; - if (trem < rsize) { - rsize = trem; - v = t; - } - } - - if (RTCHECK(ok_address(m, v))) { - mchunkptr r = chunk_plus_offset(v, nb); - assert(chunksize(v) == rsize + nb); - if (RTCHECK(ok_next(v, r))) { - unlink_large_chunk(m, v); - if (rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(m, v, (rsize + nb)); - else { - set_size_and_pinuse_of_inuse_chunk(m, v, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(m, r, rsize); - } - return chunk2mem(v); - } - } - - CORRUPTION_ERROR_ACTION(m); - return 0; -} - -/* --------------------------- realloc support --------------------------- */ - -static void* internal_realloc(mstate m, void* oldmem, size_t bytes) { - if (bytes >= MAX_REQUEST) { - MALLOC_FAILURE_ACTION; - return 0; - } - if (!PREACTION(m)) { - mchunkptr oldp = mem2chunk(oldmem); - size_t oldsize = chunksize(oldp); - mchunkptr next = chunk_plus_offset(oldp, oldsize); - mchunkptr newp = 0; - void* extra = 0; - - /* Try to either shrink or extend into top. Else malloc-copy-free */ - - if (RTCHECK(ok_address(m, oldp) && ok_cinuse(oldp) && - ok_next(oldp, next) && ok_pinuse(next))) { - size_t nb = request2size(bytes); - if (is_mmapped(oldp)) - newp = mmap_resize(m, oldp, nb); - else if (oldsize >= nb) { /* already big enough */ - size_t rsize = oldsize - nb; - newp = oldp; - if (rsize >= MIN_CHUNK_SIZE) { - mchunkptr remainder = chunk_plus_offset(newp, nb); - set_inuse(m, newp, nb); - set_inuse(m, remainder, rsize); - extra = chunk2mem(remainder); - } - } - else if (next == m->top && oldsize + m->topsize > nb) { - /* Expand into top */ - size_t newsize = oldsize + m->topsize; - size_t newtopsize = newsize - nb; - mchunkptr newtop = chunk_plus_offset(oldp, nb); - set_inuse(m, oldp, nb); - newtop->head = newtopsize |PINUSE_BIT; - m->top = newtop; - m->topsize = newtopsize; - newp = oldp; - } - } - else { - USAGE_ERROR_ACTION(m, oldmem); - POSTACTION(m); - return 0; - } - - POSTACTION(m); - - if (newp != 0) { - if (extra != 0) { - internal_free(m, extra); - } - check_inuse_chunk(m, newp); - return chunk2mem(newp); - } - else { - void* newmem = internal_malloc(m, bytes); - if (newmem != 0) { - size_t oc = oldsize - overhead_for(oldp); - memcpy(newmem, oldmem, (oc < bytes)? oc : bytes); - internal_free(m, oldmem); - } - return newmem; - } - } - return 0; -} - -/* --------------------------- memalign support -------------------------- */ - -static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { - if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ - return internal_malloc(m, bytes); - if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ - alignment = MIN_CHUNK_SIZE; - if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ - size_t a = MALLOC_ALIGNMENT << 1; - while (a < alignment) a <<= 1; - alignment = a; - } - - if (bytes >= MAX_REQUEST - alignment) { - if (m != 0) { /* Test isn't needed but avoids compiler warning */ - MALLOC_FAILURE_ACTION; - } - } - else { - size_t nb = request2size(bytes); - size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; - char* mem = (char*)internal_malloc(m, req); - if (mem != 0) { - void* leader = 0; - void* trailer = 0; - mchunkptr p = mem2chunk(mem); - - if (PREACTION(m)) return 0; - if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ - /* - Find an aligned spot inside chunk. Since we need to give - back leading space in a chunk of at least MIN_CHUNK_SIZE, if - the first calculation places us at a spot with less than - MIN_CHUNK_SIZE leader, we can move to the next aligned spot. - We've allocated enough total room so that this is always - possible. - */ - char* br = (char*)mem2chunk((size_t)(((size_t)(mem + - alignment - - SIZE_T_ONE)) & - -alignment)); - char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? - br : br+alignment; - mchunkptr newp = (mchunkptr)pos; - size_t leadsize = pos - (char*)(p); - size_t newsize = chunksize(p) - leadsize; - - if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ - newp->prev_foot = p->prev_foot + leadsize; - newp->head = (newsize|CINUSE_BIT); - } - else { /* Otherwise, give back leader, use the rest */ - set_inuse(m, newp, newsize); - set_inuse(m, p, leadsize); - leader = chunk2mem(p); - } - p = newp; - } - - /* Give back spare room at the end */ - if (!is_mmapped(p)) { - size_t size = chunksize(p); - if (size > nb + MIN_CHUNK_SIZE) { - size_t remainder_size = size - nb; - mchunkptr remainder = chunk_plus_offset(p, nb); - set_inuse(m, p, nb); - set_inuse(m, remainder, remainder_size); - trailer = chunk2mem(remainder); - } - } - - assert (chunksize(p) >= nb); - assert((((size_t)(chunk2mem(p))) % alignment) == 0); - check_inuse_chunk(m, p); - POSTACTION(m); - if (leader != 0) { - internal_free(m, leader); - } - if (trailer != 0) { - internal_free(m, trailer); - } - return chunk2mem(p); - } - } - return 0; -} - -/* ------------------------ comalloc/coalloc support --------------------- */ - -static void** ialloc(mstate m, - size_t n_elements, - size_t* sizes, - int opts, - void* chunks[]) { - /* - This provides common support for independent_X routines, handling - all of the combinations that can result. - - The opts arg has: - bit 0 set if all elements are same size (using sizes[0]) - bit 1 set if elements should be zeroed - */ - - size_t element_size; /* chunksize of each element, if all same */ - size_t contents_size; /* total size of elements */ - size_t array_size; /* request size of pointer array */ - void* mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - size_t remainder_size; /* remaining bytes while splitting */ - void** marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - flag_t was_enabled; /* to disable mmap */ - size_t size; - size_t i; - - /* compute array length, if needed */ - if (chunks != 0) { - if (n_elements == 0) - return chunks; /* nothing to do */ - marray = chunks; - array_size = 0; - } - else { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) - return (void**)internal_malloc(m, 0); - marray = 0; - array_size = request2size(n_elements * (sizeof(void*))); - } - - /* compute total element size */ - if (opts & 0x1) { /* all-same-size */ - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } - else { /* add up all the sizes */ - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) - contents_size += request2size(sizes[i]); - } - - size = contents_size + array_size; - - /* - Allocate the aggregate chunk. First disable direct-mmapping so - malloc won't use it, since we would not be able to later - free/realloc space internal to a segregated mmap region. - */ - was_enabled = use_mmap(m); - disable_mmap(m); - mem = internal_malloc(m, size - CHUNK_OVERHEAD); - if (was_enabled) - enable_mmap(m); - if (mem == 0) - return 0; - - if (PREACTION(m)) return 0; - p = mem2chunk(mem); - remainder_size = chunksize(p); - - assert(!is_mmapped(p)); - - if (opts & 0x2) { /* optionally clear the elements */ - memset((size_t*)mem, 0, remainder_size - SIZE_T_SIZE - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) { - size_t array_chunk_size; - array_chunk = chunk_plus_offset(p, contents_size); - array_chunk_size = remainder_size - contents_size; - marray = (void**) (chunk2mem(array_chunk)); - set_size_and_pinuse_of_inuse_chunk(m, array_chunk, array_chunk_size); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0; ; ++i) { - marray[i] = chunk2mem(p); - if (i != n_elements-1) { - if (element_size != 0) - size = element_size; - else - size = request2size(sizes[i]); - remainder_size -= size; - set_size_and_pinuse_of_inuse_chunk(m, p, size); - p = chunk_plus_offset(p, size); - } - else { /* the final element absorbs any overallocation slop */ - set_size_and_pinuse_of_inuse_chunk(m, p, remainder_size); - break; - } - } - -#if DEBUG - if (marray != chunks) { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) { - assert(remainder_size == element_size); - } - else { - assert(remainder_size == request2size(sizes[i])); - } - check_inuse_chunk(m, mem2chunk(marray)); - } - for (i = 0; i != n_elements; ++i) - check_inuse_chunk(m, mem2chunk(marray[i])); - -#endif /* DEBUG */ - - POSTACTION(m); - return marray; -} - - -/* -------------------------- public routines ---------------------------- */ - -#if !ONLY_MSPACES - -void* dlmalloc(size_t bytes) { - /* - Basic algorithm: - If a small request (< 256 bytes minus per-chunk overhead): - 1. If one exists, use a remainderless chunk in associated smallbin. - (Remainderless means that there are too few excess bytes to - represent as a chunk.) - 2. If it is big enough, use the dv chunk, which is normally the - chunk adjacent to the one used for the most recent small request. - 3. If one exists, split the smallest available chunk in a bin, - saving remainder in dv. - 4. If it is big enough, use the top chunk. - 5. If available, get memory from system and use it - Otherwise, for a large request: - 1. Find the smallest available binned chunk that fits, and use it - if it is better fitting than dv chunk, splitting if necessary. - 2. If better fitting than any binned chunk, use the dv chunk. - 3. If it is big enough, use the top chunk. - 4. If request size >= mmap threshold, try to directly mmap this chunk. - 5. If available, get memory from system and use it - - The ugly goto's here ensure that postaction occurs along all paths. - */ - - if (!PREACTION(gm)) { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = gm->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(gm, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(gm, b, p, idx); - set_inuse_and_pinuse(gm, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb > gm->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(gm, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(gm, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(gm, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(gm, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (gm->treemap != 0 && (mem = tmalloc_small(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (gm->treemap != 0 && (mem = tmalloc_large(gm, nb)) != 0) { - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - } - - if (nb <= gm->dvsize) { - size_t rsize = gm->dvsize - nb; - mchunkptr p = gm->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = gm->dv = chunk_plus_offset(p, nb); - gm->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - } - else { /* exhaust dv */ - size_t dvs = gm->dvsize; - gm->dvsize = 0; - gm->dv = 0; - set_inuse_and_pinuse(gm, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - else if (nb < gm->topsize) { /* Split top */ - size_t rsize = gm->topsize -= nb; - mchunkptr p = gm->top; - mchunkptr r = gm->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(gm, p, nb); - mem = chunk2mem(p); - check_top_chunk(gm, gm->top); - check_malloced_chunk(gm, mem, nb); - goto postaction; - } - - mem = sys_alloc(gm, nb); - - postaction: - POSTACTION(gm); - return mem; - } - - return 0; -} - -void dlfree(void* mem) { - /* - Consolidate freed chunks with preceeding or succeeding bordering - free chunks, if they exist, and then place in a bin. Intermixed - with special cases for top, dv, mmapped chunks, and usage errors. - */ - - if (mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } -#else /* FOOTERS */ -#define fm gm -#endif /* FOOTERS */ - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if ((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } - else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } - else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } - else - set_free_with_pinuse(p, psize, next); - - if (is_small(psize)) { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - release_unused_segments(fm); - } - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -#if !FOOTERS -#undef fm -#endif /* FOOTERS */ -} - -void* dlcalloc(size_t n_elements, size_t elem_size) { - void* mem; - size_t req = 0; - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = dlmalloc(req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void* dlrealloc(void* oldmem, size_t bytes) { - if (oldmem == 0) - return dlmalloc(bytes); -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - dlfree(oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { -#if ! FOOTERS - mstate m = gm; -#else /* FOOTERS */ - mstate m = get_mstate_for(mem2chunk(oldmem)); - if (!ok_magic(m)) { - USAGE_ERROR_ACTION(m, oldmem); - return 0; - } -#endif /* FOOTERS */ - return internal_realloc(m, oldmem, bytes); - } -} - -void* dlmemalign(size_t alignment, size_t bytes) { - return internal_memalign(gm, alignment, bytes); -} - -void** dlindependent_calloc(size_t n_elements, size_t elem_size, - void* chunks[]) { - size_t sz = elem_size; /* serves as 1-element array */ - return ialloc(gm, n_elements, &sz, 3, chunks); -} - -void** dlindependent_comalloc(size_t n_elements, size_t sizes[], - void* chunks[]) { - return ialloc(gm, n_elements, sizes, 0, chunks); -} - -void* dlvalloc(size_t bytes) { - size_t pagesz; - init_mparams(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, bytes); -} - -void* dlpvalloc(size_t bytes) { - size_t pagesz; - init_mparams(); - pagesz = mparams.page_size; - return dlmemalign(pagesz, (bytes + pagesz - SIZE_T_ONE) & ~(pagesz - SIZE_T_ONE)); -} - -int dlmalloc_trim(size_t pad) { - int result = 0; - if (!PREACTION(gm)) { - result = sys_trim(gm, pad); - POSTACTION(gm); - } - return result; -} - -size_t dlmalloc_footprint(void) { - return gm->footprint; -} - -size_t dlmalloc_max_footprint(void) { - return gm->max_footprint; -} - -#if !NO_MALLINFO -struct mallinfo dlmallinfo(void) { - return internal_mallinfo(gm); -} -#endif /* NO_MALLINFO */ - -void dlmalloc_stats() { - internal_malloc_stats(gm); -} - -size_t dlmalloc_usable_size(void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -int dlmallopt(int param_number, int value) { - return change_mparam(param_number, value); -} - -#endif /* !ONLY_MSPACES */ - -/* ----------------------------- user mspaces ---------------------------- */ - -#if MSPACES - -static mstate init_user_mstate(char* tbase, size_t tsize) { - size_t msize = pad_request(sizeof(struct malloc_state)); - mchunkptr mn; - mchunkptr msp = align_as_chunk(tbase); - mstate m = (mstate)(chunk2mem(msp)); - memset(m, 0, msize); - INITIAL_LOCK(&m->mutex); - msp->head = (msize|PINUSE_BIT|CINUSE_BIT); - m->seg.base = m->least_addr = tbase; - m->seg.size = m->footprint = m->max_footprint = tsize; - m->magic = mparams.magic; - m->release_checks = MAX_RELEASE_CHECK_RATE; - m->mflags = mparams.default_mflags; - m->extp = 0; - m->exts = 0; - disable_contiguous(m); - init_bins(m); - mn = next_chunk(mem2chunk(m)); - init_top(m, mn, (size_t)((tbase + tsize) - (char*)mn) - TOP_FOOT_SIZE); - check_top_chunk(m, m->top); - return m; -} - -mspace create_mspace(size_t capacity, int locked) { - mstate m = 0; - size_t msize = pad_request(sizeof(struct malloc_state)); - init_mparams(); /* Ensure pagesize etc initialized */ - - if (capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { - size_t rs = ((capacity == 0)? mparams.granularity : - (capacity + TOP_FOOT_SIZE + msize)); - size_t tsize = granularity_align(rs); - char* tbase = (char*)(CALL_MMAP(tsize)); - if (tbase != CMFAIL) { - m = init_user_mstate(tbase, tsize); - m->seg.sflags = IS_MMAPPED_BIT; - set_lock(m, locked); - } - } - return (mspace)m; -} - -mspace create_mspace_with_base(void* base, size_t capacity, int locked) { - mstate m = 0; - size_t msize = pad_request(sizeof(struct malloc_state)); - init_mparams(); /* Ensure pagesize etc initialized */ - - if (capacity > msize + TOP_FOOT_SIZE && - capacity < (size_t) -(msize + TOP_FOOT_SIZE + mparams.page_size)) { - m = init_user_mstate((char*)base, capacity); - m->seg.sflags = EXTERN_BIT; - set_lock(m, locked); - } - return (mspace)m; -} - -size_t destroy_mspace(mspace msp) { - size_t freed = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - msegmentptr sp = &ms->seg; - while (sp != 0) { - char* base = sp->base; - size_t size = sp->size; - flag_t flag = sp->sflags; - sp = sp->next; - if ((flag & IS_MMAPPED_BIT) && !(flag & EXTERN_BIT) && - CALL_MUNMAP(base, size) == 0) - freed += size; - } - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return freed; -} - -/* - mspace versions of routines are near-clones of the global - versions. This is not so nice but better than the alternatives. -*/ - - -void* mspace_malloc(mspace msp, size_t bytes) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - if (!PREACTION(ms)) { - void* mem; - size_t nb; - if (bytes <= MAX_SMALL_REQUEST) { - bindex_t idx; - binmap_t smallbits; - nb = (bytes < MIN_REQUEST)? MIN_CHUNK_SIZE : pad_request(bytes); - idx = small_index(nb); - smallbits = ms->smallmap >> idx; - - if ((smallbits & 0x3U) != 0) { /* Remainderless fit to a smallbin. */ - mchunkptr b, p; - idx += ~smallbits & 1; /* Uses next bin if idx empty */ - b = smallbin_at(ms, idx); - p = b->fd; - assert(chunksize(p) == small_index2size(idx)); - unlink_first_small_chunk(ms, b, p, idx); - set_inuse_and_pinuse(ms, p, small_index2size(idx)); - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb > ms->dvsize) { - if (smallbits != 0) { /* Use chunk in next nonempty smallbin */ - mchunkptr b, p, r; - size_t rsize; - bindex_t i; - binmap_t leftbits = (smallbits << idx) & left_bits(idx2bit(idx)); - binmap_t leastbit = least_bit(leftbits); - compute_bit2idx(leastbit, i); - b = smallbin_at(ms, i); - p = b->fd; - assert(chunksize(p) == small_index2size(i)); - unlink_first_small_chunk(ms, b, p, i); - rsize = small_index2size(i) - nb; - /* Fit here cannot be remainderless if 4byte sizes */ - if (SIZE_T_SIZE != 4 && rsize < MIN_CHUNK_SIZE) - set_inuse_and_pinuse(ms, p, small_index2size(i)); - else { - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - r = chunk_plus_offset(p, nb); - set_size_and_pinuse_of_free_chunk(r, rsize); - replace_dv(ms, r, rsize); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (ms->treemap != 0 && (mem = tmalloc_small(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - } - else if (bytes >= MAX_REQUEST) - nb = MAX_SIZE_T; /* Too big to allocate. Force failure (in sys alloc) */ - else { - nb = pad_request(bytes); - if (ms->treemap != 0 && (mem = tmalloc_large(ms, nb)) != 0) { - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - } - - if (nb <= ms->dvsize) { - size_t rsize = ms->dvsize - nb; - mchunkptr p = ms->dv; - if (rsize >= MIN_CHUNK_SIZE) { /* split dv */ - mchunkptr r = ms->dv = chunk_plus_offset(p, nb); - ms->dvsize = rsize; - set_size_and_pinuse_of_free_chunk(r, rsize); - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - } - else { /* exhaust dv */ - size_t dvs = ms->dvsize; - ms->dvsize = 0; - ms->dv = 0; - set_inuse_and_pinuse(ms, p, dvs); - } - mem = chunk2mem(p); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - else if (nb < ms->topsize) { /* Split top */ - size_t rsize = ms->topsize -= nb; - mchunkptr p = ms->top; - mchunkptr r = ms->top = chunk_plus_offset(p, nb); - r->head = rsize | PINUSE_BIT; - set_size_and_pinuse_of_inuse_chunk(ms, p, nb); - mem = chunk2mem(p); - check_top_chunk(ms, ms->top); - check_malloced_chunk(ms, mem, nb); - goto postaction; - } - - mem = sys_alloc(ms, nb); - - postaction: - POSTACTION(ms); - return mem; - } - - return 0; -} - -void mspace_free(mspace msp, void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); -#if FOOTERS - mstate fm = get_mstate_for(p); -#else /* FOOTERS */ - mstate fm = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(fm)) { - USAGE_ERROR_ACTION(fm, p); - return; - } - if (!PREACTION(fm)) { - check_inuse_chunk(fm, p); - if (RTCHECK(ok_address(fm, p) && ok_cinuse(p))) { - size_t psize = chunksize(p); - mchunkptr next = chunk_plus_offset(p, psize); - if (!pinuse(p)) { - size_t prevsize = p->prev_foot; - if ((prevsize & IS_MMAPPED_BIT) != 0) { - prevsize &= ~IS_MMAPPED_BIT; - psize += prevsize + MMAP_FOOT_PAD; - if (CALL_MUNMAP((char*)p - prevsize, psize) == 0) - fm->footprint -= psize; - goto postaction; - } - else { - mchunkptr prev = chunk_minus_offset(p, prevsize); - psize += prevsize; - p = prev; - if (RTCHECK(ok_address(fm, prev))) { /* consolidate backward */ - if (p != fm->dv) { - unlink_chunk(fm, p, prevsize); - } - else if ((next->head & INUSE_BITS) == INUSE_BITS) { - fm->dvsize = psize; - set_free_with_pinuse(p, psize, next); - goto postaction; - } - } - else - goto erroraction; - } - } - - if (RTCHECK(ok_next(p, next) && ok_pinuse(next))) { - if (!cinuse(next)) { /* consolidate forward */ - if (next == fm->top) { - size_t tsize = fm->topsize += psize; - fm->top = p; - p->head = tsize | PINUSE_BIT; - if (p == fm->dv) { - fm->dv = 0; - fm->dvsize = 0; - } - if (should_trim(fm, tsize)) - sys_trim(fm, 0); - goto postaction; - } - else if (next == fm->dv) { - size_t dsize = fm->dvsize += psize; - fm->dv = p; - set_size_and_pinuse_of_free_chunk(p, dsize); - goto postaction; - } - else { - size_t nsize = chunksize(next); - psize += nsize; - unlink_chunk(fm, next, nsize); - set_size_and_pinuse_of_free_chunk(p, psize); - if (p == fm->dv) { - fm->dvsize = psize; - goto postaction; - } - } - } - else - set_free_with_pinuse(p, psize, next); - - if (is_small(psize)) { - insert_small_chunk(fm, p, psize); - check_free_chunk(fm, p); - } - else { - tchunkptr tp = (tchunkptr)p; - insert_large_chunk(fm, tp, psize); - check_free_chunk(fm, p); - if (--fm->release_checks == 0) - release_unused_segments(fm); - } - goto postaction; - } - } - erroraction: - USAGE_ERROR_ACTION(fm, p); - postaction: - POSTACTION(fm); - } - } -} - -void* mspace_calloc(mspace msp, size_t n_elements, size_t elem_size) { - void* mem; - size_t req = 0; - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - if (n_elements != 0) { - req = n_elements * elem_size; - if (((n_elements | elem_size) & ~(size_t)0xffff) && - (req / n_elements != elem_size)) - req = MAX_SIZE_T; /* force downstream failure on overflow */ - } - mem = internal_malloc(ms, req); - if (mem != 0 && calloc_must_clear(mem2chunk(mem))) - memset(mem, 0, req); - return mem; -} - -void* mspace_realloc(mspace msp, void* oldmem, size_t bytes) { - if (oldmem == 0) - return mspace_malloc(msp, bytes); -#ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - mspace_free(msp, oldmem); - return 0; - } -#endif /* REALLOC_ZERO_BYTES_FREES */ - else { -#if FOOTERS - mchunkptr p = mem2chunk(oldmem); - mstate ms = get_mstate_for(p); -#else /* FOOTERS */ - mstate ms = (mstate)msp; -#endif /* FOOTERS */ - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return internal_realloc(ms, oldmem, bytes); - } -} - -void* mspace_memalign(mspace msp, size_t alignment, size_t bytes) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return internal_memalign(ms, alignment, bytes); -} - -void** mspace_independent_calloc(mspace msp, size_t n_elements, - size_t elem_size, void* chunks[]) { - size_t sz = elem_size; /* serves as 1-element array */ - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return ialloc(ms, n_elements, &sz, 3, chunks); -} - -void** mspace_independent_comalloc(mspace msp, size_t n_elements, - size_t sizes[], void* chunks[]) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - return 0; - } - return ialloc(ms, n_elements, sizes, 0, chunks); -} - -int mspace_trim(mspace msp, size_t pad) { - int result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - if (!PREACTION(ms)) { - result = sys_trim(ms, pad); - POSTACTION(ms); - } - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - -void mspace_malloc_stats(mspace msp) { - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - internal_malloc_stats(ms); - } - else { - USAGE_ERROR_ACTION(ms,ms); - } -} - -size_t mspace_footprint(mspace msp) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - result = ms->footprint; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - - -size_t mspace_max_footprint(mspace msp) { - size_t result = 0; - mstate ms = (mstate)msp; - if (ok_magic(ms)) { - result = ms->max_footprint; - } - else { - USAGE_ERROR_ACTION(ms,ms); - } - return result; -} - - -#if !NO_MALLINFO -struct mallinfo mspace_mallinfo(mspace msp) { - mstate ms = (mstate)msp; - if (!ok_magic(ms)) { - USAGE_ERROR_ACTION(ms,ms); - } - return internal_mallinfo(ms); -} -#endif /* NO_MALLINFO */ - -size_t mspace_usable_size(void* mem) { - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -int mspace_mallopt(int param_number, int value) { - return change_mparam(param_number, value); -} - -#endif /* MSPACES */ - -/* -------------------- Alternative MORECORE functions ------------------- */ - -/* - Guidelines for creating a custom version of MORECORE: - - * For best performance, MORECORE should allocate in multiples of pagesize. - * MORECORE may allocate more memory than requested. (Or even less, - but this will usually result in a malloc failure.) - * MORECORE must not allocate memory when given argument zero, but - instead return one past the end address of memory from previous - nonzero call. - * For best performance, consecutive calls to MORECORE with positive - arguments should return increasing addresses, indicating that - space has been contiguously extended. - * Even though consecutive calls to MORECORE need not return contiguous - addresses, it must be OK for malloc'ed chunks to span multiple - regions in those cases where they do happen to be contiguous. - * MORECORE need not handle negative arguments -- it may instead - just return MFAIL when given negative arguments. - Negative arguments are always multiples of pagesize. MORECORE - must not misinterpret negative args as large positive unsigned - args. You can suppress all such calls from even occurring by defining - MORECORE_CANNOT_TRIM, - - As an example alternative MORECORE, here is a custom allocator - kindly contributed for pre-OSX macOS. It uses virtually but not - necessarily physically contiguous non-paged memory (locked in, - present and won't get swapped out). You can use it by uncommenting - this section, adding some #includes, and setting up the appropriate - defines above: - - #define MORECORE osMoreCore - - There is also a shutdown routine that should somehow be called for - cleanup upon program exit. - - #define MAX_POOL_ENTRIES 100 - #define MINIMUM_MORECORE_SIZE (64 * 1024U) - static int next_os_pool; - void *our_os_pools[MAX_POOL_ENTRIES]; - - void *osMoreCore(int size) - { - void *ptr = 0; - static void *sbrk_top = 0; - - if (size > 0) - { - if (size < MINIMUM_MORECORE_SIZE) - size = MINIMUM_MORECORE_SIZE; - if (CurrentExecutionLevel() == kTaskLevel) - ptr = PoolAllocateResident(size + RM_PAGE_SIZE, 0); - if (ptr == 0) - { - return (void *) MFAIL; - } - // save ptrs so they can be freed during cleanup - our_os_pools[next_os_pool] = ptr; - next_os_pool++; - ptr = (void *) ((((size_t) ptr) + RM_PAGE_MASK) & ~RM_PAGE_MASK); - sbrk_top = (char *) ptr + size; - return ptr; - } - else if (size < 0) - { - // we don't currently support shrink behavior - return (void *) MFAIL; - } - else - { - return sbrk_top; - } - } - - // cleanup any allocated memory pools - // called as last thing before shutting down driver - - void osCleanupMem(void) - { - void **ptr; - - for (ptr = our_os_pools; ptr < &our_os_pools[MAX_POOL_ENTRIES]; ptr++) - if (*ptr) - { - PoolDeallocate(*ptr); - *ptr = 0; - } - } - -*/ - - -/* ----------------------------------------------------------------------- -History: - V2.8.4 (not yet released) - * Fix bad error check in mspace_footprint - * Adaptations for ptmalloc, courtesy of Wolfram Gloger. - * Reentrant spin locks, courtesy of Earl Chew and others - * Win32 improvements, courtesy of Niall Douglas and Earl Chew - * Add NO_SEGMENT_TRAVERSAL and MAX_RELEASE_CHECK_RATE options - * Various small adjustments to reduce warnings on some compilers - * Extension hook in malloc_state - - V2.8.3 Thu Sep 22 11:16:32 2005 Doug Lea (dl at gee) - * Add max_footprint functions - * Ensure all appropriate literals are size_t - * Fix conditional compilation problem for some #define settings - * Avoid concatenating segments with the one provided - in create_mspace_with_base - * Rename some variables to avoid compiler shadowing warnings - * Use explicit lock initialization. - * Better handling of sbrk interference. - * Simplify and fix segment insertion, trimming and mspace_destroy - * Reinstate REALLOC_ZERO_BYTES_FREES option from 2.7.x - * Thanks especially to Dennis Flanagan for help on these. - - V2.8.2 Sun Jun 12 16:01:10 2005 Doug Lea (dl at gee) - * Fix memalign brace error. - - V2.8.1 Wed Jun 8 16:11:46 2005 Doug Lea (dl at gee) - * Fix improper #endif nesting in C++ - * Add explicit casts needed for C++ - - V2.8.0 Mon May 30 14:09:02 2005 Doug Lea (dl at gee) - * Use trees for large bins - * Support mspaces - * Use segments to unify sbrk-based and mmap-based system allocation, - removing need for emulation on most platforms without sbrk. - * Default safety checks - * Optional footer checks. Thanks to William Robertson for the idea. - * Internal code refactoring - * Incorporate suggestions and platform-specific changes. - Thanks to Dennis Flanagan, Colin Plumb, Niall Douglas, - Aaron Bachmann, Emery Berger, and others. - * Speed up non-fastbin processing enough to remove fastbins. - * Remove useless cfree() to avoid conflicts with other apps. - * Remove internal memcpy, memset. Compilers handle builtins better. - * Remove some options that no one ever used and rename others. - - V2.7.2 Sat Aug 17 09:07:30 2002 Doug Lea (dl at gee) - * Fix malloc_state bitmap array misdeclaration - - V2.7.1 Thu Jul 25 10:58:03 2002 Doug Lea (dl at gee) - * Allow tuning of FIRST_SORTED_BIN_SIZE - * Use PTR_UINT as type for all ptr->int casts. Thanks to John Belmonte. - * Better detection and support for non-contiguousness of MORECORE. - Thanks to Andreas Mueller, Conal Walsh, and Wolfram Gloger - * Bypass most of malloc if no frees. Thanks To Emery Berger. - * Fix freeing of old top non-contiguous chunk im sysmalloc. - * Raised default trim and map thresholds to 256K. - * Fix mmap-related #defines. Thanks to Lubos Lunak. - * Fix copy macros; added LACKS_FCNTL_H. Thanks to Neal Walfield. - * Branch-free bin calculation - * Default trim and mmap thresholds now 256K. - - V2.7.0 Sun Mar 11 14:14:06 2001 Doug Lea (dl at gee) - * Introduce independent_comalloc and independent_calloc. - Thanks to Michael Pachos for motivation and help. - * Make optional .h file available - * Allow > 2GB requests on 32bit systems. - * new WIN32 sbrk, mmap, munmap, lock code from . - Thanks also to Andreas Mueller , - and Anonymous. - * Allow override of MALLOC_ALIGNMENT (Thanks to Ruud Waij for - helping test this.) - * memalign: check alignment arg - * realloc: don't try to shift chunks backwards, since this - leads to more fragmentation in some programs and doesn't - seem to help in any others. - * Collect all cases in malloc requiring system memory into sysmalloc - * Use mmap as backup to sbrk - * Place all internal state in malloc_state - * Introduce fastbins (although similar to 2.5.1) - * Many minor tunings and cosmetic improvements - * Introduce USE_PUBLIC_MALLOC_WRAPPERS, USE_MALLOC_LOCK - * Introduce MALLOC_FAILURE_ACTION, MORECORE_CONTIGUOUS - Thanks to Tony E. Bennett and others. - * Include errno.h to support default failure action. - - V2.6.6 Sun Dec 5 07:42:19 1999 Doug Lea (dl at gee) - * return null for negative arguments - * Added Several WIN32 cleanups from Martin C. Fong - * Add 'LACKS_SYS_PARAM_H' for those systems without 'sys/param.h' - (e.g. WIN32 platforms) - * Cleanup header file inclusion for WIN32 platforms - * Cleanup code to avoid Microsoft Visual C++ compiler complaints - * Add 'USE_DL_PREFIX' to quickly allow co-existence with existing - memory allocation routines - * Set 'malloc_getpagesize' for WIN32 platforms (needs more work) - * Use 'assert' rather than 'ASSERT' in WIN32 code to conform to - usage of 'assert' in non-WIN32 code - * Improve WIN32 'sbrk()' emulation's 'findRegion()' routine to - avoid infinite loop - * Always call 'fREe()' rather than 'free()' - - V2.6.5 Wed Jun 17 15:57:31 1998 Doug Lea (dl at gee) - * Fixed ordering problem with boundary-stamping - - V2.6.3 Sun May 19 08:17:58 1996 Doug Lea (dl at gee) - * Added pvalloc, as recommended by H.J. Liu - * Added 64bit pointer support mainly from Wolfram Gloger - * Added anonymously donated WIN32 sbrk emulation - * Malloc, calloc, getpagesize: add optimizations from Raymond Nijssen - * malloc_extend_top: fix mask error that caused wastage after - foreign sbrks - * Add linux mremap support code from HJ Liu - - V2.6.2 Tue Dec 5 06:52:55 1995 Doug Lea (dl at gee) - * Integrated most documentation with the code. - * Add support for mmap, with help from - Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Use last_remainder in more cases. - * Pack bins using idea from colin@nyx10.cs.du.edu - * Use ordered bins instead of best-fit threshhold - * Eliminate block-local decls to simplify tracing and debugging. - * Support another case of realloc via move into top - * Fix error occuring when initial sbrk_base not word-aligned. - * Rely on page size for units instead of SBRK_UNIT to - avoid surprises about sbrk alignment conventions. - * Add mallinfo, mallopt. Thanks to Raymond Nijssen - (raymond@es.ele.tue.nl) for the suggestion. - * Add `pad' argument to malloc_trim and top_pad mallopt parameter. - * More precautions for cases where other routines call sbrk, - courtesy of Wolfram Gloger (Gloger@lrz.uni-muenchen.de). - * Added macros etc., allowing use in linux libc from - H.J. Lu (hjl@gnu.ai.mit.edu) - * Inverted this history list - - V2.6.1 Sat Dec 2 14:10:57 1995 Doug Lea (dl at gee) - * Re-tuned and fixed to behave more nicely with V2.6.0 changes. - * Removed all preallocation code since under current scheme - the work required to undo bad preallocations exceeds - the work saved in good cases for most test programs. - * No longer use return list or unconsolidated bins since - no scheme using them consistently outperforms those that don't - given above changes. - * Use best fit for very large chunks to prevent some worst-cases. - * Added some support for debugging - - V2.6.0 Sat Nov 4 07:05:23 1995 Doug Lea (dl at gee) - * Removed footers when chunks are in use. Thanks to - Paul Wilson (wilson@cs.texas.edu) for the suggestion. - - V2.5.4 Wed Nov 1 07:54:51 1995 Doug Lea (dl at gee) - * Added malloc_trim, with help from Wolfram Gloger - (wmglo@Dent.MED.Uni-Muenchen.DE). - - V2.5.3 Tue Apr 26 10:16:01 1994 Doug Lea (dl at g) - - V2.5.2 Tue Apr 5 16:20:40 1994 Doug Lea (dl at g) - * realloc: try to expand in both directions - * malloc: swap order of clean-bin strategy; - * realloc: only conditionally expand backwards - * Try not to scavenge used bins - * Use bin counts as a guide to preallocation - * Occasionally bin return list chunks in first scan - * Add a few optimizations from colin@nyx10.cs.du.edu - - V2.5.1 Sat Aug 14 15:40:43 1993 Doug Lea (dl at g) - * faster bin computation & slightly different binning - * merged all consolidations to one part of malloc proper - (eliminating old malloc_find_space & malloc_clean_bin) - * Scan 2 returns chunks (not just 1) - * Propagate failure in realloc if malloc returns 0 - * Add stuff to allow compilation on non-ANSI compilers - from kpv@research.att.com - - V2.5 Sat Aug 7 07:41:59 1993 Doug Lea (dl at g.oswego.edu) - * removed potential for odd address access in prev_chunk - * removed dependency on getpagesize.h - * misc cosmetics and a bit more internal documentation - * anticosmetics: mangled names in macros to evade debugger strangeness - * tested on sparc, hp-700, dec-mips, rs6000 - with gcc & native cc (hp, dec only) allowing - Detlefs & Zorn comparison study (in SIGPLAN Notices.) - - Trial version Fri Aug 28 13:14:29 1992 Doug Lea (dl at g.oswego.edu) - * Based loosely on libg++-1.2X malloc. (It retains some of the overall - structure of old version, but most details differ.) - -*/ - - diff --git a/src/3rdparty/ptmalloc/ptmalloc3.c b/src/3rdparty/ptmalloc/ptmalloc3.c deleted file mode 100644 index 12914049fb..0000000000 --- a/src/3rdparty/ptmalloc/ptmalloc3.c +++ /dev/null @@ -1,1135 +0,0 @@ -/* - * $Id: ptmalloc3.c,v 1.8 2006/03/31 15:57:28 wg Exp $ - * - -ptmalloc3 -- wrapper for Doug Lea's malloc-2.8.3 with concurrent - allocations - -Copyright (c) 2005, 2006 Wolfram Gloger - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that (i) the above copyright notices and this permission -notice appear in all copies of the software and related documentation, -and (ii) the name of Wolfram Gloger may not be used in any advertising -or publicity relating to the software. - -THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -IN NO EVENT SHALL WOLFRAM GLOGER BE LIABLE FOR ANY SPECIAL, -INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY -OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - - */ - -/* - * TODO: optimization / better integration with malloc.c (partly done) - * malloc_{get,set}_state (probably hard to keep compatibility) - * debugging hooks - * better mstats - */ - -#include /* For size_t */ -#include /* for mmap */ -#include -#include -#include -#include /* for memset */ - -#include - -#include "malloc-2.8.3.h" - -/* ----------------------------------------------------------------------- */ - -/* The following section is replicated from malloc.c */ - -#include "malloc-private.h" - -/* end of definitions replicated from malloc.c */ - -#define munmap_chunk(mst, p) do { \ - size_t prevsize = (p)->prev_foot & ~IS_MMAPPED_BIT; \ - size_t psize = chunksize(p) + prevsize + MMAP_FOOT_PAD; \ - if (CALL_MUNMAP((char*)(p) - prevsize, psize) == 0) \ - ((struct malloc_state*)(mst))->footprint -= psize; \ -} while (0) - -/* ---------------------------------------------------------------------- */ - -/* Minimum size for a newly created arena. */ -#ifndef ARENA_SIZE_MIN -# define ARENA_SIZE_MIN (128*1024) -#endif -#define HAVE_MEMCPY 1 - -/* If THREAD_STATS is non-zero, some statistics on mutex locking are - computed. */ -#ifndef THREAD_STATS -# define THREAD_STATS 0 -#endif - -#ifndef MALLOC_DEBUG -# define MALLOC_DEBUG 0 -#endif - -#define my_powerof2(x) ((((x)-1)&(x))==0) - -/* Already initialized? */ -int __malloc_initialized = -1; - -#ifndef RETURN_ADDRESS -# define RETURN_ADDRESS(X_) (NULL) -#endif - -#if THREAD_STATS -# define THREAD_STAT(x) x -#else -# define THREAD_STAT(x) do ; while(0) -#endif - -#ifdef _LIBC - -/* Special defines for the GNU C library. */ -#define public_cALLOc __libc_calloc -#define public_fREe __libc_free -#define public_cFREe __libc_cfree -#define public_mALLOc __libc_malloc -#define public_mEMALIGn __libc_memalign -#define public_rEALLOc __libc_realloc -#define public_vALLOc __libc_valloc -#define public_pVALLOc __libc_pvalloc -#define public_pMEMALIGn __posix_memalign -#define public_mALLINFo __libc_mallinfo -#define public_mALLOPt __libc_mallopt -#define public_mTRIm __malloc_trim -#define public_mSTATs __malloc_stats -#define public_mUSABLe __malloc_usable_size -#define public_iCALLOc __libc_independent_calloc -#define public_iCOMALLOc __libc_independent_comalloc -#define public_gET_STATe __malloc_get_state -#define public_sET_STATe __malloc_set_state -#define malloc_getpagesize __getpagesize() -#define open __open -#define mmap __mmap -#define munmap __munmap -#define mremap __mremap -#define mprotect __mprotect -#define MORECORE (*__morecore) -#define MORECORE_FAILURE 0 - -void * __default_morecore (ptrdiff_t); -void *(*__morecore)(ptrdiff_t) = __default_morecore; - -#else /* !_LIBC */ - -#define public_cALLOc calloc -#define public_fREe free -#define public_cFREe cfree -#define public_mALLOc malloc -#define public_mEMALIGn memalign -#define public_rEALLOc realloc -#define public_vALLOc valloc -#define public_pVALLOc pvalloc -#define public_pMEMALIGn posix_memalign -#define public_mALLINFo mallinfo -#define public_mALLOPt mallopt -#define public_mTRIm malloc_trim -#define public_mSTATs malloc_stats -#define public_mUSABLe malloc_usable_size -#define public_iCALLOc independent_calloc -#define public_iCOMALLOc independent_comalloc -#define public_gET_STATe malloc_get_state -#define public_sET_STATe malloc_set_state - -#endif /* _LIBC */ - -#if !defined _LIBC && (!defined __GNUC__ || __GNUC__<3) -#define __builtin_expect(expr, val) (expr) -#endif - -#if MALLOC_DEBUG -#include -#else -#undef assert -#define assert(x) ((void)0) -#endif - -/* USE_STARTER determines if and when the special "starter" hook - functions are used: not at all (0), during ptmalloc_init (first bit - set), or from the beginning until an explicit call to ptmalloc_init - (second bit set). This is necessary if thread-related - initialization functions (e.g. pthread_key_create) require - malloc() calls (set USE_STARTER=1), or if those functions initially - cannot be used at all (set USE_STARTER=2 and perform an explicit - ptmalloc_init() when the thread library is ready, typically at the - start of main()). */ - -#ifndef USE_STARTER -# ifndef _LIBC -# define USE_STARTER 1 -# else -# if USE___THREAD || (defined USE_TLS && !defined SHARED) - /* These routines are never needed in this configuration. */ -# define USE_STARTER 0 -# else -# define USE_STARTER (USE_TLS ? 4 : 1) -# endif -# endif -#endif - -/*----------------------------------------------------------------------*/ - -/* Arenas */ -static tsd_key_t arena_key; -static mutex_t list_lock; - -/* Arena structure */ -struct malloc_arena { - /* Serialize access. */ - mutex_t mutex; - - /* Statistics for locking. Only used if THREAD_STATS is defined. */ - long stat_lock_direct, stat_lock_loop, stat_lock_wait; - long stat_starter; - - /* Linked list */ - struct malloc_arena *next; - - /* Space for mstate. The size is just the minimum such that - create_mspace_with_base can be successfully called. */ - char buf_[pad_request(sizeof(struct malloc_state)) + TOP_FOOT_SIZE + - CHUNK_ALIGN_MASK + 1]; -}; -#define MSPACE_OFFSET (((offsetof(struct malloc_arena, buf_) \ - + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK)) -#define arena_to_mspace(a) ((void *)chunk2mem((char*)(a) + MSPACE_OFFSET)) - -/* check for chunk from non-main arena */ -#define chunk_non_main_arena(p) ((p)->head & NON_MAIN_ARENA) - -static struct malloc_arena* _int_new_arena(size_t size); - -/* Buffer for the main arena. */ -static struct malloc_arena main_arena; - -/* For now, store arena in footer. This means typically 4bytes more - overhead for each non-main-arena chunk, but is fast and easy to - compute. Note that the pointer stored in the extra footer must be - properly aligned, though. */ -#define FOOTER_OVERHEAD \ - (2*sizeof(struct malloc_arena*) - SIZE_T_SIZE) - -#define arena_for_chunk(ptr) \ - (chunk_non_main_arena(ptr) ? *(struct malloc_arena**) \ - ((char*)(ptr) + chunksize(ptr) - (FOOTER_OVERHEAD - SIZE_T_SIZE)) \ - : &main_arena) - -/* special because of extra overhead */ -#define arena_for_mmap_chunk(ptr) \ - (chunk_non_main_arena(ptr) ? *(struct malloc_arena**) \ - ((char*)(ptr) + chunksize(ptr) - sizeof(struct malloc_arena*)) \ - : &main_arena) - -#define set_non_main_arena(mem, ar_ptr) do { \ - mchunkptr P = mem2chunk(mem); \ - size_t SZ = chunksize(P) - (is_mmapped(P) ? sizeof(struct malloc_arena*) \ - : (FOOTER_OVERHEAD - SIZE_T_SIZE)); \ - assert((unsigned long)((char*)(P) + SZ)%sizeof(struct malloc_arena*) == 0); \ - *(struct malloc_arena**)((char*)(P) + SZ) = (ar_ptr); \ - P->head |= NON_MAIN_ARENA; \ -} while (0) - -/* arena_get() acquires an arena and locks the corresponding mutex. - First, try the one last locked successfully by this thread. (This - is the common case and handled with a macro for speed.) Then, loop - once over the circularly linked list of arenas. If no arena is - readily available, create a new one. In this latter case, `size' - is just a hint as to how much memory will be required immediately - in the new arena. */ - -#define arena_get(ptr, size) do { \ - void *vptr = NULL; \ - ptr = (struct malloc_arena*)tsd_getspecific(arena_key, vptr); \ - if(ptr && !mutex_trylock(&ptr->mutex)) { \ - THREAD_STAT(++(ptr->stat_lock_direct)); \ - } else \ - ptr = arena_get2(ptr, (size)); \ -} while(0) - -static struct malloc_arena* -arena_get2(struct malloc_arena* a_tsd, size_t size) -{ - struct malloc_arena* a; - int err; - - if(!a_tsd) - a = a_tsd = &main_arena; - else { - a = a_tsd->next; - if(!a) { - /* This can only happen while initializing the new arena. */ - (void)mutex_lock(&main_arena.mutex); - THREAD_STAT(++(main_arena.stat_lock_wait)); - return &main_arena; - } - } - - /* Check the global, circularly linked list for available arenas. */ - repeat: - do { - if(!mutex_trylock(&a->mutex)) { - THREAD_STAT(++(a->stat_lock_loop)); - tsd_setspecific(arena_key, (void *)a); - return a; - } - a = a->next; - } while(a != a_tsd); - - /* If not even the list_lock can be obtained, try again. This can - happen during `atfork', or for example on systems where thread - creation makes it temporarily impossible to obtain _any_ - locks. */ - if(mutex_trylock(&list_lock)) { - a = a_tsd; - goto repeat; - } - (void)mutex_unlock(&list_lock); - - /* Nothing immediately available, so generate a new arena. */ - a = _int_new_arena(size); - if(!a) - return 0; - - tsd_setspecific(arena_key, (void *)a); - mutex_init(&a->mutex); - err = mutex_lock(&a->mutex); /* remember result */ - - /* Add the new arena to the global list. */ - (void)mutex_lock(&list_lock); - a->next = main_arena.next; - atomic_write_barrier (); - main_arena.next = a; - (void)mutex_unlock(&list_lock); - - if(err) /* locking failed; keep arena for further attempts later */ - return 0; - - THREAD_STAT(++(a->stat_lock_loop)); - return a; -} - -/* Create a new arena with room for a chunk of size "size". */ - -static struct malloc_arena* -_int_new_arena(size_t size) -{ - struct malloc_arena* a; - size_t mmap_sz = sizeof(*a) + pad_request(size); - void *m; - - if (mmap_sz < ARENA_SIZE_MIN) - mmap_sz = ARENA_SIZE_MIN; - /* conservative estimate for page size */ - mmap_sz = (mmap_sz + 8191) & ~(size_t)8191; - a = CALL_MMAP(mmap_sz); - if ((char*)a == (char*)-1) - return 0; - - m = create_mspace_with_base((char*)a + MSPACE_OFFSET, - mmap_sz - MSPACE_OFFSET, - 0); - - if (!m) { - CALL_MUNMAP(a, mmap_sz); - a = 0; - } else { - /*a->next = NULL;*/ - /*a->system_mem = a->max_system_mem = h->size;*/ - } - - return a; -} - -/*------------------------------------------------------------------------*/ - -/* Hook mechanism for proper initialization and atfork support. */ - -/* Define and initialize the hook variables. These weak definitions must - appear before any use of the variables in a function. */ -#ifndef weak_variable -#ifndef _LIBC -#define weak_variable /**/ -#else -/* In GNU libc we want the hook variables to be weak definitions to - avoid a problem with Emacs. */ -#define weak_variable weak_function -#endif -#endif - -#if !(USE_STARTER & 2) -# define free_hook_ini NULL -/* Forward declarations. */ -static void* malloc_hook_ini (size_t sz, const void *caller); -static void* realloc_hook_ini (void* ptr, size_t sz, const void* caller); -static void* memalign_hook_ini (size_t alignment, size_t sz, - const void* caller); -#else -# define free_hook_ini free_starter -# define malloc_hook_ini malloc_starter -# define realloc_hook_ini NULL -# define memalign_hook_ini memalign_starter -#endif - -void weak_variable (*__malloc_initialize_hook) (void) = NULL; -void weak_variable (*__free_hook) (void * __ptr, const void *) - = free_hook_ini; -void * weak_variable (*__malloc_hook) (size_t __size, const void *) - = malloc_hook_ini; -void * weak_variable (*__realloc_hook) - (void * __ptr, size_t __size, const void *) = realloc_hook_ini; -void * weak_variable (*__memalign_hook) - (size_t __alignment, size_t __size, const void *) = memalign_hook_ini; -/*void weak_variable (*__after_morecore_hook) (void) = NULL;*/ - -/* The initial hooks just call the initialization routine, then do the - normal work. */ - -#if !(USE_STARTER & 2) -static -#endif -void ptmalloc_init(void); - -#if !(USE_STARTER & 2) - -static void* -malloc_hook_ini(size_t sz, const void * caller) -{ - __malloc_hook = NULL; - ptmalloc_init(); - return public_mALLOc(sz); -} - -static void * -realloc_hook_ini(void *ptr, size_t sz, const void * caller) -{ - __malloc_hook = NULL; - __realloc_hook = NULL; - ptmalloc_init(); - return public_rEALLOc(ptr, sz); -} - -static void* -memalign_hook_ini(size_t alignment, size_t sz, const void * caller) -{ - __memalign_hook = NULL; - ptmalloc_init(); - return public_mEMALIGn(alignment, sz); -} - -#endif /* !(USE_STARTER & 2) */ - -/*----------------------------------------------------------------------*/ - -#if !defined NO_THREADS && USE_STARTER - -/* The following hooks are used when the global initialization in - ptmalloc_init() hasn't completed yet. */ - -static void* -malloc_starter(size_t sz, const void *caller) -{ - void* victim; - - /*ptmalloc_init_minimal();*/ - victim = mspace_malloc(arena_to_mspace(&main_arena), sz); - THREAD_STAT(++main_arena.stat_starter); - - return victim; -} - -static void* -memalign_starter(size_t align, size_t sz, const void *caller) -{ - void* victim; - - /*ptmalloc_init_minimal();*/ - victim = mspace_memalign(arena_to_mspace(&main_arena), align, sz); - THREAD_STAT(++main_arena.stat_starter); - - return victim; -} - -static void -free_starter(void* mem, const void *caller) -{ - if (mem) { - mchunkptr p = mem2chunk(mem); - void *msp = arena_to_mspace(&main_arena); - if (is_mmapped(p)) - munmap_chunk(msp, p); - else - mspace_free(msp, mem); - } - THREAD_STAT(++main_arena.stat_starter); -} - -#endif /* !defined NO_THREADS && USE_STARTER */ - -/*----------------------------------------------------------------------*/ - -#ifndef NO_THREADS - -/* atfork support. */ - -static void * (*save_malloc_hook) (size_t __size, const void *); -# if !defined _LIBC || !defined USE_TLS || (defined SHARED && !USE___THREAD) -static void * (*save_memalign_hook) (size_t __align, size_t __size, - const void *); -# endif -static void (*save_free_hook) (void * __ptr, const void *); -static void* save_arena; - -/* Magic value for the thread-specific arena pointer when - malloc_atfork() is in use. */ - -#define ATFORK_ARENA_PTR ((void*)-1) - -/* The following hooks are used while the `atfork' handling mechanism - is active. */ - -static void* -malloc_atfork(size_t sz, const void *caller) -{ - void *vptr = NULL; - - tsd_getspecific(arena_key, vptr); - if(vptr == ATFORK_ARENA_PTR) { - /* We are the only thread that may allocate at all. */ - return mspace_malloc(arena_to_mspace(&main_arena), sz); - } else { - /* Suspend the thread until the `atfork' handlers have completed. - By that time, the hooks will have been reset as well, so that - mALLOc() can be used again. */ - (void)mutex_lock(&list_lock); - (void)mutex_unlock(&list_lock); - return public_mALLOc(sz); - } -} - -static void -free_atfork(void* mem, const void *caller) -{ - void *vptr = NULL; - struct malloc_arena *ar_ptr; - mchunkptr p; /* chunk corresponding to mem */ - - if (mem == 0) /* free(0) has no effect */ - return; - - p = mem2chunk(mem); - - if (is_mmapped(p)) { /* release mmapped memory. */ - ar_ptr = arena_for_mmap_chunk(p); - munmap_chunk(arena_to_mspace(ar_ptr), p); - return; - } - - ar_ptr = arena_for_chunk(p); - tsd_getspecific(arena_key, vptr); - if(vptr != ATFORK_ARENA_PTR) - (void)mutex_lock(&ar_ptr->mutex); - mspace_free(arena_to_mspace(ar_ptr), mem); - if(vptr != ATFORK_ARENA_PTR) - (void)mutex_unlock(&ar_ptr->mutex); -} - -/* The following two functions are registered via thread_atfork() to - make sure that the mutexes remain in a consistent state in the - fork()ed version of a thread. Also adapt the malloc and free hooks - temporarily, because the `atfork' handler mechanism may use - malloc/free internally (e.g. in LinuxThreads). */ - -static void -ptmalloc_lock_all (void) -{ - struct malloc_arena* ar_ptr; - - if(__malloc_initialized < 1) - return; - (void)mutex_lock(&list_lock); - for(ar_ptr = &main_arena;;) { - (void)mutex_lock(&ar_ptr->mutex); - ar_ptr = ar_ptr->next; - if(ar_ptr == &main_arena) - break; - } - save_malloc_hook = __malloc_hook; - save_free_hook = __free_hook; - __malloc_hook = malloc_atfork; - __free_hook = free_atfork; - /* Only the current thread may perform malloc/free calls now. */ - tsd_getspecific(arena_key, save_arena); - tsd_setspecific(arena_key, ATFORK_ARENA_PTR); -} - -static void -ptmalloc_unlock_all (void) -{ - struct malloc_arena *ar_ptr; - - if(__malloc_initialized < 1) - return; - tsd_setspecific(arena_key, save_arena); - __malloc_hook = save_malloc_hook; - __free_hook = save_free_hook; - for(ar_ptr = &main_arena;;) { - (void)mutex_unlock(&ar_ptr->mutex); - ar_ptr = ar_ptr->next; - if(ar_ptr == &main_arena) break; - } - (void)mutex_unlock(&list_lock); -} - -#ifdef __linux__ - -/* In LinuxThreads, unlocking a mutex in the child process after a - fork() is currently unsafe, whereas re-initializing it is safe and - does not leak resources. Therefore, a special atfork handler is - installed for the child. */ - -static void -ptmalloc_unlock_all2(void) -{ - struct malloc_arena *ar_ptr; - - if(__malloc_initialized < 1) - return; -#if defined _LIBC || 1 /*defined MALLOC_HOOKS*/ - tsd_setspecific(arena_key, save_arena); - __malloc_hook = save_malloc_hook; - __free_hook = save_free_hook; -#endif - for(ar_ptr = &main_arena;;) { - (void)mutex_init(&ar_ptr->mutex); - ar_ptr = ar_ptr->next; - if(ar_ptr == &main_arena) break; - } - (void)mutex_init(&list_lock); -} - -#else - -#define ptmalloc_unlock_all2 ptmalloc_unlock_all - -#endif - -#endif /* !defined NO_THREADS */ - -/*---------------------------------------------------------------------*/ - -#if !(USE_STARTER & 2) -static -#endif -void -ptmalloc_init(void) -{ - const char* s; - int secure = 0; - void *mspace; - - if(__malloc_initialized >= 0) return; - __malloc_initialized = 0; - - /*if (mp_.pagesize == 0) - ptmalloc_init_minimal();*/ - -#ifndef NO_THREADS -# if USE_STARTER & 1 - /* With some threads implementations, creating thread-specific data - or initializing a mutex may call malloc() itself. Provide a - simple starter version (realloc() won't work). */ - save_malloc_hook = __malloc_hook; - save_memalign_hook = __memalign_hook; - save_free_hook = __free_hook; - __malloc_hook = malloc_starter; - __memalign_hook = memalign_starter; - __free_hook = free_starter; -# ifdef _LIBC - /* Initialize the pthreads interface. */ - if (__pthread_initialize != NULL) - __pthread_initialize(); -# endif /* !defined _LIBC */ -# endif /* USE_STARTER & 1 */ -#endif /* !defined NO_THREADS */ - mutex_init(&main_arena.mutex); - main_arena.next = &main_arena; - mspace = create_mspace_with_base((char*)&main_arena + MSPACE_OFFSET, - sizeof(main_arena) - MSPACE_OFFSET, - 0); - assert(mspace == arena_to_mspace(&main_arena)); - - mutex_init(&list_lock); - tsd_key_create(&arena_key, NULL); - tsd_setspecific(arena_key, (void *)&main_arena); - thread_atfork(ptmalloc_lock_all, ptmalloc_unlock_all, ptmalloc_unlock_all2); -#ifndef NO_THREADS -# if USE_STARTER & 1 - __malloc_hook = save_malloc_hook; - __memalign_hook = save_memalign_hook; - __free_hook = save_free_hook; -# endif -# if USE_STARTER & 2 - __malloc_hook = 0; - __memalign_hook = 0; - __free_hook = 0; -# endif -#endif -#ifdef _LIBC - secure = __libc_enable_secure; -#else - if (! secure) { - if ((s = getenv("MALLOC_TRIM_THRESHOLD_"))) - public_mALLOPt(M_TRIM_THRESHOLD, atoi(s)); - if ((s = getenv("MALLOC_TOP_PAD_")) || - (s = getenv("MALLOC_GRANULARITY_"))) - public_mALLOPt(M_GRANULARITY, atoi(s)); - if ((s = getenv("MALLOC_MMAP_THRESHOLD_"))) - public_mALLOPt(M_MMAP_THRESHOLD, atoi(s)); - /*if ((s = getenv("MALLOC_MMAP_MAX_"))) this is no longer available - public_mALLOPt(M_MMAP_MAX, atoi(s));*/ - } - s = getenv("MALLOC_CHECK_"); -#endif - if (s) { - /*if(s[0]) mALLOPt(M_CHECK_ACTION, (int)(s[0] - '0')); - __malloc_check_init();*/ - } - if (__malloc_initialize_hook != NULL) - (*__malloc_initialize_hook)(); - __malloc_initialized = 1; -} - -/*------------------------ Public wrappers. --------------------------------*/ - -void* -public_mALLOc(size_t bytes) -{ - struct malloc_arena* ar_ptr; - void *victim; - - void * (*hook) (size_t, const void *) = __malloc_hook; - if (hook != NULL) - return (*hook)(bytes, RETURN_ADDRESS (0)); - - arena_get(ar_ptr, bytes + FOOTER_OVERHEAD); - if (!ar_ptr) - return 0; - if (ar_ptr != &main_arena) - bytes += FOOTER_OVERHEAD; - victim = mspace_malloc(arena_to_mspace(ar_ptr), bytes); - if (victim && ar_ptr != &main_arena) - set_non_main_arena(victim, ar_ptr); - (void)mutex_unlock(&ar_ptr->mutex); - assert(!victim || is_mmapped(mem2chunk(victim)) || - ar_ptr == arena_for_chunk(mem2chunk(victim))); - return victim; -} -#ifdef libc_hidden_def -libc_hidden_def(public_mALLOc) -#endif - -void -public_fREe(void* mem) -{ - struct malloc_arena* ar_ptr; - mchunkptr p; /* chunk corresponding to mem */ - - void (*hook) (void *, const void *) = __free_hook; - if (hook != NULL) { - (*hook)(mem, RETURN_ADDRESS (0)); - return; - } - - if (mem == 0) /* free(0) has no effect */ - return; - - p = mem2chunk(mem); - - if (is_mmapped(p)) { /* release mmapped memory. */ - ar_ptr = arena_for_mmap_chunk(p); - munmap_chunk(arena_to_mspace(ar_ptr), p); - return; - } - - ar_ptr = arena_for_chunk(p); -#if THREAD_STATS - if(!mutex_trylock(&ar_ptr->mutex)) - ++(ar_ptr->stat_lock_direct); - else { - (void)mutex_lock(&ar_ptr->mutex); - ++(ar_ptr->stat_lock_wait); - } -#else - (void)mutex_lock(&ar_ptr->mutex); -#endif - mspace_free(arena_to_mspace(ar_ptr), mem); - (void)mutex_unlock(&ar_ptr->mutex); -} -#ifdef libc_hidden_def -libc_hidden_def (public_fREe) -#endif - -void* -public_rEALLOc(void* oldmem, size_t bytes) -{ - struct malloc_arena* ar_ptr; - - mchunkptr oldp; /* chunk corresponding to oldmem */ - - void* newp; /* chunk to return */ - - void * (*hook) (void *, size_t, const void *) = __realloc_hook; - if (hook != NULL) - return (*hook)(oldmem, bytes, RETURN_ADDRESS (0)); - -#if REALLOC_ZERO_BYTES_FREES - if (bytes == 0 && oldmem != NULL) { public_fREe(oldmem); return 0; } -#endif - - /* realloc of null is supposed to be same as malloc */ - if (oldmem == 0) - return public_mALLOc(bytes); - - oldp = mem2chunk(oldmem); - if (is_mmapped(oldp)) - ar_ptr = arena_for_mmap_chunk(oldp); /* FIXME: use mmap_resize */ - else - ar_ptr = arena_for_chunk(oldp); -#if THREAD_STATS - if(!mutex_trylock(&ar_ptr->mutex)) - ++(ar_ptr->stat_lock_direct); - else { - (void)mutex_lock(&ar_ptr->mutex); - ++(ar_ptr->stat_lock_wait); - } -#else - (void)mutex_lock(&ar_ptr->mutex); -#endif - -#ifndef NO_THREADS - /* As in malloc(), remember this arena for the next allocation. */ - tsd_setspecific(arena_key, (void *)ar_ptr); -#endif - - if (ar_ptr != &main_arena) - bytes += FOOTER_OVERHEAD; - newp = mspace_realloc(arena_to_mspace(ar_ptr), oldmem, bytes); - - if (newp && ar_ptr != &main_arena) - set_non_main_arena(newp, ar_ptr); - (void)mutex_unlock(&ar_ptr->mutex); - - assert(!newp || is_mmapped(mem2chunk(newp)) || - ar_ptr == arena_for_chunk(mem2chunk(newp))); - return newp; -} -#ifdef libc_hidden_def -libc_hidden_def (public_rEALLOc) -#endif - -void* -public_mEMALIGn(size_t alignment, size_t bytes) -{ - struct malloc_arena* ar_ptr; - void *p; - - void * (*hook) (size_t, size_t, const void *) = __memalign_hook; - if (hook != NULL) - return (*hook)(alignment, bytes, RETURN_ADDRESS (0)); - - /* If need less alignment than we give anyway, just relay to malloc */ - if (alignment <= MALLOC_ALIGNMENT) return public_mALLOc(bytes); - - /* Otherwise, ensure that it is at least a minimum chunk size */ - if (alignment < MIN_CHUNK_SIZE) - alignment = MIN_CHUNK_SIZE; - - arena_get(ar_ptr, - bytes + FOOTER_OVERHEAD + alignment + MIN_CHUNK_SIZE); - if(!ar_ptr) - return 0; - - if (ar_ptr != &main_arena) - bytes += FOOTER_OVERHEAD; - p = mspace_memalign(arena_to_mspace(ar_ptr), alignment, bytes); - - if (p && ar_ptr != &main_arena) - set_non_main_arena(p, ar_ptr); - (void)mutex_unlock(&ar_ptr->mutex); - - assert(!p || is_mmapped(mem2chunk(p)) || - ar_ptr == arena_for_chunk(mem2chunk(p))); - return p; -} -#ifdef libc_hidden_def -libc_hidden_def (public_mEMALIGn) -#endif - -void* -public_vALLOc(size_t bytes) -{ - struct malloc_arena* ar_ptr; - void *p; - - if(__malloc_initialized < 0) - ptmalloc_init (); - arena_get(ar_ptr, bytes + FOOTER_OVERHEAD + MIN_CHUNK_SIZE); - if(!ar_ptr) - return 0; - if (ar_ptr != &main_arena) - bytes += FOOTER_OVERHEAD; - p = mspace_memalign(arena_to_mspace(ar_ptr), 4096, bytes); - - if (p && ar_ptr != &main_arena) - set_non_main_arena(p, ar_ptr); - (void)mutex_unlock(&ar_ptr->mutex); - return p; -} - -int -public_pMEMALIGn (void **memptr, size_t alignment, size_t size) -{ - void *mem; - - /* Test whether the SIZE argument is valid. It must be a power of - two multiple of sizeof (void *). */ - if (alignment % sizeof (void *) != 0 - || !my_powerof2 (alignment / sizeof (void *)) != 0 - || alignment == 0) - return EINVAL; - - mem = public_mEMALIGn (alignment, size); - - if (mem != NULL) { - *memptr = mem; - return 0; - } - - return ENOMEM; -} - -void* -public_cALLOc(size_t n_elements, size_t elem_size) -{ - struct malloc_arena* ar_ptr; - size_t bytes, sz; - void* mem; - void * (*hook) (size_t, const void *) = __malloc_hook; - - /* size_t is unsigned so the behavior on overflow is defined. */ - bytes = n_elements * elem_size; -#define HALF_INTERNAL_SIZE_T \ - (((size_t) 1) << (8 * sizeof (size_t) / 2)) - if (__builtin_expect ((n_elements | elem_size) >= HALF_INTERNAL_SIZE_T, 0)) { - if (elem_size != 0 && bytes / elem_size != n_elements) { - /*MALLOC_FAILURE_ACTION;*/ - return 0; - } - } - - if (hook != NULL) { - sz = bytes; - mem = (*hook)(sz, RETURN_ADDRESS (0)); - if(mem == 0) - return 0; -#ifdef HAVE_MEMCPY - return memset(mem, 0, sz); -#else - while(sz > 0) ((char*)mem)[--sz] = 0; /* rather inefficient */ - return mem; -#endif - } - - arena_get(ar_ptr, bytes + FOOTER_OVERHEAD); - if(!ar_ptr) - return 0; - - if (ar_ptr != &main_arena) - bytes += FOOTER_OVERHEAD; - mem = mspace_calloc(arena_to_mspace(ar_ptr), bytes, 1); - - if (mem && ar_ptr != &main_arena) - set_non_main_arena(mem, ar_ptr); - (void)mutex_unlock(&ar_ptr->mutex); - - assert(!mem || is_mmapped(mem2chunk(mem)) || - ar_ptr == arena_for_chunk(mem2chunk(mem))); - - return mem; -} - -void** -public_iCALLOc(size_t n, size_t elem_size, void* chunks[]) -{ - struct malloc_arena* ar_ptr; - void** m; - - arena_get(ar_ptr, n*(elem_size + FOOTER_OVERHEAD)); - if (!ar_ptr) - return 0; - - if (ar_ptr != &main_arena) - elem_size += FOOTER_OVERHEAD; - m = mspace_independent_calloc(arena_to_mspace(ar_ptr), n, elem_size, chunks); - - if (m && ar_ptr != &main_arena) { - while (n > 0) - set_non_main_arena(m[--n], ar_ptr); - } - (void)mutex_unlock(&ar_ptr->mutex); - return m; -} - -void** -public_iCOMALLOc(size_t n, size_t sizes[], void* chunks[]) -{ - struct malloc_arena* ar_ptr; - size_t* m_sizes; - size_t i; - void** m; - - arena_get(ar_ptr, n*sizeof(size_t)); - if (!ar_ptr) - return 0; - - if (ar_ptr != &main_arena) { - /* Temporary m_sizes[] array is ugly but it would be surprising to - change the original sizes[]... */ - m_sizes = mspace_malloc(arena_to_mspace(ar_ptr), n*sizeof(size_t)); - if (!m_sizes) { - (void)mutex_unlock(&ar_ptr->mutex); - return 0; - } - for (i=0; imutex); - return 0; - } - set_non_main_arena(chunks, ar_ptr); - } - } else - m_sizes = sizes; - - m = mspace_independent_comalloc(arena_to_mspace(ar_ptr), n, m_sizes, chunks); - - if (ar_ptr != &main_arena) { - mspace_free(arena_to_mspace(ar_ptr), m_sizes); - if (m) - for (i=0; imutex); - return m; -} - -#if 0 && !defined _LIBC - -void -public_cFREe(void* m) -{ - public_fREe(m); -} - -#endif /* _LIBC */ - -int -public_mTRIm(size_t s) -{ - int result; - - (void)mutex_lock(&main_arena.mutex); - result = mspace_trim(arena_to_mspace(&main_arena), s); - (void)mutex_unlock(&main_arena.mutex); - return result; -} - -size_t -public_mUSABLe(void* mem) -{ - if (mem != 0) { - mchunkptr p = mem2chunk(mem); - if (cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -int -public_mALLOPt(int p, int v) -{ - int result; - result = mspace_mallopt(p, v); - return result; -} - -void -public_mSTATs(void) -{ - int i; - struct malloc_arena* ar_ptr; - /*unsigned long in_use_b, system_b, avail_b;*/ -#if THREAD_STATS - long stat_lock_direct = 0, stat_lock_loop = 0, stat_lock_wait = 0; -#endif - - if(__malloc_initialized < 0) - ptmalloc_init (); - for (i=0, ar_ptr = &main_arena;; ++i) { - struct malloc_state* msp = arena_to_mspace(ar_ptr); - - fprintf(stderr, "Arena %d:\n", i); - mspace_malloc_stats(msp); -#if THREAD_STATS - stat_lock_direct += ar_ptr->stat_lock_direct; - stat_lock_loop += ar_ptr->stat_lock_loop; - stat_lock_wait += ar_ptr->stat_lock_wait; -#endif - if (MALLOC_DEBUG > 1) { - struct malloc_segment* mseg = &msp->seg; - while (mseg) { - fprintf(stderr, " seg %08lx-%08lx\n", (unsigned long)mseg->base, - (unsigned long)(mseg->base + mseg->size)); - mseg = mseg->next; - } - } - ar_ptr = ar_ptr->next; - if (ar_ptr == &main_arena) - break; - } -#if THREAD_STATS - fprintf(stderr, "locked directly = %10ld\n", stat_lock_direct); - fprintf(stderr, "locked in loop = %10ld\n", stat_lock_loop); - fprintf(stderr, "locked waiting = %10ld\n", stat_lock_wait); - fprintf(stderr, "locked total = %10ld\n", - stat_lock_direct + stat_lock_loop + stat_lock_wait); - if (main_arena.stat_starter > 0) - fprintf(stderr, "starter hooks = %10ld\n", main_arena.stat_starter); -#endif -} - -/* - * Local variables: - * c-basic-offset: 2 - * End: - */ diff --git a/src/3rdparty/ptmalloc/sysdeps/generic/atomic.h b/src/3rdparty/ptmalloc/sysdeps/generic/atomic.h deleted file mode 100644 index a3aeed13e8..0000000000 --- a/src/3rdparty/ptmalloc/sysdeps/generic/atomic.h +++ /dev/null @@ -1 +0,0 @@ -/* Empty placeholder */ diff --git a/src/3rdparty/ptmalloc/sysdeps/generic/malloc-machine.h b/src/3rdparty/ptmalloc/sysdeps/generic/malloc-machine.h deleted file mode 100644 index 345137060d..0000000000 --- a/src/3rdparty/ptmalloc/sysdeps/generic/malloc-machine.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Basic platform-independent macro definitions for mutexes, - thread-specific data and parameters for malloc. - Copyright (C) 2003 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _GENERIC_MALLOC_MACHINE_H -#define _GENERIC_MALLOC_MACHINE_H - -#include - -#ifndef mutex_init /* No threads, provide dummy macros */ - -# define NO_THREADS - -/* The mutex functions used to do absolutely nothing, i.e. lock, - trylock and unlock would always just return 0. However, even - without any concurrently active threads, a mutex can be used - legitimately as an `in use' flag. To make the code that is - protected by a mutex async-signal safe, these macros would have to - be based on atomic test-and-set operations, for example. */ -typedef int mutex_t; - -# define mutex_init(m) (*(m) = 0) -# define mutex_lock(m) ((*(m) = 1), 0) -# define mutex_trylock(m) (*(m) ? 1 : ((*(m) = 1), 0)) -# define mutex_unlock(m) (*(m) = 0) - -typedef void *tsd_key_t; -# define tsd_key_create(key, destr) do {} while(0) -# define tsd_setspecific(key, data) ((key) = (data)) -# define tsd_getspecific(key, vptr) (vptr = (key)) - -# define thread_atfork(prepare, parent, child) do {} while(0) - -#endif /* !defined mutex_init */ - -#ifndef atomic_full_barrier -# define atomic_full_barrier() __asm ("" ::: "memory") -#endif - -#ifndef atomic_read_barrier -# define atomic_read_barrier() atomic_full_barrier () -#endif - -#ifndef atomic_write_barrier -# define atomic_write_barrier() atomic_full_barrier () -#endif - -#ifndef DEFAULT_TOP_PAD -# define DEFAULT_TOP_PAD 131072 -#endif - -#endif /* !defined(_GENERIC_MALLOC_MACHINE_H) */ diff --git a/src/3rdparty/ptmalloc/sysdeps/generic/thread-st.h b/src/3rdparty/ptmalloc/sysdeps/generic/thread-st.h deleted file mode 100644 index 0243774b7c..0000000000 --- a/src/3rdparty/ptmalloc/sysdeps/generic/thread-st.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * $Id:$ - * Generic version: no threads. - * by Wolfram Gloger 2004 - */ - -#include - -struct thread_st { - char *sp; /* stack pointer, can be 0 */ - void (*func)(struct thread_st* st); /* must be set by user */ - int id; - int flags; - struct user_data u; -}; - -static void -thread_init(void) -{ - printf("No threads.\n"); -} - -/* Create a thread. */ -static int -thread_create(struct thread_st *st) -{ - st->flags = 0; - st->id = 1; - st->func(st); - return 0; -} - -/* Wait for one of several subthreads to finish. */ -static void -wait_for_thread(struct thread_st st[], int n_thr, - int (*end_thr)(struct thread_st*)) -{ - int i; - for(i=0; i. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that (i) the above copyright notices and this permission -notice appear in all copies of the software and related documentation, -and (ii) the name of Wolfram Gloger may not be used in any advertising -or publicity relating to the software. - -THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -IN NO EVENT SHALL WOLFRAM GLOGER BE LIABLE FOR ANY SPECIAL, -INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY -OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef _PTHREAD_MALLOC_MACHINE_H -#define _PTHREAD_MALLOC_MACHINE_H - -#include - -#undef thread_atfork_static - -/* Use fast inline spinlocks with gcc. */ -#if (defined __i386__ || defined __x86_64__) && defined __GNUC__ && \ - !defined USE_NO_SPINLOCKS - -#include -#include - -typedef struct { - volatile unsigned int lock; - int pad0_; -} mutex_t; - -#define MUTEX_INITIALIZER { 0 } -#define mutex_init(m) ((m)->lock = 0) -static inline int mutex_lock(mutex_t *m) { - int cnt = 0, r; - struct timespec tm; - - for(;;) { - __asm__ __volatile__ - ("xchgl %0, %1" - : "=r"(r), "=m"(m->lock) - : "0"(1), "m"(m->lock) - : "memory"); - if(!r) - return 0; - if(cnt < 50) { - sched_yield(); - cnt++; - } else { - tm.tv_sec = 0; - tm.tv_nsec = 2000001; - nanosleep(&tm, NULL); - cnt = 0; - } - } -} -static inline int mutex_trylock(mutex_t *m) { - int r; - - __asm__ __volatile__ - ("xchgl %0, %1" - : "=r"(r), "=m"(m->lock) - : "0"(1), "m"(m->lock) - : "memory"); - return r; -} -static inline int mutex_unlock(mutex_t *m) { - __asm__ __volatile__ ("movl %1, %0" : "=m" (m->lock) : "g"(0) : "memory"); - return 0; -} - -#else - -/* Normal pthread mutex. */ -typedef pthread_mutex_t mutex_t; - -#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER -#define mutex_init(m) pthread_mutex_init(m, NULL) -#define mutex_lock(m) pthread_mutex_lock(m) -#define mutex_trylock(m) pthread_mutex_trylock(m) -#define mutex_unlock(m) pthread_mutex_unlock(m) - -#endif /* (__i386__ || __x86_64__) && __GNUC__ && !USE_NO_SPINLOCKS */ - -/* thread specific data */ -#if defined(__sgi) || defined(USE_TSD_DATA_HACK) - -/* Hack for thread-specific data, e.g. on Irix 6.x. We can't use - pthread_setspecific because that function calls malloc() itself. - The hack only works when pthread_t can be converted to an integral - type. */ - -typedef void *tsd_key_t[256]; -#define tsd_key_create(key, destr) do { \ - int i; \ - for(i=0; i<256; i++) (*key)[i] = 0; \ -} while(0) -#define tsd_setspecific(key, data) \ - (key[(unsigned)pthread_self() % 256] = (data)) -#define tsd_getspecific(key, vptr) \ - (vptr = key[(unsigned)pthread_self() % 256]) - -#else - -typedef pthread_key_t tsd_key_t; - -#define tsd_key_create(key, destr) pthread_key_create(key, destr) -#define tsd_setspecific(key, data) pthread_setspecific(key, data) -#define tsd_getspecific(key, vptr) (vptr = pthread_getspecific(key)) - -#endif - -/* at fork */ -#define thread_atfork(prepare, parent, child) \ - pthread_atfork(prepare, parent, child) - -#include - -#endif /* !defined(_MALLOC_MACHINE_H) */ diff --git a/src/3rdparty/ptmalloc/sysdeps/pthread/thread-st.h b/src/3rdparty/ptmalloc/sysdeps/pthread/thread-st.h deleted file mode 100644 index f97a0a3552..0000000000 --- a/src/3rdparty/ptmalloc/sysdeps/pthread/thread-st.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * $Id: thread-st.h$ - * pthread version - * by Wolfram Gloger 2004 - */ - -#include -#include - -pthread_cond_t finish_cond = PTHREAD_COND_INITIALIZER; -pthread_mutex_t finish_mutex = PTHREAD_MUTEX_INITIALIZER; - -#ifndef USE_PTHREADS_STACKS -#define USE_PTHREADS_STACKS 0 -#endif - -#ifndef STACKSIZE -#define STACKSIZE 32768 -#endif - -struct thread_st { - char *sp; /* stack pointer, can be 0 */ - void (*func)(struct thread_st* st); /* must be set by user */ - pthread_t id; - int flags; - struct user_data u; -}; - -static void -thread_init(void) -{ - printf("Using posix threads.\n"); - pthread_cond_init(&finish_cond, NULL); - pthread_mutex_init(&finish_mutex, NULL); -} - -static void * -thread_wrapper(void *ptr) -{ - struct thread_st *st = (struct thread_st*)ptr; - - /*printf("begin %p\n", st->sp);*/ - st->func(st); - pthread_mutex_lock(&finish_mutex); - st->flags = 1; - pthread_mutex_unlock(&finish_mutex); - pthread_cond_signal(&finish_cond); - /*printf("end %p\n", st->sp);*/ - return NULL; -} - -/* Create a thread. */ -static int -thread_create(struct thread_st *st) -{ - st->flags = 0; - { - pthread_attr_t* attr_p = 0; -#if USE_PTHREADS_STACKS - pthread_attr_t attr; - - pthread_attr_init (&attr); - if(!st->sp) - st->sp = malloc(STACKSIZE+16); - if(!st->sp) - return -1; - if(pthread_attr_setstacksize(&attr, STACKSIZE)) - fprintf(stderr, "error setting stacksize"); - else - pthread_attr_setstackaddr(&attr, st->sp + STACKSIZE); - /*printf("create %p\n", st->sp);*/ - attr_p = &attr; -#endif - return pthread_create(&st->id, attr_p, thread_wrapper, st); - } - return 0; -} - -/* Wait for one of several subthreads to finish. */ -static void -wait_for_thread(struct thread_st st[], int n_thr, - int (*end_thr)(struct thread_st*)) -{ - int i; - - pthread_mutex_lock(&finish_mutex); - for(;;) { - int term = 0; - for(i=0; i 0) - break; - pthread_cond_wait(&finish_cond, &finish_mutex); - } - pthread_mutex_unlock(&finish_mutex); -} - -/* - * Local variables: - * tab-width: 4 - * End: - */ diff --git a/src/3rdparty/ptmalloc/sysdeps/solaris/malloc-machine.h b/src/3rdparty/ptmalloc/sysdeps/solaris/malloc-machine.h deleted file mode 100644 index 00e33b0801..0000000000 --- a/src/3rdparty/ptmalloc/sysdeps/solaris/malloc-machine.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Basic platform-independent macro definitions for mutexes, - thread-specific data and parameters for malloc. - Solaris threads version. - Copyright (C) 2004 Wolfram Gloger . - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that (i) the above copyright notices and this permission -notice appear in all copies of the software and related documentation, -and (ii) the name of Wolfram Gloger may not be used in any advertising -or publicity relating to the software. - -THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -IN NO EVENT SHALL WOLFRAM GLOGER BE LIABLE FOR ANY SPECIAL, -INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY -OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef _SOLARIS_MALLOC_MACHINE_H -#define _SOLARIS_MALLOC_MACHINE_H - -#include - -typedef thread_t thread_id; - -#define MUTEX_INITIALIZER { 0 } -#define mutex_init(m) mutex_init(m, USYNC_THREAD, NULL) - -/* - * Hack for thread-specific data on Solaris. We can't use thr_setspecific - * because that function calls malloc() itself. - */ -typedef void *tsd_key_t[256]; -#define tsd_key_create(key, destr) do { \ - int i; \ - for(i=0; i<256; i++) (*key)[i] = 0; \ -} while(0) -#define tsd_setspecific(key, data) (key[(unsigned)thr_self() % 256] = (data)) -#define tsd_getspecific(key, vptr) (vptr = key[(unsigned)thr_self() % 256]) - -#define thread_atfork(prepare, parent, child) do {} while(0) - -#include - -#endif /* !defined(_SOLARIS_MALLOC_MACHINE_H) */ diff --git a/src/3rdparty/ptmalloc/sysdeps/solaris/thread-st.h b/src/3rdparty/ptmalloc/sysdeps/solaris/thread-st.h deleted file mode 100644 index dbb4b097e8..0000000000 --- a/src/3rdparty/ptmalloc/sysdeps/solaris/thread-st.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * $Id:$ - * Solaris version - * by Wolfram Gloger 2004 - */ - -#include -#include - -#ifndef STACKSIZE -#define STACKSIZE 32768 -#endif - -struct thread_st { - char *sp; /* stack pointer, can be 0 */ - void (*func)(struct thread_st* st); /* must be set by user */ - thread_id id; - int flags; - struct user_data u; -}; - -static void -thread_init(void) -{ - printf("Using Solaris threads.\n"); -} - -static void * -thread_wrapper(void *ptr) -{ - struct thread_st *st = (struct thread_st*)ptr; - - /*printf("begin %p\n", st->sp);*/ - st->func(st); - /*printf("end %p\n", st->sp);*/ - return NULL; -} - -/* Create a thread. */ -static int -thread_create(struct thread_st *st) -{ - st->flags = 0; - if(!st->sp) - st->sp = malloc(STACKSIZE); - if(!st->sp) return -1; - thr_create(st->sp, STACKSIZE, thread_wrapper, st, THR_NEW_LWP, &st->id); - return 0; -} - -/* Wait for one of several subthreads to finish. */ -static void -wait_for_thread(struct thread_st st[], int n_thr, - int (*end_thr)(struct thread_st*)) -{ - int i; - thread_t id; - - thr_join(0, &id, NULL); - for(i=0; i. - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that (i) the above copyright notices and this permission -notice appear in all copies of the software and related documentation, -and (ii) the name of Wolfram Gloger may not be used in any advertising -or publicity relating to the software. - -THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, -EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY -WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - -IN NO EVENT SHALL WOLFRAM GLOGER BE LIABLE FOR ANY SPECIAL, -INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY -OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef _SPROC_MALLOC_MACHINE_H -#define _SPROC_MALLOC_MACHINE_H - -#include -#include -#include -#include - -typedef abilock_t mutex_t; - -#define MUTEX_INITIALIZER { 0 } -#define mutex_init(m) init_lock(m) -#define mutex_lock(m) (spin_lock(m), 0) -#define mutex_trylock(m) acquire_lock(m) -#define mutex_unlock(m) release_lock(m) - -typedef int tsd_key_t; -int tsd_key_next; -#define tsd_key_create(key, destr) ((*key) = tsd_key_next++) -#define tsd_setspecific(key, data) (((void **)(&PRDA->usr_prda))[key] = data) -#define tsd_getspecific(key, vptr) (vptr = ((void **)(&PRDA->usr_prda))[key]) - -#define thread_atfork(prepare, parent, child) do {} while(0) - -#include - -#endif /* !defined(_SPROC_MALLOC_MACHINE_H) */ diff --git a/src/3rdparty/ptmalloc/sysdeps/sproc/thread-st.h b/src/3rdparty/ptmalloc/sysdeps/sproc/thread-st.h deleted file mode 100644 index 3559a48454..0000000000 --- a/src/3rdparty/ptmalloc/sysdeps/sproc/thread-st.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * $Id:$ - * sproc version - * by Wolfram Gloger 2001, 2004, 2006 - */ - -#include -#include -#include -#include - -#ifndef STACKSIZE -#define STACKSIZE 32768 -#endif - -struct thread_st { - char *sp; /* stack pointer, can be 0 */ - void (*func)(struct thread_st* st); /* must be set by user */ - int id; - int flags; - struct user_data u; -}; - -static void -thread_init(void) -{ - printf("Using sproc() threads.\n"); -} - -static void -thread_wrapper(void *ptr, size_t stack_len) -{ - struct thread_st *st = (struct thread_st*)ptr; - - /*printf("begin %p\n", st->sp);*/ - st->func(st); - /*printf("end %p\n", st->sp);*/ -} - -/* Create a thread. */ -static int -thread_create(struct thread_st *st) -{ - st->flags = 0; - if(!st->sp) - st->sp = malloc(STACKSIZE); - if(!st->sp) return -1; - st->id = sprocsp(thread_wrapper, PR_SALL, st, st->sp+STACKSIZE, STACKSIZE); - if(st->id < 0) { - return -1; - } - return 0; -} - -/* Wait for one of several subthreads to finish. */ -static void -wait_for_thread(struct thread_st st[], int n_thr, - int (*end_thr)(struct thread_st*)) -{ - int i; - int id; - - int status = 0; - id = wait(&status); - if(status != 0) { - if(WIFSIGNALED(status)) - printf("thread %id terminated by signal %d\n", - id, WTERMSIG(status)); - else - printf("thread %id exited with status %d\n", - id, WEXITSTATUS(status)); - } - for(i=0; i -#include -#include - -/* JEJ - NOTE WE DO NOT INCLUDE Xwacom.h HERE. THIS ELIMINATES A CONFLICT - * WHEN THIS FILE IS INSTALLED SINCE Xwacom.h WILL IN MANY CASES NOT - * GO WITH IT. SOMEDAY IT MAY BE PART OF XFREE86. */ - -typedef struct _WACOMCONFIG WACOMCONFIG; -typedef struct _WACOMDEVICE WACOMDEVICE; -typedef void (*WACOMERRORFUNC)(int err, const char* pszText); -typedef struct _WACOMDEVICEINFO WACOMDEVICEINFO; - -typedef enum -{ - WACOMDEVICETYPE_UNKNOWN, - WACOMDEVICETYPE_CURSOR, - WACOMDEVICETYPE_STYLUS, - WACOMDEVICETYPE_ERASER, - WACOMDEVICETYPE_PAD, - WACOMDEVICETYPE_TOUCH, - WACOMDEVICETYPE_MAX -} WACOMDEVICETYPE; - -struct _WACOMDEVICEINFO -{ - const char* pszName; - WACOMDEVICETYPE type; -}; - -struct _WACOMCONFIG -{ - Display* pDisp; - WACOMERRORFUNC pfnError; - XDeviceInfo * pDevs; - int nDevCnt; -}; - -struct _WACOMDEVICE -{ - WACOMCONFIG* pCfg; - XDevice* pDev; -}; - - -/***************************************************************************** -** Functions -*****************************************************************************/ - -WACOMCONFIG * WacomConfigInit(Display* pDisplay, WACOMERRORFUNC pfnErrorHandler); -/* Initializes configuration library. - * pDisplay - display to configure - * pfnErrorHandler - handler to which errors are reported; may be NULL - * Returns WACOMCONFIG handle on success, NULL on error. - * errno contains error code. */ - -void WacomConfigTerm(WACOMCONFIG * hConfig); -/* Terminates configuration library, releasing display. */ - -int WacomConfigListDevices(WACOMCONFIG * hConfig, WACOMDEVICEINFO** ppInfo, - unsigned int* puCount); -/* Returns a list of wacom devices. - * ppInfo - pointer to WACOMDEVICEINFO* to receive device data - * puSize - pointer to receive device count - * Returns 0 on success, -1 on failure. errno contains error code. - * Comments: You must free this structure using WacomConfigFree. */ - -WACOMDEVICE * WacomConfigOpenDevice(WACOMCONFIG * hConfig, - const char* pszDeviceName); -/* Open a device by name. - * pszDeviceName - name of XInput device corresponding to wacom device - * Returns handle to device on success, NULL on error. - * errno contains error code. - * Comments: Close using WacomConfigCloseDevice */ - -int WacomConfigCloseDevice(WACOMDEVICE * hDevice); -/* Closes a device. - * Returns 0 on success, -1 on error. errno contains error code. */ - -int WacomConfigSetRawParam(WACOMDEVICE * hDevice, int nParam, int nValue, unsigned * keys); -/* Sets the raw device parameter to specified value. - * nParam - valid paramters can be found Xwacom.h which is not - * automatically included. - * nValue - 32 bit integer value - * keys - an array of keys and modifiers - * Returns 0 on success, -1 on error. errno contains error code. - * EINVAL - invalid parameter or value - * EIO - unknown X failure, use XSetErrorHandler to capture complete - * error code and message - * Comments: Data is sent to wacom_drv module without any error checking. - * Generally, you should use the more specific handler functions in this - * library, but for some parameters, particularly experimental ones, you - * will probably have to set them directly. */ - -int WacomConfigGetRawParam(WACOMDEVICE *hDevice, int nParam, int *nValue, int valu, unsigned * keys); -/* Gets the raw device parameter. - * nParam - valid paramters can be found Xwacom.h which is not - * automatically included. - * nValue - the device parameter is returned in the integer - * pointed by this parameter. - * valu - calling valuator value: 1: Get 3: GetDefault - * keys - an array of keys and modifiers - * Returns 0 on success, -1 on error. errno contains error code. - * EINVAL - invalid parameter or value - * EIO - unknown X failure, use XSetErrorHandler to capture complete - * error code and message - */ - -void WacomConfigFree(void* pvData); -/* Frees memory allocated by library. */ - -#endif /* __LINUXWACOM_WACOMCFG_H */ - diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 867d303676..b7f785b716 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -36,25 +36,7 @@ # ###################################### -include(MacroAddFileDependencies) - -MACRO (QT5_EXTRACT_OPTIONS _qt5_files _qt5_options) - SET(${_qt5_files}) - SET(${_qt5_options}) - SET(_QT5_DOING_OPTIONS FALSE) - FOREACH(_currentArg ${ARGN}) - IF ("${_currentArg}" STREQUAL "OPTIONS") - SET(_QT5_DOING_OPTIONS TRUE) - ELSE ("${_currentArg}" STREQUAL "OPTIONS") - IF(_QT5_DOING_OPTIONS) - LIST(APPEND ${_qt5_options} "${_currentArg}") - ELSE(_QT5_DOING_OPTIONS) - LIST(APPEND ${_qt5_files} "${_currentArg}") - ENDIF(_QT5_DOING_OPTIONS) - ENDIF ("${_currentArg}" STREQUAL "OPTIONS") - ENDFOREACH(_currentArg) -ENDMACRO (QT5_EXTRACT_OPTIONS) - +include(CMakeParseArguments) # macro used to create the names of output files preserving relative dirs MACRO (QT5_MAKE_OUTPUT_FILE infile prefix ext outfile ) @@ -135,7 +117,7 @@ MACRO (QT5_CREATE_MOC_COMMAND infile outfile moc_flags moc_options) ADD_CUSTOM_COMMAND(OUTPUT ${outfile} COMMAND ${QT_MOC_EXECUTABLE} ARGS ${moc_flags} ${moc_options} -o ${outfile} ${infile} - DEPENDS ${infile}) + DEPENDS ${infile} VERBATIM) ENDIF (WIN32) ENDMACRO (QT5_CREATE_MOC_COMMAND) @@ -158,8 +140,15 @@ ENDMACRO (QT5_GENERATE_MOC) MACRO (QT5_WRAP_CPP outfiles ) # get include dirs QT5_GET_MOC_FLAGS(moc_flags) - QT5_EXTRACT_OPTIONS(moc_files moc_options ${ARGN}) + set(options) + set(oneValueArgs) + set(multiValueArgs OPTIONS) + + cmake_parse_arguments(_WRAP_CPP "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(moc_files ${_WRAP_CPP_UNPARSED_ARGUMENTS}) + set(moc_options ${_WRAP_CPP_OPTIONS}) FOREACH (it ${moc_files}) GET_FILENAME_COMPONENT(it ${it} ABSOLUTE) QT5_MAKE_OUTPUT_FILE(${it} moc_ cxx outfile) @@ -173,7 +162,15 @@ ENDMACRO (QT5_WRAP_CPP) # QT5_ADD_RESOURCES(outfiles inputfile ... ) MACRO (QT5_ADD_RESOURCES outfiles ) - QT5_EXTRACT_OPTIONS(rcc_files rcc_options ${ARGN}) + + set(options) + set(oneValueArgs) + set(multiValueArgs OPTIONS) + + cmake_parse_arguments(_RCC "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(rcc_files ${_RCC_UNPARSED_ARGUMENTS}) + set(rcc_options ${_RCC_OPTIONS}) FOREACH (it ${rcc_files}) GET_FILENAME_COMPONENT(outfilename ${it} NAME_WE) @@ -201,7 +198,7 @@ MACRO (QT5_ADD_RESOURCES outfiles ) COMMAND ${QT_RCC_EXECUTABLE} ARGS ${rcc_options} -name ${outfilename} -o ${outfile} ${infile} MAIN_DEPENDENCY ${infile} - DEPENDS ${_RC_DEPENDS} "${out_depends}") + DEPENDS ${_RC_DEPENDS} "${out_depends}" VERBATIM) SET(${outfiles} ${${outfiles}} ${outfile}) ENDFOREACH (it) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 91bfbfd526..b6e2384ea0 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -970,6 +970,10 @@ public: Key_LaunchG = 0x0100010e, Key_LaunchH = 0x0100010f, + Key_TouchpadToggle = 0x01000110, + Key_TouchpadOn = 0x01000111, + Key_TouchpadOff = 0x01000112, + Key_MediaLast = 0x0100ffff, // Keypad navigation keys diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 958587c9a2..63ac4a95be 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1649,6 +1649,9 @@ \value Key_PowerDown \value Key_Suspend \value Key_ContrastAdjust + \value Key_TouchpadToggle + \value Key_TouchpadOn + \value Key_TouchpadOff \value Key_MediaLast \value Key_unknown diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp index c3a41fdd4c..78ec1774eb 100644 --- a/src/corelib/io/qtemporarydir.cpp +++ b/src/corelib/io/qtemporarydir.cpp @@ -45,7 +45,6 @@ #include "qdiriterator.h" #include "qplatformdefs.h" -#include "private/qdir_p.h" #include #if defined(QT_BUILD_CORE_LIB) @@ -67,7 +66,6 @@ public: QTemporaryDirPrivate(); ~QTemporaryDirPrivate(); - QString defaultTemplateName() const; void create(const QString &templateName); QString path; @@ -85,7 +83,7 @@ QTemporaryDirPrivate::~QTemporaryDirPrivate() { } -QString QTemporaryDirPrivate::defaultTemplateName() const +static QString defaultTemplateName() { QString baseName; #if defined(QT_BUILD_CORE_LIB) @@ -168,14 +166,14 @@ void QTemporaryDirPrivate::create(const QString &templateName) QTemporaryDir::QTemporaryDir() : d_ptr(new QTemporaryDirPrivate) { - d_ptr->create(d_ptr->defaultTemplateName()); + d_ptr->create(defaultTemplateName()); } QTemporaryDir::QTemporaryDir(const QString &templateName) : d_ptr(new QTemporaryDirPrivate) { if (templateName.isEmpty()) - d_ptr->create(d_ptr->defaultTemplateName()); + d_ptr->create(defaultTemplateName()); else d_ptr->create(templateName); } @@ -189,9 +187,8 @@ QTemporaryDir::QTemporaryDir(const QString &templateName) */ QTemporaryDir::~QTemporaryDir() { - if (d_ptr->success && d_ptr->autoRemove) + if (d_ptr->autoRemove) remove(); - delete d_ptr; } /*! diff --git a/src/corelib/io/qtemporarydir.h b/src/corelib/io/qtemporarydir.h index 96dc18d952..da0d1214c4 100644 --- a/src/corelib/io/qtemporarydir.h +++ b/src/corelib/io/qtemporarydir.h @@ -43,6 +43,7 @@ #define QTEMPORARYDIR_H #include +#include QT_BEGIN_HEADER @@ -70,7 +71,7 @@ public: QString path() const; private: - QTemporaryDirPrivate* const d_ptr; + QScopedPointer d_ptr; Q_DISABLE_COPY(QTemporaryDir) }; diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index ebcaaa71bd..677be45f65 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -439,8 +439,6 @@ protected: QTemporaryFilePrivate(); ~QTemporaryFilePrivate(); - QString defaultTemplateName() const; - bool autoRemove; QString templateName; }; @@ -453,7 +451,7 @@ QTemporaryFilePrivate::~QTemporaryFilePrivate() { } -QString QTemporaryFilePrivate::defaultTemplateName() const +static QString defaultTemplateName() { QString baseName; #if defined(QT_BUILD_CORE_LIB) @@ -518,7 +516,7 @@ QTemporaryFile::QTemporaryFile() : QFile(*new QTemporaryFilePrivate) { Q_D(QTemporaryFile); - d->templateName = d->defaultTemplateName(); + d->templateName = defaultTemplateName(); } QTemporaryFile::QTemporaryFile(const QString &templateName) @@ -541,7 +539,7 @@ QTemporaryFile::QTemporaryFile() : QFile(*new QTemporaryFilePrivate, 0) { Q_D(QTemporaryFile); - d->templateName = d->defaultTemplateName(); + d->templateName = defaultTemplateName(); } /*! @@ -577,7 +575,7 @@ QTemporaryFile::QTemporaryFile(QObject *parent) : QFile(*new QTemporaryFilePrivate, parent) { Q_D(QTemporaryFile); - d->templateName = d->defaultTemplateName(); + d->templateName = defaultTemplateName(); } /*! diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index cbbb20a8c9..99455371ae 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -2522,8 +2522,6 @@ bool QAbstractItemModelPrivate::allowMove(const QModelIndex &srcParent, int star required to do yourself. Using beginMoveRows and endMoveRows is an alternative to emitting layoutAboutToBeChanged and layoutChanged directly along with changePersistentIndexes. - layoutAboutToBeChanged is emitted by this method for compatibility - reasons. The \a sourceParent index corresponds to the parent from which the rows are moved; \a sourceFirst and \a sourceLast are the first and last @@ -2623,7 +2621,6 @@ bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sour d->changes.push(destinationChange); emit rowsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild); - emit layoutAboutToBeChanged(); d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Vertical); return true; } @@ -2635,8 +2632,6 @@ bool QAbstractItemModel::beginMoveRows(const QModelIndex &sourceParent, int sour function \e after moving data within the model's underlying data store. - layoutChanged is emitted by this method for compatibility reasons. - \sa beginMoveRows() \since 4.6 @@ -2661,7 +2656,6 @@ void QAbstractItemModel::endMoveRows() d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Vertical); emit rowsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first); - emit layoutChanged(); } /*! @@ -2795,8 +2789,6 @@ void QAbstractItemModel::endRemoveColumns() required to do yourself. Using beginMoveRows and endMoveRows is an alternative to emitting layoutAboutToBeChanged and layoutChanged directly along with changePersistentIndexes. - layoutAboutToBeChanged is emitted by this method for compatibility - reasons. The \a sourceParent index corresponds to the parent from which the columns are moved; \a sourceFirst and \a sourceLast are the first and last @@ -2848,7 +2840,6 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s d->itemsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild, Qt::Horizontal); emit columnsAboutToBeMoved(sourceParent, sourceFirst, sourceLast, destinationParent, destinationChild); - emit layoutAboutToBeChanged(); return true; } @@ -2859,8 +2850,6 @@ bool QAbstractItemModel::beginMoveColumns(const QModelIndex &sourceParent, int s function \e after moving data within the model's underlying data store. - layoutChanged is emitted by this method for compatibility reasons. - \sa beginMoveColumns() \since 4.6 @@ -2885,7 +2874,6 @@ void QAbstractItemModel::endMoveColumns() d->itemsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first, Qt::Horizontal); emit columnsMoved(adjustedSource, removeChange.first, removeChange.last, adjustedDestination, insertChange.first); - emit layoutChanged(); } /*! diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index 3c7dacf527..660294b956 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -92,7 +92,7 @@ namespace QtPrivate { template struct ApplyReturnValue { void *data; - ApplyReturnValue(void *data) : data(data) {} + ApplyReturnValue(void *data_) : data(data_) {} }; template void operator,(const T &value, const ApplyReturnValue &container) { diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index bd7c76c37a..f605a82dfe 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -56,11 +56,6 @@ const QMapData QMapData::shared_null = { Q_REFCOUNT_INITIALIZER(-1), 0, 0, 0, false, true, false, 0 }; -QMapData *QMapData::createData() -{ - return createData(0); -} - QMapData *QMapData::createData(int alignment) { QMapData *d = new QMapData; @@ -95,11 +90,6 @@ void QMapData::continueFreeData(int offset) delete this; } -QMapData::Node *QMapData::node_create(Node *update[], int offset) -{ - return node_create(update, offset, 0); -} - /*! Creates a new node inside the data structure. diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 8beae03a6e..362b723b0a 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -77,10 +77,8 @@ struct Q_CORE_EXPORT QMapData uint strictAlignment : 1; uint reserved : 29; - static QMapData *createData(); // ### Qt5 remove me static QMapData *createData(int alignment); void continueFreeData(int offset); - Node *node_create(Node *update[], int offset); // ### Qt5 remove me Node *node_create(Node *update[], int offset, int alignment); void node_delete(Node *update[], int offset, Node *node); #ifdef QT_QMAP_DEBUG diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h index 18b8cb52c3..3e19bef273 100644 --- a/src/corelib/xml/qxmlstream.h +++ b/src/corelib/xml/qxmlstream.h @@ -56,64 +56,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) -// QXmlStream* was originally in the QtXml module -// since we've moved it to QtCore in Qt 4.4.0, we need to -// keep binary compatibility -// -// The list of supported platforms is in: -// http://qt.nokia.com/doc/supported_platforms.html -// -// These platforms do not support symbol moving nor duplication -// (because duplicate symbols cause warnings when linking): -// Apple MacOS X (Mach-O executable format) -// special case: 64-bit on Mac wasn't supported before 4.5.0 -// IBM AIX (XCOFF executable format) -// -// These platforms do not support symbol moving but allow it to be duplicated: -// Microsoft Windows (COFF PE executable format) -// special case: Windows CE wasn't supported before 4.4.0 -// -// These platforms support symbol moving: -// HP HP-UX (PA-RISC2.0 shared executables) -// HP HP-UXi (ELF executable format) -// FreeBSD (ELF executable format) -// Linux (ELF executable format) -// SGI IRIX (ELF executable format) -// Sun Solaris (ELF executable format) -// -// Other platforms are supported through community contributions only. -// We are taking the optimist scenario here to avoid creating more -// symbols to be supported. - -#if defined(Q_OS_MAC32) || defined(Q_OS_AIX) -# if !defined QT_BUILD_XML_LIB -# define Q_XMLSTREAM_RENAME_SYMBOLS -# endif -#endif - -#if defined QT_BUILD_XML_LIB -# define Q_XMLSTREAM_EXPORT Q_XML_EXPORT -#else -# define Q_XMLSTREAM_EXPORT Q_CORE_EXPORT -#endif - -#if defined Q_XMLSTREAM_RENAME_SYMBOLS -// don't worry, we'll undef and change to typedef at the bottom of the file -# define QXmlStreamAttribute QCoreXmlStreamAttribute -# define QXmlStreamAttributes QCoreXmlStreamAttributes -# define QXmlStreamEntityDeclaration QCoreXmlStreamEntityDeclaration -# define QXmlStreamEntityDeclarations QCoreXmlStreamEntityDeclarations -# define QXmlStreamEntityResolver QCoreXmlStreamEntityResolver -# define QXmlStreamNamespaceDeclaration QCoreXmlStreamNamespaceDeclaration -# define QXmlStreamNamespaceDeclarations QCoreXmlStreamNamespaceDeclarations -# define QXmlStreamNotationDeclaration QCoreXmlStreamNotationDeclaration -# define QXmlStreamNotationDeclarations QCoreXmlStreamNotationDeclarations -# define QXmlStreamReader QCoreXmlStreamReader -# define QXmlStreamStringRef QCoreXmlStreamStringRef -# define QXmlStreamWriter QCoreXmlStreamWriter -#endif - -class Q_XMLSTREAM_EXPORT QXmlStreamStringRef { +class Q_CORE_EXPORT QXmlStreamStringRef { QString m_string; int m_position, m_size; public: @@ -132,7 +75,7 @@ public: class QXmlStreamReaderPrivate; class QXmlStreamAttributes; -class Q_XMLSTREAM_EXPORT QXmlStreamAttribute { +class Q_CORE_EXPORT QXmlStreamAttribute { QXmlStreamStringRef m_name, m_namespaceUri, m_qualifiedName, m_value; void *reserved; uint m_isDefault : 1; @@ -166,7 +109,7 @@ public: Q_DECLARE_TYPEINFO(QXmlStreamAttribute, Q_MOVABLE_TYPE); -class Q_XMLSTREAM_EXPORT QXmlStreamAttributes : public QVector +class Q_CORE_EXPORT QXmlStreamAttributes : public QVector { public: inline QXmlStreamAttributes() {} @@ -201,7 +144,7 @@ public: #endif }; -class Q_XMLSTREAM_EXPORT QXmlStreamNamespaceDeclaration { +class Q_CORE_EXPORT QXmlStreamNamespaceDeclaration { QXmlStreamStringRef m_prefix, m_namespaceUri; void *reserved; @@ -224,7 +167,7 @@ public: Q_DECLARE_TYPEINFO(QXmlStreamNamespaceDeclaration, Q_MOVABLE_TYPE); typedef QVector QXmlStreamNamespaceDeclarations; -class Q_XMLSTREAM_EXPORT QXmlStreamNotationDeclaration { +class Q_CORE_EXPORT QXmlStreamNotationDeclaration { QXmlStreamStringRef m_name, m_systemId, m_publicId; void *reserved; @@ -248,7 +191,7 @@ public: Q_DECLARE_TYPEINFO(QXmlStreamNotationDeclaration, Q_MOVABLE_TYPE); typedef QVector QXmlStreamNotationDeclarations; -class Q_XMLSTREAM_EXPORT QXmlStreamEntityDeclaration { +class Q_CORE_EXPORT QXmlStreamEntityDeclaration { QXmlStreamStringRef m_name, m_notationName, m_systemId, m_publicId, m_value; void *reserved; @@ -278,7 +221,7 @@ Q_DECLARE_TYPEINFO(QXmlStreamEntityDeclaration, Q_MOVABLE_TYPE); typedef QVector QXmlStreamEntityDeclarations; -class Q_XMLSTREAM_EXPORT QXmlStreamEntityResolver +class Q_CORE_EXPORT QXmlStreamEntityResolver { public: virtual ~QXmlStreamEntityResolver(); @@ -287,7 +230,7 @@ public: }; #ifndef QT_NO_XMLSTREAMREADER -class Q_XMLSTREAM_EXPORT QXmlStreamReader { +class Q_CORE_EXPORT QXmlStreamReader { QDOC_PROPERTY(bool namespaceProcessing READ namespaceProcessing WRITE setNamespaceProcessing) public: enum TokenType { @@ -413,7 +356,7 @@ private: class QXmlStreamWriterPrivate; -class Q_XMLSTREAM_EXPORT QXmlStreamWriter +class Q_CORE_EXPORT QXmlStreamWriter { QDOC_PROPERTY(bool autoFormatting READ autoFormatting WRITE setAutoFormatting) QDOC_PROPERTY(int autoFormattingIndent READ autoFormattingIndent WRITE setAutoFormattingIndent) diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp index 29b9a20b93..c65e7df327 100644 --- a/src/gui/accessible/qaccessible.cpp +++ b/src/gui/accessible/qaccessible.cpp @@ -859,7 +859,7 @@ const QAccessibleInterface *other, int otherChild) const */ QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterface *) const { - return Unrelated; + return QAccessible::Unrelated; } /*! @@ -871,7 +871,7 @@ QAccessible::Relation QAccessibleInterface::relationTo(const QAccessibleInterfac */ QVector > QAccessibleInterface::relations() const { - return QVector >(); + return QVector >(); } /*! @@ -1191,7 +1191,7 @@ QWindow *QAccessibleInterface::window() const Returns an invalid QVariant if the object doesn't support the action. */ -QVariant QAccessibleInterface::invokeMethod(Method method, const QVariantList ¶ms) +QVariant QAccessibleInterface::invokeMethod(QAccessible::Method method, const QVariantList ¶ms) { Q_UNUSED(method) Q_UNUSED(params) diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index f2fd1a794d..6ee1885a3d 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -62,9 +62,16 @@ QT_MODULE(Gui) class QAccessibleInterface; class QWindow; +// We need to inherit QObject to expose the enums to QML. class Q_GUI_EXPORT QAccessible +#ifndef qdoc + :public QObject +#endif { + Q_OBJECT + Q_ENUMS(Role Event State) public: + enum Event { SoundPlayed = 0x0001, Alert = 0x0002, @@ -141,6 +148,7 @@ public: AcceleratorChanged = 0x80C0 }; + enum StateFlag { Normal = 0x00000000, Unavailable = 0x00000001, @@ -152,11 +160,11 @@ public: ReadOnly = 0x00000040, HotTracked = 0x00000080, DefaultButton = 0x00000100, - // #### Qt5 Expandable Expanded = 0x00000200, Collapsed = 0x00000400, Busy = 0x00000800, // Floating = 0x00001000, + Expandable = 0x00001000, Marqueed = 0x00002000, Animated = 0x00004000, Invisible = 0x00008000, @@ -180,6 +188,7 @@ public: }; Q_DECLARE_FLAGS(State, StateFlag) + enum Role { NoRole = 0x00000000, TitleBar = 0x00000001, @@ -224,7 +233,10 @@ public: Graphic = 0x00000028, StaticText = 0x00000029, EditableText = 0x0000002A, // Editable, selectable, etc. - PushButton = 0x0000002B, + Button = 0x0000002B, +#ifndef qdoc + PushButton = Button, // deprecated +#endif CheckBox = 0x0000002C, RadioButton = 0x0000002D, ComboBox = 0x0000002E, @@ -255,6 +267,7 @@ public: Value, Help, Accelerator, + DebugDescription, UserText = 0x0000ffff }; @@ -320,6 +333,12 @@ public: private: static UpdateHandler updateHandler; static RootObjectHandler rootObjectHandler; + + /*! @internal + This class is purely a collection of enums and static functions, + it is not supposed to be instantiated. + */ + QAccessible() {} }; Q_DECLARE_OPERATORS_FOR_FLAGS(QAccessible::State) @@ -337,7 +356,7 @@ class QAccessibleImageInterface; class QAccessibleTableInterface; class QAccessibleTableCellInterface; -class Q_GUI_EXPORT QAccessibleInterface : public QAccessible +class Q_GUI_EXPORT QAccessibleInterface { public: virtual ~QAccessibleInterface() {} @@ -347,8 +366,8 @@ public: virtual QWindow *window() const; // relations - virtual Relation relationTo(const QAccessibleInterface *other) const; - virtual QVector > relations() const; + virtual QAccessible::Relation relationTo(const QAccessibleInterface *other) const; + virtual QVector > relations() const; virtual int childAt(int x, int y) const = 0; @@ -357,22 +376,23 @@ public: virtual QAccessibleInterface *child(int index) const = 0; virtual int childCount() const = 0; virtual int indexOfChild(const QAccessibleInterface *) const = 0; - virtual int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const = 0; + virtual int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const = 0; // properties and state - virtual QString text(Text t) const = 0; - virtual void setText(Text t, const QString &text) = 0; + virtual QString text(QAccessible::Text t) const = 0; + virtual void setText(QAccessible::Text t, const QString &text) = 0; virtual QRect rect() const = 0; - virtual Role role() const = 0; - virtual State state() const = 0; + virtual QAccessible::Role role() const = 0; + virtual QAccessible::State state() const = 0; + // FIXME virtual QSet states() const = 0; virtual QColor foregroundColor() const; virtual QColor backgroundColor() const; - virtual QVariant invokeMethod(Method method, const QVariantList ¶ms = QVariantList()); + virtual QVariant invokeMethod(QAccessible::Method method, const QVariantList ¶ms = QVariantList()); - inline QSet supportedMethods() - { return qvariant_cast >(invokeMethod(ListSupportedMethods)); } + inline QSet supportedMethods() + { return qvariant_cast >(invokeMethod(QAccessible::ListSupportedMethods)); } inline QAccessibleTextInterface *textInterface() { return reinterpret_cast(interface_cast(QAccessible::TextInterface)); } diff --git a/src/gui/accessible/qaccessible2.h b/src/gui/accessible/qaccessible2.h index 4155a1679a..93db869364 100644 --- a/src/gui/accessible/qaccessible2.h +++ b/src/gui/accessible/qaccessible2.h @@ -184,9 +184,6 @@ public: virtual void rowColumnExtents(int *row, int *column, int *rowExtents, int *columnExtents, bool *selected) const = 0; // Returns a reference to the accessbile of the containing table. virtual QAccessibleInterface* table() const = 0; - - // #### Qt5 this should not be here but part of the state - virtual bool isExpandable() const = 0; }; class Q_GUI_EXPORT QAccessibleTableInterface diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp index 695c66654e..18941437fe 100644 --- a/src/gui/accessible/qaccessibleobject.cpp +++ b/src/gui/accessible/qaccessibleobject.cpp @@ -150,7 +150,7 @@ QRect QAccessibleObject::rect() const } /*! \reimp */ -void QAccessibleObject::setText(Text, const QString &) +void QAccessibleObject::setText(QAccessible::Text, const QString &) { } @@ -231,13 +231,13 @@ QAccessible::Relation QAccessibleApplication::relationTo(const QAccessibleInterf { QObject *o = other ? other->object() : 0; if (!o) - return Unrelated; + return QAccessible::Unrelated; if(o == object()) { - return Self; + return QAccessible::Self; } - return Unrelated; + return QAccessible::Unrelated; } QAccessibleInterface *QAccessibleApplication::parent() const @@ -254,7 +254,7 @@ QAccessibleInterface *QAccessibleApplication::child(int index) const } /*! \reimp */ -int QAccessibleApplication::navigate(RelationFlag relation, int, +int QAccessibleApplication::navigate(QAccessible::RelationFlag relation, int, QAccessibleInterface **target) const { if (!target) @@ -264,16 +264,16 @@ int QAccessibleApplication::navigate(RelationFlag relation, int, QObject *targetObject = 0; switch (relation) { - case Self: + case QAccessible::Self: targetObject = object(); break; - case FocusChild: + case QAccessible::FocusChild: if (QWindow *window = QGuiApplication::activeWindow()) { *target = window->accessibleRoot(); return 0; } break; - case Ancestor: + case QAccessible::Ancestor: *target = parent(); return 0; default: @@ -284,12 +284,12 @@ int QAccessibleApplication::navigate(RelationFlag relation, int, } /*! \reimp */ -QString QAccessibleApplication::text(Text t) const +QString QAccessibleApplication::text(QAccessible::Text t) const { switch (t) { - case Name: + case QAccessible::Name: return QGuiApplication::applicationName(); - case Description: + case QAccessible::Description: return QGuiApplication::applicationFilePath(); default: break; @@ -300,13 +300,13 @@ QString QAccessibleApplication::text(Text t) const /*! \reimp */ QAccessible::Role QAccessibleApplication::role() const { - return Application; + return QAccessible::Application; } /*! \reimp */ QAccessible::State QAccessibleApplication::state() const { - return QGuiApplication::activeWindow() ? Focused : Normal; + return QGuiApplication::activeWindow() ? QAccessible::Focused : QAccessible::Normal; } diff --git a/src/gui/accessible/qaccessibleobject.h b/src/gui/accessible/qaccessibleobject.h index 75d277f05b..f2a9fd0430 100644 --- a/src/gui/accessible/qaccessibleobject.h +++ b/src/gui/accessible/qaccessibleobject.h @@ -66,7 +66,7 @@ public: // properties QRect rect() const; - void setText(Text t, const QString &text); + void setText(QAccessible::Text t, const QString &text); protected: virtual ~QAccessibleObject(); @@ -85,18 +85,18 @@ public: // relations int childCount() const; int indexOfChild(const QAccessibleInterface*) const; - Relation relationTo(const QAccessibleInterface *other) const; + QAccessible::Relation relationTo(const QAccessibleInterface *other) const; // navigation QAccessibleInterface *parent() const; int childAt(int x, int y) const; QAccessibleInterface *child(int index) const; - int navigate(RelationFlag, int, QAccessibleInterface **) const; + int navigate(QAccessible::RelationFlag, int, QAccessibleInterface **) const; // properties and state - QString text(Text t) const; - Role role() const; - State state() const; + QString text(QAccessible::Text t) const; + QAccessible::Role role() const; + QAccessible::State state() const; }; #endif // QT_NO_ACCESSIBILITY diff --git a/src/gui/accessible/qaccessibleplugin.h b/src/gui/accessible/qaccessibleplugin.h index 3db84469ca..4e09034dfd 100644 --- a/src/gui/accessible/qaccessibleplugin.h +++ b/src/gui/accessible/qaccessibleplugin.h @@ -56,7 +56,7 @@ QT_MODULE(Gui) class QStringList; class QAccessibleInterface; -struct Q_GUI_EXPORT QAccessibleFactoryInterface : public QAccessible, public QFactoryInterface +struct Q_GUI_EXPORT QAccessibleFactoryInterface : public QFactoryInterface { virtual QAccessibleInterface* create(const QString &key, QObject *object) = 0; }; diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index c6f6cab5da..57ed3a983a 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -50,7 +50,9 @@ HEADERS += \ kernel/qsessionmanager.h \ kernel/qwindowdefs.h \ kernel/qscreen.h \ - kernel/qstylehints.h + kernel/qstylehints.h \ + kernel/qtouchdevice.h \ + kernel/qtouchdevice_p.h SOURCES += \ kernel/qclipboard_qpa.cpp \ @@ -91,6 +93,7 @@ SOURCES += \ kernel/qguivariant.cpp \ kernel/qscreen.cpp \ kernel/qshortcutmap.cpp \ - kernel/qstylehints.cpp + kernel/qstylehints.cpp \ + kernel/qtouchdevice.cpp win32:HEADERS+=kernel/qwindowdefs_win.h diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 0d26268030..035f1b2666 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3450,34 +3450,25 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent() This enum represents the type of device that generated a QTouchEvent. - \value TouchScreen In this type of device, the touch surface and display are integrated. This - means the surface and display typically have the same size, such that there - is a direct relationship between the touch points' physical positions and the - coordinate reported by QTouchEvent::TouchPoint. As a result, Qt allows the - user to interact directly with multiple QWidgets and QGraphicsItems at the - same time. + This enum has been deprecated. Use QTouchDevice::DeviceType instead. - \value TouchPad In this type of device, the touch surface is separate from the display. There - is not a direct relationship between the physical touch location and the - on-screen coordinates. Instead, they are calculated relative to the current - mouse position, and the user must use the touch-pad to move this reference - point. Unlike touch-screens, Qt allows users to only interact with a single - QWidget or QGraphicsItem at a time. + \sa QTouchDevice::DeviceType, QTouchDevice::type(), QTouchEvent::device() */ /*! - Constructs a QTouchEvent with the given \a eventType, \a deviceType, and \a touchPoints. - The \a touchPointStates and \a modifiers are the current touch point states and keyboard - modifiers at the time of the event. + Constructs a QTouchEvent with the given \a eventType, \a deviceType, \a + touchPoints and \a device. The \a touchPointStates and \a modifiers + are the current touch point states and keyboard modifiers at the time of + the event. */ QTouchEvent::QTouchEvent(QEvent::Type eventType, - QTouchEvent::DeviceType deviceType, + QTouchDevice *device, Qt::KeyboardModifiers modifiers, Qt::TouchPointStates touchPointStates, const QList &touchPoints) : QInputEvent(eventType, modifiers), _widget(0), - _deviceType(deviceType), + _device(device), _touchPointStates(touchPointStates), _touchPoints(touchPoints) { } @@ -3493,6 +3484,22 @@ QTouchEvent::~QTouchEvent() Returns the widget on which the event occurred. */ +/*! \fn QWindow *QTouchEvent::window() const + + Returns the window on which the event occurred. Useful for doing + global-local mapping on data like rawScreenPositions() which, + for performance reasons, only stores the global positions in the + touch event. +*/ + +/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const + + Returns the touch device Type, which is of type \l {QTouchEvent::DeviceType} {DeviceType}. + + This function has been deprecated. Use QTouchDevice::type() instead. + + \sa QTouchDevice::type(), QTouchEvent::device() +*/ /*! \fn Qt::TouchPointStates QTouchEvent::touchPointStates() const @@ -3509,6 +3516,11 @@ QTouchEvent::~QTouchEvent() Returns the touch device Type, which is of type \l {QTouchEvent::DeviceType} {DeviceType}. */ +/*! \fn QTouchDevice* QTouchEvent::device() const + + Returns the touch device from which this touch event originates. +*/ + /*! \fn void QTouchEvent::setWidget(QWidget *widget) \internal @@ -3516,6 +3528,13 @@ QTouchEvent::~QTouchEvent() Sets the widget for this event. */ +/*! \fn void QTouchEvent::setWindow(QWindow *window) + + \internal + + Sets the window for this event. +*/ + /*! \fn void QTouchEvent::setTouchPointStates(Qt::TouchPointStates touchPointStates) \internal @@ -3538,11 +3557,25 @@ QTouchEvent::~QTouchEvent() {DeviceType}. */ +/*! \fn void QTouchEvent::setTouchDevice(QTouchDevice *device) + + \internal + + Sets the touch event's device to the given one. +*/ + /*! \class QTouchEvent::TouchPoint \brief The TouchPoint class provides information about a touch point in a QTouchEvent. \since 4.6 */ +/*! \enum QTouchEvent::TouchPoint::InfoFlags + + The values of this enum describe additional information about a touch point. + + \value Pen Indicates that the contact has been made by a designated pointing device (e.g. a pen) instead of a finger. +*/ + /*! \internal Constructs a QTouchEvent::TouchPoint for use in a QTouchEvent. @@ -3795,6 +3828,42 @@ qreal QTouchEvent::TouchPoint::pressure() const return d->pressure; } +/*! + Returns a velocity vector for this touch point. + The vector is in the screen's coordinate system, using pixels per seconds for the magnitude. + + \note The returned vector is only valid if the touch device's capabilities include QTouchDevice::Velocity. + + \sa QTouchDevice::capabilities(), device() +*/ +QVector2D QTouchEvent::TouchPoint::velocity() const +{ + return d->velocity; +} + +/*! + Returns additional information about the touch point. + + \sa QTouchEvent::TouchPoint::InfoFlags + */ +QTouchEvent::TouchPoint::InfoFlags QTouchEvent::TouchPoint::flags() const +{ + return d->flags; +} + +/*! + Returns the raw, unfiltered positions for the touch point. The positions are in screen coordinates. + To get local coordinates you can use mapFromGlobal() of the QWindow returned by QTouchEvent::window(). + + \note Returns an empty list if the touch device's capabilities do not include QTouchDevice::RawPositions. + + \sa QTouchDevice::capabilities(), device(), window() + */ +QList QTouchEvent::TouchPoint::rawScreenPositions() const +{ + return d->rawScreenPositions; +} + /*! \internal */ void QTouchEvent::TouchPoint::setId(int id) { @@ -3939,6 +4008,30 @@ void QTouchEvent::TouchPoint::setPressure(qreal pressure) d->pressure = pressure; } +/*! \internal */ +void QTouchEvent::TouchPoint::setVelocity(const QVector2D &v) +{ + if (d->ref.load() != 1) + d = d->detach(); + d->velocity = v; +} + +/*! \internal */ +void QTouchEvent::TouchPoint::setRawScreenPositions(const QList &positions) +{ + if (d->ref.load() != 1) + d = d->detach(); + d->rawScreenPositions = positions; +} + +/* \internal */ +void QTouchEvent::TouchPoint::setFlags(InfoFlags flags) +{ + if (d->ref.load() != 1) + d = d->detach(); + d->flags = flags; +} + /*! \internal */ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::TouchPoint &other) { diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index a79a56b771..6a0442509c 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -54,7 +54,8 @@ #include #include #include - +#include +#include QT_BEGIN_HEADER @@ -692,6 +693,11 @@ public: class Q_GUI_EXPORT TouchPoint { public: + enum InfoFlag { + Pen = 0x0001 + }; + Q_DECLARE_FLAGS(InfoFlags, InfoFlag) + TouchPoint(int id = -1); TouchPoint(const QTouchEvent::TouchPoint &other); ~TouchPoint(); @@ -722,6 +728,9 @@ public: QRectF screenRect() const; qreal pressure() const; + QVector2D velocity() const; + InfoFlags flags() const; + QList rawScreenPositions() const; // internal void setId(int id); @@ -742,6 +751,9 @@ public: void setSceneRect(const QRectF &sceneRect); void setScreenRect(const QRectF &screenRect); void setPressure(qreal pressure); + void setVelocity(const QVector2D &v); + void setFlags(InfoFlags flags); + void setRawScreenPositions(const QList &positions); QTouchEvent::TouchPoint &operator=(const QTouchEvent::TouchPoint &other); private: @@ -752,32 +764,36 @@ public: friend class QApplicationPrivate; }; - enum DeviceType { + QT_DEPRECATED enum DeviceType { TouchScreen, TouchPad }; QTouchEvent(QEvent::Type eventType, - QTouchEvent::DeviceType deviceType = TouchScreen, + QTouchDevice *device = 0, Qt::KeyboardModifiers modifiers = Qt::NoModifier, Qt::TouchPointStates touchPointStates = 0, const QList &touchPoints = QList()); ~QTouchEvent(); inline QWidget *widget() const { return _widget; } - inline QTouchEvent::DeviceType deviceType() const { return _deviceType; } + inline QWindow *window() const { return _window; } + QT_DEPRECATED inline QTouchEvent::DeviceType deviceType() const { return static_cast(int(_device->type())); } inline Qt::TouchPointStates touchPointStates() const { return _touchPointStates; } inline const QList &touchPoints() const { return _touchPoints; } + inline QTouchDevice *device() const { return _device; } // internal inline void setWidget(QWidget *awidget) { _widget = awidget; } - inline void setDeviceType(DeviceType adeviceType) { _deviceType = adeviceType; } + inline void setWindow(QWindow *awindow) { _window = awindow; } inline void setTouchPointStates(Qt::TouchPointStates aTouchPointStates) { _touchPointStates = aTouchPointStates; } inline void setTouchPoints(const QList &atouchPoints) { _touchPoints = atouchPoints; } + inline void setDevice(QTouchDevice *device) { _device = device; } protected: QWidget *_widget; - QTouchEvent::DeviceType _deviceType; + QWindow *_window; + QTouchDevice *_device; Qt::TouchPointStates _touchPointStates; QList _touchPoints; @@ -787,6 +803,7 @@ protected: friend class QApplicationPrivate; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QTouchEvent::TouchPoint::InfoFlags) class QScrollPrepareEventPrivate; class Q_GUI_EXPORT QScrollPrepareEvent : public QEvent diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index fa6b675c86..1eee92d176 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -105,6 +105,9 @@ public: startPos, startScenePos, startScreenPos, startNormalizedPos, lastPos, lastScenePos, lastScreenPos, lastNormalizedPos; qreal pressure; + QVector2D velocity; + QTouchEvent::TouchPoint::InfoFlags flags; + QList rawScreenPositions; }; class QFileOpenEventPrivate diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index da981b577b..6d5e210e82 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -841,7 +841,7 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To QTouchEvent::TouchPoint previousTouchPoint; switch (touchPoint.state()) { case Qt::TouchPointPressed: - if (e->devType == QTouchEvent::TouchPad) { + if (e->device->type() == QTouchDevice::TouchPad) { // on touch-pads, send all touch points to the same widget w = d->windowForTouchPointId.isEmpty() ? QWeakPointer() @@ -944,13 +944,15 @@ void QGuiApplicationPrivate::processTouchEvent(QWindowSystemInterfacePrivate::To } QTouchEvent touchEvent(eventType, - e->devType, + e->device, e->modifiers, it.value().first, it.value().second); touchEvent.setTimestamp(e->timestamp); + touchEvent.setWindow(w); - for (int i = 0; i < touchEvent.touchPoints().count(); ++i) { + const int pointCount = touchEvent.touchPoints().count(); + for (int i = 0; i < pointCount; ++i) { QTouchEvent::TouchPoint &touchPoint = touchEvent._touchPoints[i]; // preserve the sub-pixel resolution diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp index 3549f647b5..6a9cb43028 100644 --- a/src/gui/kernel/qopenglcontext.cpp +++ b/src/gui/kernel/qopenglcontext.cpp @@ -164,6 +164,8 @@ bool QOpenGLContext::create() Q_D(QOpenGLContext); d->platformGLContext = QGuiApplicationPrivate::platformIntegration()->createPlatformOpenGLContext(this); d->platformGLContext->setContext(this); + if (!d->platformGLContext->isSharing()) + d->shareContext = 0; d->shareGroup = d->shareContext ? d->shareContext->shareGroup() : new QOpenGLContextGroup; d->shareGroup->d_func()->addContext(this); return d->platformGLContext; @@ -197,7 +199,7 @@ QOpenGLContext::~QOpenGLContext() bool QOpenGLContext::isValid() const { Q_D(const QOpenGLContext); - return d->platformGLContext != 0; + return d->platformGLContext && d->platformGLContext->isValid(); } /*! @@ -225,7 +227,7 @@ QOpenGLFunctions *QOpenGLContext::functions() const bool QOpenGLContext::makeCurrent(QSurface *surface) { Q_D(QOpenGLContext); - if (!d->platformGLContext) + if (!isValid()) return false; if (thread() != QThread::currentThread()) @@ -257,7 +259,7 @@ bool QOpenGLContext::makeCurrent(QSurface *surface) void QOpenGLContext::doneCurrent() { Q_D(QOpenGLContext); - if (!d->platformGLContext) + if (!isValid()) return; if (QOpenGLContext::currentContext() == this) @@ -282,7 +284,7 @@ QSurface *QOpenGLContext::surface() const void QOpenGLContext::swapBuffers(QSurface *surface) { Q_D(QOpenGLContext); - if (!d->platformGLContext) + if (!isValid()) return; if (!surface) { diff --git a/src/gui/kernel/qplatformopenglcontext_qpa.h b/src/gui/kernel/qplatformopenglcontext_qpa.h index fc1b404b91..1b3bfc9a34 100644 --- a/src/gui/kernel/qplatformopenglcontext_qpa.h +++ b/src/gui/kernel/qplatformopenglcontext_qpa.h @@ -68,6 +68,9 @@ public: virtual bool makeCurrent(QPlatformSurface *surface) = 0; virtual void doneCurrent() = 0; + virtual bool isSharing() const { return false; } + virtual bool isValid() const { return true; } + virtual QFunctionPointer getProcAddress(const QByteArray &procName) = 0; QOpenGLContext *context() const; diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp new file mode 100644 index 0000000000..abf1acc310 --- /dev/null +++ b/src/gui/kernel/qtouchdevice.cpp @@ -0,0 +1,224 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtouchdevice.h" +#include "qtouchdevice_p.h" +#include +#include +#include + +QT_BEGIN_NAMESPACE + +/*! + \class QTouchDevice + \brief The QTouchDevice class describes the device from with touch events originate. + \since 5.0 + \ingroup touch + + Each QTouchEvent contains a QTouchDevice pointer to allow accessing + device-specific properties like type and capabilities. It is the + responsibility of the platform or generic plug-ins to register the + available touch devices via QWindowSystemInterface before generating any + touch events. Applications do not need to instantiate this class, they + should just access the global instances pointed to by QTouchEvent::device(). +*/ + +/*! \enum QTouchDevice::DeviceType + + This enum represents the type of device that generated a QTouchEvent. + + \value TouchScreen In this type of device, the touch surface and display are integrated. This + means the surface and display typically have the same size, such that there + is a direct relationship between the touch points' physical positions and the + coordinate reported by QTouchEvent::TouchPoint. As a result, Qt allows the + user to interact directly with multiple QWidgets and QGraphicsItems at the + same time. + + \value TouchPad In this type of device, the touch surface is separate from the display. There + is not a direct relationship between the physical touch location and the + on-screen coordinates. Instead, they are calculated relative to the current + mouse position, and the user must use the touch-pad to move this reference + point. Unlike touch-screens, Qt allows users to only interact with a single + QWidget or QGraphicsItem at a time. +*/ + +/*! \enum QTouchDevice::CapabilityFlag + + This enum is used with QTouchDevice::capabilities() to indicate what kind of information the + touch device or its driver can provide. + + \value Position Indicates that position information is available, meaning + that the pos() family of functions in the touch points return valid points. + + \value Area Indicates that touch area information is available, meaning that the rect() family + of functions in the touch points return valid rectangles. + + \value Pressure Indicates that pressure information is available, meaning that pressure() + returns a valid value. + + \value Velocity Indicates that velocity information is available, meaning that velocity() + returns a valid vector. + + \value RawPositions Indicates that the list returned by QTouchEvent::TouchPoint::rawScreenPositions() + may contain one or more positions for each touch point. This is relevant when + the touch input gets filtered or corrected on driver level. + + \value NormalizedPosition Indicates that the normalized position is available, meaning that normalizedPos() + returns a valid value. +*/ + +/*! + Creates a new touch device instance. + By default the name is empty, the only capability is Position and type is TouchScreen. + */ +QTouchDevice::QTouchDevice() + : d(new QTouchDevicePrivate) +{ +} + +QTouchDevice::~QTouchDevice() +{ + delete d; +} + +/*! + Returns the touch device type. +*/ +QTouchDevice::DeviceType QTouchDevice::type() const +{ + return d->type; +} + +/*! + Returns the touch device capabilities. + */ +QTouchDevice::Capabilities QTouchDevice::capabilities() const +{ + return d->caps; +} + +/*! + Returns the touch device name. + + This string may often be empty. It is however useful for systems that have + more than one touch input device because there it can be used to + differentiate between the devices (i.e. to tell from which device a + QTouchEvent originates from). +*/ +QString QTouchDevice::name() const +{ + return d->name; +} + +/*! + Sets the device type. + */ +void QTouchDevice::setType(DeviceType devType) +{ + d->type = devType; +} + +/*! + Sets the capabilities supported by the device and its driver. + */ +void QTouchDevice::setCapabilities(Capabilities caps) +{ + d->caps = caps; +} + +/*! + Sets the name (a unique identifier) for the device. In most systems it is + enough to leave this unset and keep the default empty name. This identifier + becomes important when having multiple touch devices and a need to + differentiate between them. + */ +void QTouchDevice::setName(const QString &name) +{ + d->name = name; +} + +typedef QList TouchDevices; +Q_GLOBAL_STATIC(TouchDevices, deviceList) +Q_GLOBAL_STATIC(QMutex, devicesMutex) + +static void cleanupDevicesList() +{ + QMutexLocker lock(devicesMutex()); + qDeleteAll(*deviceList()); + deviceList()->clear(); +} + +/*! + Returns a list of all registered devices. + + \note The returned list cannot be used to add new devices. Use QWindowSystemInterface::registerTouchDevice() instead. + */ +QList QTouchDevice::devices() +{ + QMutexLocker lock(devicesMutex()); + QList *devList = deviceList(); + QList constDevList; + for (int i = 0, count = devList->count(); i != count; ++i) + constDevList.append(devList->at(i)); + return constDevList; +} + +/*! + \internal + */ +bool QTouchDevicePrivate::isRegistered(QTouchDevice *dev) +{ + QMutexLocker lock(devicesMutex()); + return deviceList()->contains(dev); +} + +/*! + \internal + */ +void QTouchDevicePrivate::registerDevice(QTouchDevice *dev) +{ + QMutexLocker lock(devicesMutex()); + if (deviceList()->isEmpty()) + qAddPostRoutine(cleanupDevicesList); + deviceList()->append(dev); +} + +QT_END_NAMESPACE diff --git a/src/widgets/kernel/qsound_p.h b/src/gui/kernel/qtouchdevice.h similarity index 60% rename from src/widgets/kernel/qsound_p.h rename to src/gui/kernel/qtouchdevice.h index df7147058b..496bb7a522 100644 --- a/src/widgets/kernel/qsound_p.h +++ b/src/gui/kernel/qtouchdevice.h @@ -39,62 +39,58 @@ ** ****************************************************************************/ -#ifndef QSOUND_P_H -#define QSOUND_P_H +#ifndef QTOUCHDEVICE_H +#define QTOUCHDEVICE_H -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of other Qt classes. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// +#include -#include "QtCore/qobject.h" +QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -#ifndef QT_NO_SOUND +QT_MODULE(Gui) -class QSound; -/* - QAuServer is an INTERNAL class. If you wish to provide support for - additional audio servers, you can make a subclass of QAuServer to do - so, HOWEVER, your class may need to be re-engineered to some degree - with each new Qt release, including minor releases. +class QTouchDevicePrivate; - QAuBucket is whatever you want. -*/ - -class QAuBucket { +class Q_GUI_EXPORT QTouchDevice +{ public: - virtual ~QAuBucket(); + enum DeviceType { + TouchScreen, + TouchPad + }; + + enum CapabilityFlag { + Position = 0x0001, + Area = 0x0002, + Pressure = 0x0004, + Velocity = 0x0008, + RawPositions = 0x0010, + NormalizedPosition = 0x0020 + }; + Q_DECLARE_FLAGS(Capabilities, CapabilityFlag) + + QTouchDevice(); + ~QTouchDevice(); + + static QList devices(); + + QString name() const; + DeviceType type() const; + Capabilities capabilities() const; + + void setName(const QString &name); + void setType(DeviceType devType); + void setCapabilities(Capabilities caps); + +private: + QTouchDevicePrivate *d; }; -class QAuServer : public QObject { - Q_OBJECT - -public: - explicit QAuServer(QObject* parent); - ~QAuServer(); - - virtual void init(QSound*); - virtual void play(const QString& filename); - virtual void play(QSound*)=0; - virtual void stop(QSound*)=0; - virtual bool okay()=0; - -protected: - void setBucket(QSound*, QAuBucket*); - QAuBucket* bucket(QSound*); - int decLoop(QSound*); -}; - -#endif // QT_NO_SOUND +Q_DECLARE_OPERATORS_FOR_FLAGS(QTouchDevice::Capabilities) QT_END_NAMESPACE -#endif // QSOUND_P_H +QT_END_HEADER + +#endif // QTOUCHDEVICE_H diff --git a/src/widgets/kernel/qsound.h b/src/gui/kernel/qtouchdevice_p.h similarity index 75% rename from src/widgets/kernel/qsound.h rename to src/gui/kernel/qtouchdevice_p.h index 79fd241948..f782d1585d 100644 --- a/src/widgets/kernel/qsound.h +++ b/src/gui/kernel/qtouchdevice_p.h @@ -39,10 +39,11 @@ ** ****************************************************************************/ -#ifndef QSOUND_H -#define QSOUND_H +#ifndef QTOUCHDEVICE_P_H +#define QTOUCHDEVICE_P_H #include +#include QT_BEGIN_HEADER @@ -50,41 +51,24 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -#ifndef QT_NO_SOUND - -class QSoundPrivate; - -class Q_WIDGETS_EXPORT QSound : public QObject +class QTouchDevicePrivate { - Q_OBJECT - public: - static bool isAvailable(); - static void play(const QString& filename); + QTouchDevicePrivate() + : type(QTouchDevice::TouchScreen), + caps(QTouchDevice::Position) + { } - explicit QSound(const QString& filename, QObject* parent = 0); - ~QSound(); + QTouchDevice::DeviceType type; + QTouchDevice::Capabilities caps; + QString name; - int loops() const; - int loopsRemaining() const; - void setLoops(int); - QString fileName() const; - - bool isFinished() const; - -public Q_SLOTS: - void play(); - void stop(); - -private: - Q_DECLARE_PRIVATE(QSound) - friend class QAuServer; + static void registerDevice(QTouchDevice *dev); + static bool isRegistered(QTouchDevice *dev); }; -#endif // QT_NO_SOUND - QT_END_NAMESPACE QT_END_HEADER -#endif // QSOUND_H +#endif // QTOUCHDEVICE_P_H diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.cpp b/src/gui/kernel/qwindowsysteminterface_qpa.cpp index 979a168c05..016446780b 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.cpp +++ b/src/gui/kernel/qwindowsysteminterface_qpa.cpp @@ -41,6 +41,7 @@ #include "qwindowsysteminterface_qpa.h" #include "qwindowsysteminterface_qpa_p.h" #include "private/qguiapplication_p.h" +#include "private/qtouchdevice_p.h" #include #include @@ -213,16 +214,28 @@ void QWindowSystemInterfacePrivate::queueWindowSystemEvent(QWindowSystemInterfac dispatcher->wakeUp(); } -void QWindowSystemInterface::handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList &points, Qt::KeyboardModifiers mods) { - unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); - handleTouchEvent(w, time, type, devType, points, mods); +void QWindowSystemInterface::registerTouchDevice(QTouchDevice *device) +{ + QTouchDevicePrivate::registerDevice(device); } -void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList &points, Qt::KeyboardModifiers mods) +void QWindowSystemInterface::handleTouchEvent(QWindow *w, QEvent::Type type, QTouchDevice *device, + const QList &points, Qt::KeyboardModifiers mods) +{ + unsigned long time = QWindowSystemInterfacePrivate::eventTime.elapsed(); + handleTouchEvent(w, time, type, device, points, mods); +} + +void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEvent::Type type, + QTouchDevice *device, + const QList &points, Qt::KeyboardModifiers mods) { if (!points.size()) // Touch events must have at least one point return; + if (!QTouchDevicePrivate::isRegistered(device)) // Disallow passing bogus, non-registered devices. + return; + QList touchPoints; Qt::TouchPointStates states; QTouchEvent::TouchPoint p; @@ -247,13 +260,16 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QEv // when the event gets processed by QGuiApplication. p.setNormalizedPos(point->normalPosition); + p.setVelocity(point->velocity); + p.setFlags(point->flags); + p.setRawScreenPositions(point->rawPositions); touchPoints.append(p); ++point; } QWindowSystemInterfacePrivate::TouchEvent *e = - new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, devType, touchPoints, mods); + new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods); QWindowSystemInterfacePrivate::queueWindowSystemEvent(e); } diff --git a/src/gui/kernel/qwindowsysteminterface_qpa.h b/src/gui/kernel/qwindowsysteminterface_qpa.h index d00f0af37c..423281955c 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa.h @@ -51,12 +51,14 @@ #include #include #include +#include QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QMimeData; +class QTouchDevice; QT_MODULE(Gui) @@ -84,16 +86,23 @@ public: static void handleWheelEvent(QWindow *w, ulong timestamp, const QPointF & local, const QPointF & global, int d, Qt::Orientation o, Qt::KeyboardModifiers mods = Qt::NoModifier); struct TouchPoint { + TouchPoint() : id(0), isPrimary(false), pressure(0), state(Qt::TouchPointStationary), flags(0) { } int id; // for application use bool isPrimary; // for application use QPointF normalPosition; // touch device coordinates, (0 to 1, 0 to 1) QRectF area; // the touched area, centered at position in screen coordinates qreal pressure; // 0 to 1 Qt::TouchPointState state; //Qt::TouchPoint{Pressed|Moved|Stationary|Released} + QVector2D velocity; // in screen coordinate system, pixels / seconds + QTouchEvent::TouchPoint::InfoFlags flags; + QList rawPositions; // in screen coordinates }; - static void handleTouchEvent(QWindow *w, QEvent::Type type, QTouchEvent::DeviceType devType, const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier); - static void handleTouchEvent(QWindow *w, ulong timestamp, QEvent::Type type, QTouchEvent::DeviceType devType, const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier); + static void registerTouchDevice(QTouchDevice *device); + static void handleTouchEvent(QWindow *w, QEvent::Type type, QTouchDevice *device, + const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier); + static void handleTouchEvent(QWindow *w, ulong timestamp, QEvent::Type type, QTouchDevice *device, + const QList &points, Qt::KeyboardModifiers mods = Qt::NoModifier); static void handleGeometryChange(QWindow *w, const QRect &newRect); static void handleSynchronousGeometryChange(QWindow *w, const QRect &newRect); diff --git a/src/gui/kernel/qwindowsysteminterface_qpa_p.h b/src/gui/kernel/qwindowsysteminterface_qpa_p.h index 7d5455c06b..5580104c3b 100644 --- a/src/gui/kernel/qwindowsysteminterface_qpa_p.h +++ b/src/gui/kernel/qwindowsysteminterface_qpa_p.h @@ -187,12 +187,12 @@ public: class TouchEvent : public InputEvent { public: - TouchEvent(QWindow *w, ulong time, QEvent::Type t, QTouchEvent::DeviceType d, const QList &p, Qt::KeyboardModifiers mods) - :InputEvent(w, time, Touch, mods), devType(d), points(p), touchType(t) { } - QTouchEvent::DeviceType devType; + TouchEvent(QWindow *w, ulong time, QEvent::Type t, QTouchDevice *dev, + const QList &p, Qt::KeyboardModifiers mods) + :InputEvent(w, time, Touch, mods), device(dev), points(p), touchType(t) { } + QTouchDevice *device; QList points; QEvent::Type touchType; - }; class ScreenOrientationEvent : public WindowSystemEvent { diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index e03b3fc59d..f0755337fc 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -472,11 +472,15 @@ void QHttpThreadDelegate::headerChangedSlot() // Is using a zerocopy buffer allowed by user and possible with this reply? if (httpReply->supportsUserProvidedDownloadBuffer() - && downloadBufferMaximumSize > 0) { - char *buf = new char[httpReply->contentLength()]; // throws if allocation fails - if (buf) { - downloadBuffer = QSharedPointer(buf, downloadBufferDeleter); - httpReply->setUserProvidedDownloadBuffer(buf); + && (downloadBufferMaximumSize > 0) && (httpReply->contentLength() <= downloadBufferMaximumSize)) { + QT_TRY { + char *buf = new char[httpReply->contentLength()]; // throws if allocation fails + if (buf) { + downloadBuffer = QSharedPointer(buf, downloadBufferDeleter); + httpReply->setUserProvidedDownloadBuffer(buf); + } + } QT_CATCH(const std::bad_alloc &) { + // in out of memory situations, don't use downloadbuffer. } } diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 05f50af6f1..e3dd6ae0c5 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1630,6 +1630,10 @@ void QSslSocket::startClientEncryption() qWarning("QSslSocket::startClientEncryption: cannot start handshake on non-plain connection"); return; } + if (state() != ConnectedState) { + qWarning("QSslSocket::startClientEncryption: cannot start handshake when not connected"); + return; + } #ifdef QSSLSOCKET_DEBUG qDebug() << "QSslSocket::startClientEncryption()"; #endif diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp index dfa0bacd35..1f1f215494 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp +++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp @@ -56,7 +56,7 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform EGLConfig config = q_configFromGLFormat(display, format, true); m_format = q_glFormatFromConfig(display, config); - EGLContext shareContext = share ? static_cast(share)->m_eglContext : 0; + m_shareContext = share ? static_cast(share)->m_eglContext : 0; QVector contextAttrs; contextAttrs.append(EGL_CONTEXT_CLIENT_VERSION); @@ -64,11 +64,10 @@ QEGLPlatformContext::QEGLPlatformContext(const QSurfaceFormat &format, QPlatform contextAttrs.append(EGL_NONE); eglBindAPI(m_eglApi); - m_eglContext = eglCreateContext(m_eglDisplay, config, shareContext, contextAttrs.constData()); - if (m_eglContext == EGL_NO_CONTEXT) { - qWarning("Could not create the egl context\n"); - eglTerminate(m_eglDisplay); - qFatal("EGL error"); + m_eglContext = eglCreateContext(m_eglDisplay, config, m_shareContext, contextAttrs.constData()); + if (m_eglContext == EGL_NO_CONTEXT && m_shareContext != EGL_NO_CONTEXT) { + m_shareContext = 0; + m_eglContext = eglCreateContext(m_eglDisplay, config, 0, contextAttrs.constData()); } } diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h index c38af1dfda..7002c8b9c2 100644 --- a/src/platformsupport/eglconvenience/qeglplatformcontext_p.h +++ b/src/platformsupport/eglconvenience/qeglplatformcontext_p.h @@ -59,6 +59,8 @@ public: void (*getProcAddress(const QByteArray &procName)) (); QSurfaceFormat format() const; + bool isSharing() const { return m_shareContext != EGL_NO_CONTEXT; } + bool isValid() const { return m_eglContext != EGL_NO_CONTEXT; } EGLContext eglContext() const; @@ -67,6 +69,7 @@ protected: private: EGLContext m_eglContext; + EGLContext m_shareContext; EGLDisplay m_eglDisplay; EGLenum m_eglApi; diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index f5145bf537..1ceeb31b16 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -270,7 +270,7 @@ QString QAccessibleItemRow::text_helper(int child) const return value; } -QString QAccessibleItemRow::text(Text t, int child) const +QString QAccessibleItemRow::text(QAccessible::Text t, int child) const { QString value; if (t == Name) { @@ -339,7 +339,7 @@ QString QAccessibleItemRow::text(Text t, int child) const return value; } -void QAccessibleItemRow::setText(Text t, int child, const QString &text) +void QAccessibleItemRow::setText(QAccessible::Text t, int child, const QString &text) { if (m_header) { if (child) @@ -966,7 +966,7 @@ int QAccessibleItemView::childCount() const } } -QString QAccessibleItemView::text(Text t, int child) const +QString QAccessibleItemView::text(QAccessible::Text t, int child) const { if (atViewport()) { if (!child) @@ -983,7 +983,7 @@ QString QAccessibleItemView::text(Text t, int child) const } } -void QAccessibleItemView::setText(Text t, int child, const QString &text) +void QAccessibleItemView::setText(QAccessible::Text t, int child, const QString &text) { if (atViewport()) { if (!child) { @@ -1386,7 +1386,7 @@ int QAccessibleHeader::childCount() const return header()->count(); } -QString QAccessibleHeader::text(Text t, int child) const +QString QAccessibleHeader::text(QAccessible::Text t, int child) const { QString str; @@ -1464,10 +1464,10 @@ public: } QObject *object() const { return 0; } - Role role() const { return QAccessible::PageTab; } - State state() const { + QAccessible::Role role() const { return QAccessible::PageTab; } + QAccessible::State state() const { QAccessibleInterface *parentInterface = parent(); - State state = parentInterface->state(); + QAccessible::State state = parentInterface->state(); delete parentInterface; return state; } @@ -1487,14 +1487,14 @@ public: int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } - QString text(Text) const { return qt_accStripAmp(m_parent->tabText(m_index)); } - void setText(Text, const QString &) {} + QString text(QAccessible::Text) const { return qt_accStripAmp(m_parent->tabText(m_index)); } + void setText(QAccessible::Text, const QString &) {} QAccessibleInterface *parent() const { return QAccessible::queryAccessibleInterface(m_parent); } QAccessibleInterface *child(int) const { return 0; } - int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const + int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const { if (relation == QAccessible::Ancestor && index == 1) { *iface = parent(); @@ -1502,7 +1502,7 @@ public: } return -1; } - Relation relationTo(const QAccessibleInterface *) const + QAccessible::Relation relationTo(const QAccessibleInterface *) const { return QAccessible::Unrelated; } @@ -1533,7 +1533,7 @@ private: Constructs a QAccessibleTabBar object for \a w. */ QAccessibleTabBar::QAccessibleTabBar(QWidget *w) -: QAccessibleWidget(w, PageTabList) +: QAccessibleWidget(w, QAccessible::PageTabList) { Q_ASSERT(tabBar()); } @@ -1544,7 +1544,7 @@ QTabBar *QAccessibleTabBar::tabBar() const return qobject_cast(object()); } -int QAccessibleTabBar::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const +int QAccessibleTabBar::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const { if (rel == QAccessible::Child) { *target = child(entry - 1); @@ -1590,7 +1590,7 @@ int QAccessibleTabBar::childCount() const return tabBar()->count() + 2; } -QString QAccessibleTabBar::text(Text t) const +QString QAccessibleTabBar::text(QAccessible::Text t) const { if (t == QAccessible::Name) { return qt_accStripAmp(tabBar()->tabText(tabBar()->currentIndex())); @@ -1648,7 +1648,7 @@ QVector QAccessibleTabBar::selection() const Constructs a QAccessibleComboBox object for \a w. */ QAccessibleComboBox::QAccessibleComboBox(QWidget *w) -: QAccessibleWidget(w, ComboBox) +: QAccessibleWidget(w, QAccessible::ComboBox) { Q_ASSERT(comboBox()); } @@ -1696,24 +1696,24 @@ int QAccessibleComboBox::indexOfChild(const QAccessibleInterface *child) const } /*! \reimp */ -QString QAccessibleComboBox::text(Text t) const +QString QAccessibleComboBox::text(QAccessible::Text t) const { QString str; switch (t) { - case Name: + case QAccessible::Name: #ifndef Q_OS_UNIX // on Linux we use relations for this, name is text (fall through to Value) str = QAccessibleWidget::text(t); break; #endif - case Value: + case QAccessible::Value: if (comboBox()->isEditable()) str = comboBox()->lineEdit()->text(); else str = comboBox()->currentText(); break; #ifndef QT_NO_SHORTCUT - case Accelerator: + case QAccessible::Accelerator: str = (QString)QKeySequence(Qt::Key_Down); break; #endif @@ -1770,7 +1770,7 @@ static inline void removeInvisibleWidgetsFromList(QWidgetList *list) #ifndef QT_NO_SCROLLAREA // ======================= QAccessibleAbstractScrollArea ======================= QAccessibleAbstractScrollArea::QAccessibleAbstractScrollArea(QWidget *widget) - : QAccessibleWidget(widget, Client) + : QAccessibleWidget(widget, QAccessible::Client) { Q_ASSERT(qobject_cast(widget)); } @@ -1805,7 +1805,7 @@ bool QAccessibleAbstractScrollArea::isValid() const return (QAccessibleWidget::isValid() && abstractScrollArea() && abstractScrollArea()->viewport()); } -int QAccessibleAbstractScrollArea::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleAbstractScrollArea::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { if (!target) return -1; @@ -1815,8 +1815,8 @@ int QAccessibleAbstractScrollArea::navigate(RelationFlag relation, int entry, QA QWidget *targetWidget = 0; QWidget *entryWidget = 0; - if (relation == Child || - relation == Left || relation == Up || relation == Right || relation == Down) { + if (relation == QAccessible::Child || + relation == QAccessible::Left || relation == QAccessible::Up || relation == QAccessible::Right || relation == QAccessible::Down) { QWidgetList children = accessibleChildren(); if (entry < 0 || entry > children.count()) return -1; @@ -1832,12 +1832,12 @@ int QAccessibleAbstractScrollArea::navigate(RelationFlag relation, int entry, QA // It might be possible to make it more general, but I'll leave that as an exercise // to the reader. :-) switch (relation) { - case Child: + case QAccessible::Child: if (entry > 0) { *target = child(entry - 1); return *target ? 0 : -1; } - case Left: + case QAccessible::Left: if (entry < 1) break; switch (entryElement) { @@ -1861,7 +1861,7 @@ int QAccessibleAbstractScrollArea::navigate(RelationFlag relation, int entry, QA break; } break; - case Right: + case QAccessible::Right: if (entry < 1) break; switch (entryElement) { @@ -1884,7 +1884,7 @@ int QAccessibleAbstractScrollArea::navigate(RelationFlag relation, int entry, QA break; } break; - case Up: + case QAccessible::Up: if (entry < 1) break; switch (entryElement) { @@ -1898,7 +1898,7 @@ int QAccessibleAbstractScrollArea::navigate(RelationFlag relation, int entry, QA break; } break; - case Down: + case QAccessible::Down: if (entry < 1) break; switch (entryElement) { diff --git a/src/plugins/accessible/widgets/complexwidgets.h b/src/plugins/accessible/widgets/complexwidgets.h index f094719a6c..2dde422b12 100644 --- a/src/plugins/accessible/widgets/complexwidgets.h +++ b/src/plugins/accessible/widgets/complexwidgets.h @@ -79,7 +79,7 @@ public: int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; bool isValid() const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; // int childAt(int x, int y) const; //protected: @@ -109,7 +109,7 @@ public: int childCount() const; QRect rect(int child) const; - QString text(Text t, int child) const; + QString text(QAccessible::Text t, int child) const; Role role(int child) const; State state(int child) const; @@ -123,8 +123,8 @@ class QAccessibleItemRow: public QAccessibleInterface public: QAccessibleItemRow(QAbstractItemView *view, const QModelIndex &index = QModelIndex(), bool isHeader = false); QRect rect(int child) const; - QString text(Text t, int child) const; - void setText(Text t, int child, const QString &text); + QString text(QAccessible::Text t, int child) const; + void setText(QAccessible::Text t, int child, const QString &text); bool isValid() const; QObject *object() const; Role role(int child) const; @@ -138,7 +138,7 @@ public: int childAt(int x, int y) const; QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; + int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; int userActionCount(int child) const; QString actionText(int action, Text t, int child) const; @@ -170,14 +170,14 @@ public: QRect rect(int child) const; int childAt(int x, int y) const; int childCount() const; - QString text(Text t, int child) const; - void setText(Text t, int child, const QString &text); + QString text(QAccessible::Text t, int child) const; + void setText(QAccessible::Text t, int child, const QString &text); int indexOfChild(const QAccessibleInterface *iface) const; QModelIndex childIndex(int child) const; int entryFromIndex(const QModelIndex &index) const; bool isValid() const; - int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; + int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; QAccessibleInterface *accessibleAt(int row, int column); QAccessibleInterface *caption(); @@ -234,14 +234,14 @@ public: explicit QAccessibleTabBar(QWidget *w); int childCount() const; - QString text(Text t) const; + QString text(QAccessible::Text t) const; bool setSelected(int child, bool on, bool extend); QVector selection() const; QAccessibleInterface* child(int index) const; int indexOfChild(const QAccessibleInterface *child) const; - int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const; protected: QTabBar *tabBar() const; @@ -259,7 +259,7 @@ public: int indexOfChild(const QAccessibleInterface *child) const; QAccessibleInterface* child(int index) const; - QString text(Text t) const; + QString text(QAccessible::Text t) const; // QAccessibleActionInterface QStringList actionNames() const; diff --git a/src/plugins/accessible/widgets/itemviews.cpp b/src/plugins/accessible/widgets/itemviews.cpp index 3c416b7e23..b33260099f 100644 --- a/src/plugins/accessible/widgets/itemviews.cpp +++ b/src/plugins/accessible/widgets/itemviews.cpp @@ -224,7 +224,6 @@ QAccessibleInterface *QAccessibleTable::cellAt(int row, int column) const { Q_ASSERT(role() != QAccessible::Tree); QModelIndex index = view->model()->index(row, column); - //Q_ASSERT(index.isValid()); if (!index.isValid()) { qWarning() << "QAccessibleTable::cellAt: invalid index: " << index << " for " << view; return 0; @@ -411,7 +410,7 @@ int QAccessibleTable::indexOfChild(const QAccessibleInterface *iface) const return -1; } -QString QAccessibleTable::text(Text t) const +QString QAccessibleTable::text(QAccessible::Text t) const { if (t == QAccessible::Description) return view->accessibleDescription(); @@ -443,11 +442,11 @@ QAccessibleInterface *QAccessibleTable::child(int index) const return childFromLogical(index + 1); } -int QAccessibleTable::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +int QAccessibleTable::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const { *iface = 0; switch (relation) { - case Ancestor: { + case QAccessible::Ancestor: { *iface = parent(); return *iface ? 0 : -1; } @@ -551,7 +550,7 @@ int QAccessibleTree::indexOfChild(const QAccessibleInterface *iface) const return -1; } -int QAccessibleTree::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +int QAccessibleTree::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const { switch (relation) { case QAccessible::Child: { @@ -623,7 +622,8 @@ bool QAccessibleTree::selectRow(int row) QAccessibleTableCell::QAccessibleTableCell(QAbstractItemView *view_, const QModelIndex &index_, QAccessible::Role role_) : /* QAccessibleSimpleEditableTextInterface(this), */ view(view_), m_index(index_), m_role(role_) { - Q_ASSERT(index_.isValid()); + if (!index_.isValid()) + qWarning() << "QAccessibleTableCell::QAccessibleTableCell with invalid index: " << index_; } void *QAccessibleTableCell::interface_cast(QAccessible::InterfaceType t) @@ -724,41 +724,38 @@ QAccessible::Role QAccessibleTableCell::role() const QAccessible::State QAccessibleTableCell::state() const { - State st = Normal; - + QAccessible::State st = QAccessible::Normal; QRect globalRect = view->rect(); globalRect.translate(view->mapToGlobal(QPoint(0,0))); if (!globalRect.intersects(rect())) - st |= Invisible; + st |= QAccessible::Invisible; if (view->selectionModel()->isSelected(m_index)) - st |= Selected; + st |= QAccessible::Selected; if (view->selectionModel()->currentIndex() == m_index) - st |= Focused; + st |= QAccessible::Focused; if (m_index.model()->data(m_index, Qt::CheckStateRole).toInt() == Qt::Checked) - st |= Checked; + st |= QAccessible::Checked; Qt::ItemFlags flags = m_index.flags(); if (flags & Qt::ItemIsSelectable) { - st |= Selectable; - st |= Focusable; + st |= QAccessible::Selectable; + st |= QAccessible::Focusable; if (view->selectionMode() == QAbstractItemView::MultiSelection) - st |= MultiSelectable; + st |= QAccessible::MultiSelectable; if (view->selectionMode() == QAbstractItemView::ExtendedSelection) - st |= ExtSelectable; + st |= QAccessible::ExtSelectable; } if (m_role == QAccessible::TreeItem) { const QTreeView *treeView = qobject_cast(view); + if (treeView->model()->hasChildren(m_index)) + st |= QAccessible::Expandable; if (treeView->isExpanded(m_index)) - st |= Expanded; + st |= QAccessible::Expanded; } return st; } -bool QAccessibleTableCell::isExpandable() const -{ - return view->model()->hasChildren(m_index); -} QRect QAccessibleTableCell::rect() const { @@ -771,7 +768,7 @@ QRect QAccessibleTableCell::rect() const return r; } -QString QAccessibleTableCell::text(Text t) const +QString QAccessibleTableCell::text(QAccessible::Text t) const { QAbstractItemModel *model = view->model(); QString value; @@ -791,7 +788,7 @@ QString QAccessibleTableCell::text(Text t) const return value; } -void QAccessibleTableCell::setText(Text /*t*/, const QString &text) +void QAccessibleTableCell::setText(QAccessible::Text /*t*/, const QString &text) { if (!(m_index.flags() & Qt::ItemIsEditable)) return; @@ -800,10 +797,6 @@ void QAccessibleTableCell::setText(Text /*t*/, const QString &text) bool QAccessibleTableCell::isValid() const { - if (!m_index.isValid()) { - qDebug() << "Interface is not valid"; - } - return m_index.isValid(); } @@ -820,9 +813,9 @@ QAccessibleInterface *QAccessibleTableCell::child(int) const return 0; } -int QAccessibleTableCell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +int QAccessibleTableCell::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const { - if (relation == Ancestor && index == 1) { + if (relation == QAccessible::Ancestor && index == 1) { *iface = parent(); return 0; } @@ -833,12 +826,12 @@ int QAccessibleTableCell::navigate(RelationFlag relation, int index, QAccessible switch (relation) { - case Child: { + case QAccessible::Child: { return -1; } - case Sibling: + case QAccessible::Sibling: if (index > 0) { - QAccessibleInterface *parent = queryAccessibleInterface(view); + QAccessibleInterface *parent = QAccessible::queryAccessibleInterface(view); *iface = parent->child(index - 1); delete parent; return *iface ? 0 : -1; @@ -934,7 +927,7 @@ QRect QAccessibleTableHeaderCell::rect() const : QRect(zero.x(), zero.y() + sectionPos, header->width(), sectionSize); } -QString QAccessibleTableHeaderCell::text(Text t) const +QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const { QAbstractItemModel *model = view->model(); QString value; @@ -954,7 +947,7 @@ QString QAccessibleTableHeaderCell::text(Text t) const return value; } -void QAccessibleTableHeaderCell::setText(Text, const QString &) +void QAccessibleTableHeaderCell::setText(QAccessible::Text, const QString &) { return; } @@ -981,7 +974,7 @@ QAccessibleInterface *QAccessibleTableHeaderCell::child(int) const return 0; } -int QAccessibleTableHeaderCell::navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const +int QAccessibleTableHeaderCell::navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const { if (relation == QAccessible::Ancestor && index == 1) { *iface = parent(); diff --git a/src/plugins/accessible/widgets/itemviews.h b/src/plugins/accessible/widgets/itemviews.h index 9d58fd0957..08e0bbb487 100644 --- a/src/plugins/accessible/widgets/itemviews.h +++ b/src/plugins/accessible/widgets/itemviews.h @@ -66,9 +66,9 @@ public: virtual ~QAccessibleTable(); QObject *object() const { return view; } - Role role() const; - State state() const; - QString text(Text t) const; + QAccessible::Role role() const; + QAccessible::State state() const; + QString text(QAccessible::Text t) const; QRect rect() const; int childAt(int x, int y) const; @@ -77,10 +77,10 @@ public: QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; - Relation relationTo(const QAccessibleInterface *other) const; + int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; + QAccessible::Relation relationTo(const QAccessibleInterface *other) const; - QVariant invokeMethod(Method, const QVariantList &) { return QVariant(); } + QVariant invokeMethod(QAccessible::Method, const QVariantList &) { return QVariant(); } void *interface_cast(QAccessible::InterfaceType t); // table interface @@ -159,8 +159,8 @@ public: int rowCount() const; - int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; - Relation relationTo(const QAccessibleInterface *other) const; + int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; + QAccessible::Relation relationTo(const QAccessibleInterface *other) const; // table interface QAccessibleInterface *cellAt(int row, int column) const; @@ -179,8 +179,8 @@ public: void *interface_cast(QAccessible::InterfaceType t); QObject *object() const { return 0; } - Role role() const; - State state() const; + QAccessible::Role role() const; + QAccessible::State state() const; QRect rect() const; bool isValid() const; @@ -188,15 +188,13 @@ public: int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } - QString text(Text t) const; - void setText(Text t, const QString &text); + QString text(QAccessible::Text t) const; + void setText(QAccessible::Text t, const QString &text); QAccessibleInterface *parent() const; QAccessibleInterface *child(int) const; - int navigate(RelationFlag relation, int m_index, QAccessibleInterface **iface) const; - Relation relationTo(const QAccessibleInterface *other) const; - - bool isExpandable() const; + int navigate(QAccessible::RelationFlag relation, int m_index, QAccessibleInterface **iface) const; + QAccessible::Relation relationTo(const QAccessibleInterface *other) const; // cell interface virtual int columnExtent() const; @@ -228,8 +226,8 @@ public: QAccessibleTableHeaderCell(QAbstractItemView *view, int index, Qt::Orientation orientation); QObject *object() const { return 0; } - Role role() const; - State state() const; + QAccessible::Role role() const; + QAccessible::State state() const; QRect rect() const; bool isValid() const; @@ -237,13 +235,13 @@ public: int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } - QString text(Text t) const; - void setText(Text t, const QString &text); + QString text(QAccessible::Text t) const; + void setText(QAccessible::Text t, const QString &text); QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(RelationFlag relation, int index, QAccessibleInterface **iface) const; - Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; + int navigate(QAccessible::RelationFlag relation, int index, QAccessibleInterface **iface) const; + QAccessible::Relation relationTo(int child, const QAccessibleInterface *other, int otherChild) const; private: QAbstractItemView *view; @@ -265,8 +263,8 @@ public: {} QObject *object() const { return 0; } - Role role() const { return QAccessible::Pane; } - State state() const { return QAccessible::Normal; } + QAccessible::Role role() const { return QAccessible::Pane; } + QAccessible::State state() const { return QAccessible::Normal; } QRect rect() const { return QRect(); } bool isValid() const { return true; } @@ -274,8 +272,8 @@ public: int childCount() const { return 0; } int indexOfChild(const QAccessibleInterface *) const { return -1; } - QString text(Text) const { return QString(); } - void setText(Text, const QString &) {} + QString text(QAccessible::Text) const { return QString(); } + void setText(QAccessible::Text, const QString &) {} QAccessibleInterface *parent() const { return QAccessible::queryAccessibleInterface(view); @@ -283,7 +281,7 @@ public: QAccessibleInterface *child(int) const { return 0; } - int navigate(RelationFlag relation, int, QAccessibleInterface **iface) const + int navigate(QAccessible::RelationFlag relation, int, QAccessibleInterface **iface) const { if (relation == QAccessible::Ancestor) { *iface = parent(); @@ -291,7 +289,7 @@ public: } return -1; } - Relation relationTo(int, const QAccessibleInterface *, int) const + QAccessible::Relation relationTo(int, const QAccessibleInterface *, int) const { return QAccessible::Unrelated; } diff --git a/src/plugins/accessible/widgets/main.cpp b/src/plugins/accessible/widgets/main.cpp index af3fb59934..821b219b36 100644 --- a/src/plugins/accessible/widgets/main.cpp +++ b/src/plugins/accessible/widgets/main.cpp @@ -193,41 +193,41 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec #endif #ifndef QT_NO_TOOLBUTTON } else if (classname == QLatin1String("QToolButton")) { - Role role = NoRole; + QAccessible::Role role = QAccessible::NoRole; #ifndef QT_NO_MENU QToolButton *tb = qobject_cast(widget); if (!tb->menu()) - role = tb->isCheckable() ? CheckBox : PushButton; + role = tb->isCheckable() ? QAccessible::CheckBox : QAccessible::PushButton; else if (!tb->popupMode() != QToolButton::DelayedPopup) - role = ButtonDropDown; + role = QAccessible::ButtonDropDown; else #endif - role = ButtonMenu; + role = QAccessible::ButtonMenu; iface = new QAccessibleToolButton(widget, role); #endif // QT_NO_TOOLBUTTON } else if (classname == QLatin1String("QCheckBox")) { - iface = new QAccessibleButton(widget, CheckBox); + iface = new QAccessibleButton(widget, QAccessible::CheckBox); } else if (classname == QLatin1String("QRadioButton")) { - iface = new QAccessibleButton(widget, RadioButton); + iface = new QAccessibleButton(widget, QAccessible::RadioButton); } else if (classname == QLatin1String("QPushButton")) { - Role role = NoRole; + QAccessible::Role role = QAccessible::NoRole; QPushButton *pb = qobject_cast(widget); #ifndef QT_NO_MENU if (pb->menu()) - role = ButtonMenu; + role = QAccessible::ButtonMenu; else #endif if (pb->isCheckable()) - role = CheckBox; + role = QAccessible::CheckBox; else - role = PushButton; + role = QAccessible::PushButton; iface = new QAccessibleButton(widget, role); } else if (classname == QLatin1String("QAbstractButton")) { - iface = new QAccessibleButton(widget, PushButton); + iface = new QAccessibleButton(widget, QAccessible::PushButton); } else if (classname == QLatin1String("QDialog")) { - iface = new QAccessibleWidget(widget, Dialog); + iface = new QAccessibleWidget(widget, QAccessible::Dialog); } else if (classname == QLatin1String("QMessageBox")) { - iface = new QAccessibleWidget(widget, AlertMessage); + iface = new QAccessibleWidget(widget, QAccessible::AlertMessage); #ifndef QT_NO_MAINWINDOW } else if (classname == QLatin1String("QMainWindow")) { iface = new QAccessibleMainWindow(widget); @@ -235,15 +235,15 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec } else if (classname == QLatin1String("QLabel") || classname == QLatin1String("QLCDNumber")) { iface = new QAccessibleDisplay(widget); } else if (classname == QLatin1String("QGroupBox")) { - iface = new QAccessibleDisplay(widget, Grouping); + iface = new QAccessibleDisplay(widget, QAccessible::Grouping); } else if (classname == QLatin1String("QStatusBar")) { - iface = new QAccessibleWidget(widget, StatusBar); + iface = new QAccessibleWidget(widget, QAccessible::StatusBar); #ifndef QT_NO_PROGRESSBAR } else if (classname == QLatin1String("QProgressBar")) { iface = new QAccessibleProgressBar(widget); #endif } else if (classname == QLatin1String("QToolBar")) { - iface = new QAccessibleWidget(widget, ToolBar, widget->windowTitle()); + iface = new QAccessibleWidget(widget, QAccessible::ToolBar, widget->windowTitle()); #ifndef QT_NO_MENUBAR } else if (classname == QLatin1String("QMenuBar")) { iface = new QAccessibleMenuBar(widget); @@ -275,23 +275,23 @@ QAccessibleInterface *AccessibleFactory::create(const QString &classname, QObjec iface = new QAccessibleTabBar(widget); #endif } else if (classname == QLatin1String("QWorkspaceChild")) { - iface = new QAccessibleWidget(widget, Window); + iface = new QAccessibleWidget(widget, QAccessible::Window); } else if (classname == QLatin1String("QSizeGrip")) { - iface = new QAccessibleWidget(widget, Grip); + iface = new QAccessibleWidget(widget, QAccessible::Grip); #ifndef QT_NO_SPLITTER } else if (classname == QLatin1String("QSplitter")) { - iface = new QAccessibleWidget(widget, Splitter); + iface = new QAccessibleWidget(widget, QAccessible::Splitter); } else if (classname == QLatin1String("QSplitterHandle")) { - iface = new QAccessibleWidget(widget, Grip); + iface = new QAccessibleWidget(widget, QAccessible::Grip); #endif #ifndef QT_NO_TEXTEDIT } else if (classname == QLatin1String("QTextEdit")) { iface = new QAccessibleTextEdit(widget); #endif } else if (classname == QLatin1String("QTipLabel")) { - iface = new QAccessibleDisplay(widget, ToolTip); + iface = new QAccessibleDisplay(widget, QAccessible::ToolTip); } else if (classname == QLatin1String("QFrame")) { - iface = new QAccessibleWidget(widget, Border); + iface = new QAccessibleWidget(widget, QAccessible::Border); #ifndef QT_NO_STACKEDWIDGET } else if (classname == QLatin1String("QStackedWidget")) { iface = new QAccessibleStackedWidget(widget); diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.cpp b/src/plugins/accessible/widgets/qaccessiblemenu.cpp index a0622f2a4c..2fe67fedfe 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.cpp +++ b/src/plugins/accessible/widgets/qaccessiblemenu.cpp @@ -79,20 +79,20 @@ int QAccessibleMenu::childAt(int x, int y) const return menu()->actions().indexOf(act) + 1; } -QString QAccessibleMenu::text(Text t) const +QString QAccessibleMenu::text(QAccessible::Text t) const { QString tx = QAccessibleWidget::text(t); if (!tx.isEmpty()) return tx; - if (t == Name) + if (t == QAccessible::Name) return menu()->windowTitle(); return tx; } QAccessible::Role QAccessibleMenu::role() const { - return PopupMenu; + return QAccessible::PopupMenu; } QAccessibleInterface *QAccessibleMenu::child(int index) const @@ -111,14 +111,14 @@ QAccessibleInterface *QAccessibleMenu::parent() const return QAccessibleWidget::parent(); } -int QAccessibleMenu::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleMenu::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { Q_ASSERT(entry >= 0); switch (relation) { - case Child: + case QAccessible::Child: *target = child(entry - 1); return *target ? 0 : -1; - case Ancestor: + case QAccessible::Ancestor: *target = parent(); return *target ? 0 : -1; default: @@ -129,8 +129,8 @@ int QAccessibleMenu::navigate(RelationFlag relation, int entry, QAccessibleInter int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const { int index = -1; - Role r = child->role(); - if ((r == MenuItem || r == Separator) && menu()) { + QAccessible::Role r = child->role(); + if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menu()) { index = menu()->actions().indexOf(qobject_cast(child->object())); if (index != -1) ++index; @@ -140,7 +140,7 @@ int QAccessibleMenu::indexOfChild( const QAccessibleInterface *child) const #ifndef QT_NO_MENUBAR QAccessibleMenuBar::QAccessibleMenuBar(QWidget *w) - : QAccessibleWidget(w, MenuBar) + : QAccessibleWidget(w, QAccessible::MenuBar) { Q_ASSERT(menuBar()); } @@ -162,9 +162,9 @@ QAccessibleInterface *QAccessibleMenuBar::child(int index) const return 0; } -int QAccessibleMenuBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleMenuBar::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { - if (relation == Child) { + if (relation == QAccessible::Child) { *target = child(entry - 1); return *target ? 0 : -1; } @@ -174,8 +174,8 @@ int QAccessibleMenuBar::navigate(RelationFlag relation, int entry, QAccessibleIn int QAccessibleMenuBar::indexOfChild(const QAccessibleInterface *child) const { int index = -1; - Role r = child->role(); - if ((r == MenuItem || r == Separator) && menuBar()) { + QAccessible::Role r = child->role(); + if ((r == QAccessible::MenuItem || r == QAccessible::Separator) && menuBar()) { index = menuBar()->actions().indexOf(qobject_cast(child->object())); if (index != -1) ++index; @@ -214,7 +214,7 @@ int QAccessibleMenuItem::childCount() const int QAccessibleMenuItem::indexOfChild(const QAccessibleInterface * child) const { Q_ASSERT(child == 0); - if (child->role() == PopupMenu && child->object() == m_action->menu()) + if (child->role() == QAccessible::PopupMenu && child->object() == m_action->menu()) return 1; return -1; @@ -237,7 +237,7 @@ QAccessibleInterface *QAccessibleMenuItem::child(int index) const return 0; } -int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleMenuItem::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { *target = 0; if (entry < 0) { @@ -245,26 +245,26 @@ int QAccessibleMenuItem::navigate(RelationFlag relation, int entry, QAccessibleI } switch (relation) { - case Child: + case QAccessible::Child: *target = child(entry - 1); break; - case Ancestor: + case QAccessible::Ancestor: *target = parent(); break; - case Up: - case Down:{ + case QAccessible::Up: + case QAccessible::Down:{ QAccessibleInterface *parentIface = parent(); if (parentIface) { int index = parentIface->indexOfChild(this); if (index != -1) { - index += (relation == Down ? +1 : -1); + index += (relation == QAccessible::Down ? +1 : -1); *target = parentIface->child(index - 1); } } delete parentIface; break; } - case Sibling: { + case QAccessible::Sibling: { QAccessibleInterface *parentIface = parent(); if (parentIface) *target = parentIface->child(entry - 1); @@ -312,59 +312,59 @@ QRect QAccessibleMenuItem::rect() const QAccessible::Relation QAccessibleMenuItem::relationTo(const QAccessibleInterface *other) const { if (other->object() == owner()) { - return Child; + return QAccessible::Child; } Q_UNUSED(other) // ### - return Unrelated; + return QAccessible::Unrelated; } QAccessible::Role QAccessibleMenuItem::role() const { - return m_action->isSeparator() ? Separator : MenuItem; + return m_action->isSeparator() ? QAccessible::Separator : QAccessible::MenuItem; } -void QAccessibleMenuItem::setText ( Text /*t*/, const QString & /*text */) +void QAccessibleMenuItem::setText(QAccessible::Text /*t*/, const QString & /*text */) { } QAccessible::State QAccessibleMenuItem::state() const { - QAccessible::State s = Normal; + QAccessible::State s = QAccessible::Normal; QWidget *own = owner(); if (own->testAttribute(Qt::WA_WState_Visible) == false || m_action->isVisible() == false) { - s |= Invisible; + s |= QAccessible::Invisible; } if (QMenu *menu = qobject_cast(own)) { if (menu->activeAction() == m_action) - s |= Focused; + s |= QAccessible::Focused; #ifndef QT_NO_MENUBAR } else if (QMenuBar *menuBar = qobject_cast(own)) { if (menuBar->activeAction() == m_action) - s |= Focused; + s |= QAccessible::Focused; #endif } if (own->style()->styleHint(QStyle::SH_Menu_MouseTracking)) - s |= HotTracked; + s |= QAccessible::HotTracked; if (m_action->isSeparator() || !m_action->isEnabled()) - s |= Unavailable; + s |= QAccessible::Unavailable; if (m_action->isChecked()) - s |= Checked; + s |= QAccessible::Checked; return s; } -QString QAccessibleMenuItem::text(Text t) const +QString QAccessibleMenuItem::text(QAccessible::Text t) const { QString str; switch (t) { - case Name: + case QAccessible::Name: str = m_action->text(); str = qt_accStripAmp(str); break; - case Accelerator: { + case QAccessible::Accelerator: { #ifndef QT_NO_SHORTCUT QKeySequence key = m_action->shortcut(); if (!key.isEmpty()) { diff --git a/src/plugins/accessible/widgets/qaccessiblemenu.h b/src/plugins/accessible/widgets/qaccessiblemenu.h index a7fda52580..cf6a703b0c 100644 --- a/src/plugins/accessible/widgets/qaccessiblemenu.h +++ b/src/plugins/accessible/widgets/qaccessiblemenu.h @@ -61,11 +61,11 @@ public: int childCount() const; int childAt(int x, int y) const; - QString text(Text t) const; - Role role() const; + QString text(QAccessible::Text t) const; + QAccessible::Role role() const; QAccessibleInterface *child(int index) const; QAccessibleInterface *parent() const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; int indexOfChild( const QAccessibleInterface *child ) const; protected: @@ -81,7 +81,7 @@ public: QAccessibleInterface *child(int index) const; int childCount() const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; int indexOfChild(const QAccessibleInterface *child) const; protected: diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 9dec243dd7..c1cdd7c45d 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -251,7 +251,7 @@ static int qTextBlockPosition(QTextBlock block) Constructs a QAccessibleTextEdit object for a \a widget. */ QAccessibleTextEdit::QAccessibleTextEdit(QWidget *o) -: QAccessibleWidget(o, EditableText) +: QAccessibleWidget(o, QAccessible::EditableText) { Q_ASSERT(widget()->inherits("QTextEdit")); } @@ -262,17 +262,17 @@ QTextEdit *QAccessibleTextEdit::textEdit() const return static_cast(widget()); } -QString QAccessibleTextEdit::text(Text t) const +QString QAccessibleTextEdit::text(QAccessible::Text t) const { - if (t == Value) + if (t == QAccessible::Value) return textEdit()->toPlainText(); return QAccessibleWidget::text(t); } -void QAccessibleTextEdit::setText(Text t, const QString &text) +void QAccessibleTextEdit::setText(QAccessible::Text t, const QString &text) { - if (t != Value) { + if (t != QAccessible::Value) { QAccessibleWidget::setText(t, text); return; } @@ -286,16 +286,16 @@ QVariant QAccessibleTextEdit::invokeMethod(QAccessible::Method method, const QVariantList ¶ms) { switch (method) { - case ListSupportedMethods: { + case QAccessible::ListSupportedMethods: { QSet set; - set << ListSupportedMethods << SetCursorPosition << GetCursorPosition; + set << QAccessible::ListSupportedMethods << QAccessible::SetCursorPosition << QAccessible::GetCursorPosition; return QVariant::fromValue(set | qvariant_cast >( QAccessibleWidget::invokeMethod(method, params))); } - case SetCursorPosition: + case QAccessible::SetCursorPosition: setCursorPosition(params.value(0).toInt()); return true; - case GetCursorPosition: + case QAccessible::GetCursorPosition: return textEdit()->textCursor().position(); default: return QAccessibleWidget::invokeMethod(method, params); @@ -711,7 +711,7 @@ void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QS #ifndef QT_NO_STACKEDWIDGET // ======================= QAccessibleStackedWidget ====================== QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget) - : QAccessibleWidget(widget, LayeredPane) + : QAccessibleWidget(widget, QAccessible::LayeredPane) { Q_ASSERT(qobject_cast(widget)); } @@ -759,10 +759,10 @@ QAccessibleInterface *QAccessibleStackedWidget::child(int index) const return QAccessible::queryAccessibleInterface(stackedWidget()->widget(index)); } -int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleStackedWidget::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { switch (relation) { - case Child: + case QAccessible::Child: *target = child(entry - 1); return *target ? 0 : -1; default: @@ -779,7 +779,7 @@ QStackedWidget *QAccessibleStackedWidget::stackedWidget() const #ifndef QT_NO_TOOLBOX // ======================= QAccessibleToolBox ====================== QAccessibleToolBox::QAccessibleToolBox(QWidget *widget) - : QAccessibleWidget(widget, LayeredPane) + : QAccessibleWidget(widget, QAccessible::LayeredPane) { Q_ASSERT(qobject_cast(widget)); } @@ -793,7 +793,7 @@ QToolBox * QAccessibleToolBox::toolBox() const // ======================= QAccessibleMdiArea ====================== #ifndef QT_NO_MDIAREA QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget) - : QAccessibleWidget(widget, LayeredPane) + : QAccessibleWidget(widget, QAccessible::LayeredPane) { Q_ASSERT(qobject_cast(widget)); } @@ -815,21 +815,21 @@ int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const return -1; } -int QAccessibleMdiArea::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleMdiArea::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { *target = 0; QWidget *targetObject = 0; QList subWindows = mdiArea()->subWindowList(); switch (relation) { - case Child: + case QAccessible::Child: if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count()) return -1; targetObject = subWindows.at(entry - 1); break; - case Up: - case Down: - case Left: - case Right: + case QAccessible::Up: + case QAccessible::Down: + case QAccessible::Left: + case QAccessible::Right: targetObject = mdiAreaNavigate(mdiArea(), relation, entry); break; default: @@ -851,7 +851,7 @@ QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget) Q_ASSERT(qobject_cast(widget)); } -QString QAccessibleMdiSubWindow::text(Text textType) const +QString QAccessibleMdiSubWindow::text(QAccessible::Text textType) const { if (textType == QAccessible::Name) { QString title = mdiSubWindow()->windowTitle(); @@ -861,7 +861,7 @@ QString QAccessibleMdiSubWindow::text(Text textType) const return QAccessibleWidget::text(textType); } -void QAccessibleMdiSubWindow::setText(Text textType, const QString &text) +void QAccessibleMdiSubWindow::setText(QAccessible::Text textType, const QString &text) { if (textType == QAccessible::Name) mdiSubWindow()->setWindowTitle(text); @@ -900,7 +900,7 @@ int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) con return -1; } -int QAccessibleMdiSubWindow::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleMdiSubWindow::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { *target = 0; @@ -910,15 +910,15 @@ int QAccessibleMdiSubWindow::navigate(RelationFlag relation, int entry, QAccessi QWidget *targetObject = 0; QMdiSubWindow *source = mdiSubWindow(); switch (relation) { - case Child: + case QAccessible::Child: if (entry != 1 || !source->widget()) return -1; targetObject = source->widget(); break; - case Up: - case Down: - case Left: - case Right: { + case QAccessible::Up: + case QAccessible::Down: + case QAccessible::Left: + case QAccessible::Right: { if (entry != 0) break; QWidget *parent = source->parentWidget(); @@ -981,7 +981,7 @@ QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const // ======================= QAccessibleWorkspace ====================== #ifndef QT_NO_WORKSPACE QAccessibleWorkspace::QAccessibleWorkspace(QWidget *widget) - : QAccessibleWidget(widget, LayeredPane) + : QAccessibleWidget(widget, QAccessible::LayeredPane) { Q_ASSERT(qobject_cast(widget)); } @@ -1003,21 +1003,21 @@ int QAccessibleWorkspace::indexOfChild(const QAccessibleInterface *child) const return -1; } -int QAccessibleWorkspace::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleWorkspace::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { *target = 0; QWidget *targetObject = 0; QWidgetList subWindows = workspace()->windowList(); switch (relation) { - case Child: + case QAccessible::Child: if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count()) return -1; targetObject = subWindows.at(entry - 1); break; - case Up: - case Down: - case Left: - case Right: + case QAccessible::Up: + case QAccessible::Down: + case QAccessible::Left: + case QAccessible::Right: targetObject = mdiAreaNavigate(workspace(), relation, entry); break; default: @@ -1036,7 +1036,7 @@ QWorkspace *QAccessibleWorkspace::workspace() const #ifndef QT_NO_DIALOGBUTTONBOX // ======================= QAccessibleDialogButtonBox ====================== QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) - : QAccessibleWidget(widget, Grouping) + : QAccessibleWidget(widget, QAccessible::Grouping) { Q_ASSERT(qobject_cast(widget)); } @@ -1063,7 +1063,7 @@ QAccessible::Role QAccessibleTextBrowser::role() const #ifndef QT_NO_CALENDARWIDGET // ===================== QAccessibleCalendarWidget ======================== QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget) - : QAccessibleWidget(widget, Table) + : QAccessibleWidget(widget, QAccessible::Table) { Q_ASSERT(qobject_cast(widget)); } @@ -1093,33 +1093,33 @@ QAccessibleInterface *QAccessibleCalendarWidget::child(int index) const return 0; if (childCount() > 1 && index == 0) - return queryAccessibleInterface(navigationBar()); + return QAccessible::queryAccessibleInterface(navigationBar()); - return queryAccessibleInterface(calendarView()); + return QAccessible::queryAccessibleInterface(calendarView()); } -int QAccessibleCalendarWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleCalendarWidget::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { *target = 0; if (entry <= 0 || entry > childCount()) return QAccessibleWidget::navigate(relation, entry, target); QWidget *targetWidget = 0; switch (relation) { - case Child: + case QAccessible::Child: *target = child(entry - 1); return *target ? 0 : -1; - case Up: + case QAccessible::Up: if (entry == 2) targetWidget = navigationBar(); break; - case Down: + case QAccessible::Down: if (entry == 1 && childCount() == 2) targetWidget = calendarView(); break; default: return QAccessibleWidget::navigate(relation, entry, target); } - *target = queryAccessibleInterface(targetWidget); + *target = QAccessible::queryAccessibleInterface(targetWidget); return *target ? 0 : -1; } @@ -1149,7 +1149,7 @@ QWidget *QAccessibleCalendarWidget::navigationBar() const #ifndef QT_NO_DOCKWIDGET QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget) - : QAccessibleWidget(widget, Window) + : QAccessibleWidget(widget, QAccessible::Window) { } @@ -1172,7 +1172,7 @@ int QAccessibleDockWidget::childCount() const int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const { if (child) { - if (child->role() == TitleBar) { + if (child->role() == QAccessible::TitleBar) { return 1; } else { return 2; //### @@ -1183,7 +1183,7 @@ int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const QAccessible::Role QAccessibleDockWidget::role() const { - return Window; + return QAccessible::Window; } QRect QAccessibleDockWidget::rect() const @@ -1237,13 +1237,13 @@ QAccessibleInterface *QAccessibleTitleBar::child(int index) const return 0; } -int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const +int QAccessibleTitleBar::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **iface) const { switch (relation) { - case Child: + case QAccessible::Child: *iface = child(entry - 1); return *iface ? 0 : -1; - case FocusChild: + case QAccessible::FocusChild: // ### if (entry >= 1) { QDockWidgetLayout *layout = dockWidgetLayout(); @@ -1261,7 +1261,7 @@ int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleI return role > QDockWidgetLayout::FloatButton ? -1 : index; } break; - case Ancestor: + case QAccessible::Ancestor: *iface = parent(); return iface ? 0 : -1; default: @@ -1273,7 +1273,7 @@ int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleI QAccessible::Relation QAccessibleTitleBar::relationTo(const QAccessibleInterface * /*otherChild*/) const { - return Unrelated; //### + return QAccessible::Unrelated; //### } int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const @@ -1293,9 +1293,9 @@ int QAccessibleTitleBar::childCount() const return count; } -QString QAccessibleTitleBar::text(Text t) const +QString QAccessibleTitleBar::text(QAccessible::Text t) const { - if (t == Name || t == Value) { + if (t == QAccessible::Name || t == QAccessible::Value) { return qt_accStripAmp(dockWidget()->windowTitle()); } return QString(); @@ -1303,17 +1303,17 @@ QString QAccessibleTitleBar::text(Text t) const QAccessible::State QAccessibleTitleBar::state() const { - QAccessible::State state = Normal; + QAccessible::State state = QAccessible::Normal; QDockWidget *w = dockWidget(); if (w->testAttribute(Qt::WA_WState_Visible) == false) - state |= Invisible; + state |= QAccessible::Invisible; if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow()) - state |= Focusable; + state |= QAccessible::Focusable; if (w->hasFocus()) - state |= Focused; + state |= QAccessible::Focused; if (!w->isEnabled()) - state |= Unavailable; + state |= QAccessible::Unavailable; return state; } @@ -1418,10 +1418,10 @@ QDockWidget *QAccessibleTitleBar::dockWidget() const QAccessible::Role QAccessibleTitleBar::role() const { - return TitleBar; + return QAccessible::TitleBar; } -void QAccessibleTitleBar::setText(Text /*t*/, const QString &/*text*/) +void QAccessibleTitleBar::setText(QAccessible::Text /*t*/, const QString &/*text*/) { } @@ -1434,7 +1434,7 @@ bool QAccessibleTitleBar::isValid() const #ifndef QT_NO_MAINWINDOW QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget) - : QAccessibleWidget(widget, Window) { } + : QAccessibleWidget(widget, QAccessible::Window) { } QVariant QAccessibleMainWindow::invokeMethod(QAccessible::Method /*method*/, int /*child*/, const QVariantList & /*params*/) { diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index b416469dc6..232293b32a 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -72,8 +72,8 @@ class QAccessibleTextEdit : public QAccessibleWidget, public QAccessibleTextInte public: explicit QAccessibleTextEdit(QWidget *o); - QString text(Text t) const; - void setText(Text t, const QString &text); + QString text(QAccessible::Text t) const; + void setText(QAccessible::Text t, const QString &text); QVariant invokeMethod(QAccessible::Method method, const QVariantList ¶ms); void *interface_cast(QAccessible::InterfaceType t); @@ -126,7 +126,7 @@ public: int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; QAccessibleInterface *child(int index) const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; protected: QStackedWidget *stackedWidget() const; @@ -155,7 +155,7 @@ public: int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; protected: QMdiArea *mdiArea() const; @@ -166,12 +166,12 @@ class QAccessibleMdiSubWindow : public QAccessibleWidget public: explicit QAccessibleMdiSubWindow(QWidget *widget); - QString text(Text textType) const; - void setText(Text textType, const QString &text); - State state() const; + QString text(QAccessible::Text textType) const; + void setText(QAccessible::Text textType, const QString &text); + QAccessible::State state() const; int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; QRect rect() const; int childAt(int x, int y) const; @@ -188,7 +188,7 @@ public: int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; protected: QWorkspace *workspace() const; @@ -209,7 +209,7 @@ class QAccessibleTextBrowser : public QAccessibleTextEdit public: explicit QAccessibleTextBrowser(QWidget *widget); - Role role() const; + QAccessible::Role role() const; }; #endif // QT_NO_TEXTBROWSER @@ -221,7 +221,7 @@ public: int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const; QAccessibleInterface *child(int index) const; @@ -245,7 +245,7 @@ public: int indexOfChild(const QAccessibleInterface *child) const; int childCount() const; QRect rect () const; - Role role() const; + QAccessible::Role role() const; QDockWidget *dockWidget() const; }; @@ -257,15 +257,15 @@ public: QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const; + int navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **iface) const; int indexOfChild(const QAccessibleInterface *child) const; int childCount() const; - Relation relationTo(const QAccessibleInterface *other) const; - void setText(Text t, const QString &text); - QString text(Text t) const; - Role role() const; + QAccessible::Relation relationTo(const QAccessibleInterface *other) const; + void setText(QAccessible::Text t, const QString &text); + QString text(QAccessible::Text t) const; + QAccessible::Role role() const; QRect rect () const; - State state() const; + QAccessible::State state() const; int childAt(int x, int y) const; QObject *object() const; bool isValid() const; diff --git a/src/plugins/accessible/widgets/rangecontrols.cpp b/src/plugins/accessible/widgets/rangecontrols.cpp index 684b45d7c5..06ff8e2cbf 100644 --- a/src/plugins/accessible/widgets/rangecontrols.cpp +++ b/src/plugins/accessible/widgets/rangecontrols.cpp @@ -67,7 +67,7 @@ extern QStyleOptionSlider Q_GUI_EXPORT qt_qsliderStyleOption(QSlider *slider); #ifndef QT_NO_SPINBOX QAccessibleAbstractSpinBox::QAccessibleAbstractSpinBox(QWidget *w) -: QAccessibleWidget(w, SpinBox) +: QAccessibleWidget(w, QAccessible::SpinBox) { Q_ASSERT(abstractSpinBox()); } @@ -80,7 +80,7 @@ QAbstractSpinBox *QAccessibleAbstractSpinBox::abstractSpinBox() const return qobject_cast(object()); } -QString QAccessibleAbstractSpinBox::text(Text t) const +QString QAccessibleAbstractSpinBox::text(QAccessible::Text t) const { if (t == QAccessible::Value) return abstractSpinBox()->text(); @@ -167,9 +167,9 @@ QDoubleSpinBox *QAccessibleDoubleSpinBox::doubleSpinBox() const return static_cast(object()); } -QString QAccessibleDoubleSpinBox::text(Text textType) const +QString QAccessibleDoubleSpinBox::text(QAccessible::Text textType) const { - if (textType == Value) + if (textType == QAccessible::Value) return doubleSpinBox()->textFromValue(doubleSpinBox()->value()); return QAccessibleWidget::text(textType); } @@ -190,7 +190,7 @@ QString QAccessibleDoubleSpinBox::text(Text textType) const \a name is propagated to the QAccessibleWidget constructor. */ QAccessibleScrollBar::QAccessibleScrollBar(QWidget *w) -: QAccessibleAbstractSlider(w, ScrollBar) +: QAccessibleAbstractSlider(w, QAccessible::ScrollBar) { Q_ASSERT(scrollBar()); addControllingSignal(QLatin1String("valueChanged(int)")); @@ -202,9 +202,9 @@ QScrollBar *QAccessibleScrollBar::scrollBar() const return qobject_cast(object()); } -QString QAccessibleScrollBar::text(Text t) const +QString QAccessibleScrollBar::text(QAccessible::Text t) const { - if (t == Value) + if (t == QAccessible::Value) return QString::number(scrollBar()->value()); return QAccessibleAbstractSlider::text(t); } @@ -237,15 +237,15 @@ QSlider *QAccessibleSlider::slider() const return qobject_cast(object()); } -QString QAccessibleSlider::text(Text t) const +QString QAccessibleSlider::text(QAccessible::Text t) const { - if (t == Value) + if (t == QAccessible::Value) return QString::number(slider()->value()); return QAccessibleAbstractSlider::text(t); } -QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, Role r) +QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r) : QAccessibleWidget(w, r) { Q_ASSERT(qobject_cast(w)); @@ -288,15 +288,15 @@ QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const #ifndef QT_NO_DIAL // ======================================= QAccessibleDial ====================================== QAccessibleDial::QAccessibleDial(QWidget *widget) - : QAccessibleAbstractSlider(widget, Dial) + : QAccessibleAbstractSlider(widget, QAccessible::Dial) { Q_ASSERT(qobject_cast(widget)); addControllingSignal(QLatin1String("valueChanged(int)")); } -QString QAccessibleDial::text(Text textType) const +QString QAccessibleDial::text(QAccessible::Text textType) const { - if (textType == Value) + if (textType == QAccessible::Value) return QString::number(dial()->value()); return QAccessibleAbstractSlider::text(textType); diff --git a/src/plugins/accessible/widgets/rangecontrols.h b/src/plugins/accessible/widgets/rangecontrols.h index 59eb8f934a..f6cbcc6900 100644 --- a/src/plugins/accessible/widgets/rangecontrols.h +++ b/src/plugins/accessible/widgets/rangecontrols.h @@ -63,7 +63,7 @@ class QAccessibleAbstractSpinBox: public QAccessibleWidget, public QAccessibleVa public: explicit QAccessibleAbstractSpinBox(QWidget *w); - QString text(Text t) const; + QString text(QAccessible::Text t) const; void *interface_cast(QAccessible::InterfaceType t); // QAccessibleValueInterface @@ -92,7 +92,7 @@ class QAccessibleDoubleSpinBox : public QAccessibleAbstractSpinBox public: explicit QAccessibleDoubleSpinBox(QWidget *widget); - QString text(Text t) const; + QString text(QAccessible::Text t) const; protected: QDoubleSpinBox *doubleSpinBox() const; @@ -102,7 +102,7 @@ protected: class QAccessibleAbstractSlider: public QAccessibleWidget, public QAccessibleValueInterface { public: - explicit QAccessibleAbstractSlider(QWidget *w, Role r = Slider); + explicit QAccessibleAbstractSlider(QWidget *w, QAccessible::Role r = QAccessible::Slider); void *interface_cast(QAccessible::InterfaceType t); // QAccessibleValueInterface @@ -120,7 +120,7 @@ class QAccessibleScrollBar : public QAccessibleAbstractSlider { public: explicit QAccessibleScrollBar(QWidget *w); - QString text(Text t) const; + QString text(QAccessible::Text t) const; protected: QScrollBar *scrollBar() const; @@ -132,7 +132,7 @@ class QAccessibleSlider : public QAccessibleAbstractSlider { public: explicit QAccessibleSlider(QWidget *w); - QString text(Text t) const; + QString text(QAccessible::Text t) const; protected: QSlider *slider() const; @@ -145,7 +145,7 @@ class QAccessibleDial : public QAccessibleAbstractSlider public: explicit QAccessibleDial(QWidget *w); - QString text(Text textType) const; + QString text(QAccessible::Text textType) const; protected: QDial *dial() const; diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 28661f0fc3..8f4fed48fe 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -88,7 +88,7 @@ QString Q_GUI_EXPORT qTextAfterOffsetFromString(int offset, QAccessible2::Bounda Creates a QAccessibleButton object for \a w. \a role is propagated to the QAccessibleWidget constructor. */ -QAccessibleButton::QAccessibleButton(QWidget *w, Role role) +QAccessibleButton::QAccessibleButton(QWidget *w, QAccessible::Role role) : QAccessibleWidget(w, role) { Q_ASSERT(button()); @@ -105,11 +105,11 @@ QAbstractButton *QAccessibleButton::button() const } /*! \reimp */ -QString QAccessibleButton::text(Text t) const +QString QAccessibleButton::text(QAccessible::Text t) const { QString str; switch (t) { - case Accelerator: + case QAccessible::Accelerator: { #ifndef QT_NO_SHORTCUT QPushButton *pb = qobject_cast(object()); @@ -120,7 +120,7 @@ QString QAccessibleButton::text(Text t) const str = qt_accHotKey(button()->text()); } break; - case Name: + case QAccessible::Name: str = widget()->accessibleName(); if (str.isEmpty()) str = button()->text(); @@ -135,23 +135,23 @@ QString QAccessibleButton::text(Text t) const QAccessible::State QAccessibleButton::state() const { - State state = QAccessibleWidget::state(); + QAccessible::State state = QAccessibleWidget::state(); QAbstractButton *b = button(); QCheckBox *cb = qobject_cast(b); if (b->isChecked()) - state |= Checked; + state |= QAccessible::Checked; else if (cb && cb->checkState() == Qt::PartiallyChecked) - state |= Mixed; + state |= QAccessible::Mixed; if (b->isDown()) - state |= Pressed; + state |= QAccessible::Pressed; QPushButton *pb = qobject_cast(b); if (pb) { if (pb->isDefault()) - state |= DefaultButton; + state |= QAccessible::DefaultButton; #ifndef QT_NO_MENU if (pb->menu()) - state |= HasPopup; + state |= QAccessible::HasPopup; #endif } @@ -163,15 +163,15 @@ QStringList QAccessibleButton::actionNames() const QStringList names; if (widget()->isEnabled()) { switch (role()) { - case ButtonMenu: + case QAccessible::ButtonMenu: names << showMenuAction(); break; - case RadioButton: + case QAccessible::RadioButton: names << checkAction(); break; default: if (button()->isCheckable()) { - if (state() & Checked) { + if (state() & QAccessible::Checked) { names << uncheckAction(); } else { // FIXME @@ -235,7 +235,7 @@ QStringList QAccessibleButton::keyBindingsForAction(const QString &actionName) c Creates a QAccessibleToolButton object for \a w. \a role is propagated to the QAccessibleWidget constructor. */ -QAccessibleToolButton::QAccessibleToolButton(QWidget *w, Role role) +QAccessibleToolButton::QAccessibleToolButton(QWidget *w, QAccessible::Role role) : QAccessibleButton(w, role) { Q_ASSERT(toolButton()); @@ -263,10 +263,10 @@ QAccessible::State QAccessibleToolButton::state() const { QAccessible::State st = QAccessibleButton::state(); if (toolButton()->autoRaise()) - st |= HotTracked; + st |= QAccessible::HotTracked; #ifndef QT_NO_MENU if (toolButton()->menu()) - st |= HasPopup; + st |= QAccessible::HasPopup; #endif return st; } @@ -281,7 +281,7 @@ QAccessibleInterface *QAccessibleToolButton::child(int index) const #ifndef QT_NO_MENU if (index == 0 && toolButton()->menu()) { - return queryAccessibleInterface(toolButton()->menu()); + return QAccessible::queryAccessibleInterface(toolButton()->menu()); } #endif return 0; @@ -293,11 +293,11 @@ QAccessibleInterface *QAccessibleToolButton::child(int index) const Returns the button's text label, depending on the text \a t, and the \a child. */ -QString QAccessibleToolButton::text(Text t) const +QString QAccessibleToolButton::text(QAccessible::Text t) const { QString str; switch (t) { - case Name: + case QAccessible::Name: str = toolButton()->accessibleName(); if (str.isEmpty()) str = toolButton()->text(); @@ -362,7 +362,7 @@ void QAccessibleToolButton::doAction(const QString &actionName) Constructs a QAccessibleDisplay object for \a w. \a role is propagated to the QAccessibleWidget constructor. */ -QAccessibleDisplay::QAccessibleDisplay(QWidget *w, Role role) +QAccessibleDisplay::QAccessibleDisplay(QWidget *w, QAccessible::Role role) : QAccessibleWidget(w, role) { } @@ -372,28 +372,28 @@ QAccessible::Role QAccessibleDisplay::role() const QLabel *l = qobject_cast(object()); if (l) { if (l->pixmap()) - return Graphic; + return QAccessible::Graphic; #ifndef QT_NO_PICTURE if (l->picture()) - return Graphic; + return QAccessible::Graphic; #endif #ifndef QT_NO_MOVIE if (l->movie()) - return Animation; + return QAccessible::Animation; #endif #ifndef QT_NO_PROGRESSBAR } else if (qobject_cast(object())) { - return ProgressBar; + return QAccessible::ProgressBar; #endif } return QAccessibleWidget::role(); } -QString QAccessibleDisplay::text(Text t) const +QString QAccessibleDisplay::text(QAccessible::Text t) const { QString str; switch (t) { - case Name: + case QAccessible::Name: str = widget()->accessibleName(); if (str.isEmpty()) { if (qobject_cast(object())) { @@ -413,7 +413,7 @@ QString QAccessibleDisplay::text(Text t) const } } break; - case Value: + case QAccessible::Value: #ifndef QT_NO_PROGRESSBAR if (qobject_cast(object())) str = QString::number(qobject_cast(object())->value()); @@ -429,30 +429,30 @@ QString QAccessibleDisplay::text(Text t) const QAccessible::Relation QAccessibleDisplay::relationTo(const QAccessibleInterface *other) const { - Relation relation = QAccessibleWidget::relationTo(other); + QAccessible::Relation relation = QAccessibleWidget::relationTo(other); QObject *o = other->object(); QLabel *label = qobject_cast(object()); if (label) { #ifndef QT_NO_SHORTCUT if (o == label->buddy()) - relation |= Label; + relation |= QAccessible::Label; #endif #ifndef QT_NO_GROUPBOX } else { QGroupBox *groupbox = qobject_cast(object()); if (groupbox && !groupbox->title().isEmpty()) if (groupbox->children().contains(o)) - relation |= Label; + relation |= QAccessible::Label; #endif } return relation; } -int QAccessibleDisplay::navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const +int QAccessibleDisplay::navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const { *target = 0; - if (rel == Labelled) { + if (rel == QAccessible::Labelled) { QObject *targetObject = 0; QLabel *label = qobject_cast(object()); if (label) { @@ -464,7 +464,7 @@ int QAccessibleDisplay::navigate(RelationFlag rel, int entry, QAccessibleInterfa } else { QGroupBox *groupbox = qobject_cast(object()); if (groupbox && !groupbox->title().isEmpty()) - rel = Child; + rel = QAccessible::Child; #endif } *target = QAccessible::queryAccessibleInterface(targetObject); @@ -537,7 +537,7 @@ QRect QAccessibleDisplay::imagePosition(QAccessible2::CoordinateType coordType) \a name is propagated to the QAccessibleWidget constructor. */ QAccessibleLineEdit::QAccessibleLineEdit(QWidget *w, const QString &name) -: QAccessibleWidget(w, EditableText, name), QAccessibleSimpleEditableTextInterface(this) +: QAccessibleWidget(w, QAccessible::EditableText, name), QAccessibleSimpleEditableTextInterface(this) { addControllingSignal(QLatin1String("textChanged(const QString&)")); addControllingSignal(QLatin1String("returnPressed()")); @@ -549,11 +549,11 @@ QLineEdit *QAccessibleLineEdit::lineEdit() const return qobject_cast(object()); } -QString QAccessibleLineEdit::text(Text t) const +QString QAccessibleLineEdit::text(QAccessible::Text t) const { QString str; switch (t) { - case Value: + case QAccessible::Value: if (lineEdit()->echoMode() == QLineEdit::Normal) str = lineEdit()->text(); break; @@ -565,9 +565,9 @@ QString QAccessibleLineEdit::text(Text t) const return qt_accStripAmp(str); } -void QAccessibleLineEdit::setText(Text t, const QString &text) +void QAccessibleLineEdit::setText(QAccessible::Text t, const QString &text) { - if (t != Value) { + if (t != QAccessible::Value) { QAccessibleWidget::setText(t, text); return; } @@ -583,20 +583,20 @@ void QAccessibleLineEdit::setText(Text t, const QString &text) QAccessible::State QAccessibleLineEdit::state() const { - State state = QAccessibleWidget::state(); + QAccessible::State state = QAccessibleWidget::state(); QLineEdit *l = lineEdit(); if (l->isReadOnly()) - state |= ReadOnly; + state |= QAccessible::ReadOnly; if (l->echoMode() != QLineEdit::Normal) - state |= Protected; - state |= Selectable; + state |= QAccessible::Protected; + state |= QAccessible::Selectable; if (l->hasSelectedText()) - state |= Selected; + state |= QAccessible::Selected; if (l->contextMenuPolicy() != Qt::NoContextMenu && l->contextMenuPolicy() != Qt::PreventContextMenu) - state |= HasPopup; + state |= QAccessible::HasPopup; return state; } @@ -605,16 +605,16 @@ QVariant QAccessibleLineEdit::invokeMethod(QAccessible::Method method, const QVariantList ¶ms) { switch (method) { - case ListSupportedMethods: { + case QAccessible::ListSupportedMethods: { QSet set; - set << ListSupportedMethods << SetCursorPosition << GetCursorPosition; + set << QAccessible::ListSupportedMethods << QAccessible::SetCursorPosition << QAccessible::GetCursorPosition; return QVariant::fromValue(set | qvariant_cast >( QAccessibleWidget::invokeMethod(method, params))); } - case SetCursorPosition: + case QAccessible::SetCursorPosition: setCursorPosition(params.value(0).toInt()); return true; - case GetCursorPosition: + case QAccessible::GetCursorPosition: return cursorPosition(); default: return QAccessibleWidget::invokeMethod(method, params); diff --git a/src/plugins/accessible/widgets/simplewidgets.h b/src/plugins/accessible/widgets/simplewidgets.h index 35fa6ee9b8..40386153be 100644 --- a/src/plugins/accessible/widgets/simplewidgets.h +++ b/src/plugins/accessible/widgets/simplewidgets.h @@ -59,10 +59,10 @@ class QAccessibleButton : public QAccessibleWidget { Q_DECLARE_TR_FUNCTIONS(QAccessibleButton) public: - QAccessibleButton(QWidget *w, Role r); + QAccessibleButton(QWidget *w, QAccessible::Role r); - QString text(Text t) const; - State state() const; + QString text(QAccessible::Text t) const; + QAccessible::State state() const; QStringList actionNames() const; void doAction(const QString &actionName); @@ -76,14 +76,14 @@ protected: class QAccessibleToolButton : public QAccessibleButton { public: - QAccessibleToolButton(QWidget *w, Role role); + QAccessibleToolButton(QWidget *w, QAccessible::Role role); - State state() const; + QAccessible::State state() const; int childCount() const; QAccessibleInterface *child(int index) const; - QString text(Text t) const; + QString text(QAccessible::Text t) const; // QAccessibleActionInterface QStringList actionNames() const; @@ -99,13 +99,13 @@ protected: class QAccessibleDisplay : public QAccessibleWidget, public QAccessibleImageInterface { public: - explicit QAccessibleDisplay(QWidget *w, Role role = StaticText); + explicit QAccessibleDisplay(QWidget *w, QAccessible::Role role = QAccessible::StaticText); - QString text(Text t) const; - Role role() const; + QString text(QAccessible::Text t) const; + QAccessible::Role role() const; - Relation relationTo(const QAccessibleInterface *other) const; - int navigate(RelationFlag, int entry, QAccessibleInterface **target) const; + QAccessible::Relation relationTo(const QAccessibleInterface *other) const; + int navigate(QAccessible::RelationFlag, int entry, QAccessibleInterface **target) const; void *interface_cast(QAccessible::InterfaceType t); // QAccessibleImageInterface @@ -121,9 +121,9 @@ class QAccessibleLineEdit : public QAccessibleWidget, public QAccessibleTextInte public: explicit QAccessibleLineEdit(QWidget *o, const QString &name = QString()); - QString text(Text t) const; - void setText(Text t, const QString &text); - State state() const; + QString text(QAccessible::Text t) const; + void setText(QAccessible::Text t, const QString &text); + QAccessible::State state() const; QVariant invokeMethod(QAccessible::Method method, const QVariantList ¶ms); void *interface_cast(QAccessible::InterfaceType t); diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp index d9ec92cda7..08db058e10 100644 --- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp +++ b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.cpp @@ -52,6 +52,10 @@ QT_BEGIN_NAMESPACE QTouchEventSenderQPA::QTouchEventSenderQPA(const QString &spec) { m_forceToActiveWindow = spec.split(QLatin1Char(':')).contains(QLatin1String("force_window")); + m_device = new QTouchDevice; + m_device->setType(QTouchDevice::TouchScreen); + m_device->setCapabilities(QTouchDevice::Position | QTouchDevice::Area); + QWindowSystemInterface::registerTouchDevice(m_device); } void QTouchEventSenderQPA::touch_configure(int x_min, int x_max, int y_min, int y_max) @@ -103,7 +107,7 @@ void QTouchEventSenderQPA::touch_point(QEvent::Type state, #endif } - QWindowSystemInterface::handleTouchEvent(0, state, QTouchEvent::TouchScreen, touchPoints); + QWindowSystemInterface::handleTouchEvent(0, state, m_device, touchPoints); } QT_END_NAMESPACE diff --git a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h index 91a6b4f3bb..b6e1613b24 100644 --- a/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h +++ b/src/plugins/generic/touchscreen/qtoucheventsenderqpa.h @@ -48,6 +48,8 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE +class QTouchDevice; + class QTouchEventSenderQPA : public QTouchScreenObserver { public: @@ -61,6 +63,7 @@ private: int hw_range_x_max; int hw_range_y_min; int hw_range_y_max; + QTouchDevice *m_device; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoacursor.h b/src/plugins/platforms/cocoa/qcocoacursor.h index bb48da7ecb..dd66185f70 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.h +++ b/src/plugins/platforms/cocoa/qcocoacursor.h @@ -55,7 +55,7 @@ public: explicit QCocoaCursor(QPlatformScreen *); virtual void changeCursor(QCursor * widgetCursor, QWindow * widget); - virtual QPoint pos(); + virtual QPoint pos() const; virtual void setPos(const QPoint &position); private: QHash m_cursors; diff --git a/src/plugins/platforms/cocoa/qcocoacursor.mm b/src/plugins/platforms/cocoa/qcocoacursor.mm index 70e3fb8c63..67386c78e1 100644 --- a/src/plugins/platforms/cocoa/qcocoacursor.mm +++ b/src/plugins/platforms/cocoa/qcocoacursor.mm @@ -113,7 +113,7 @@ void QCocoaCursor::changeCursor(QCursor *cursor, QWindow *window) } } -QPoint QCocoaCursor::pos() +QPoint QCocoaCursor::pos() const { return qt_mac_flipPoint([NSEvent mouseLocation]).toPoint(); } diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 5311eaff83..1852173b5b 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -93,7 +93,6 @@ private: QPlatformFontDatabase *mFontDb; QAbstractEventDispatcher *mEventDispatcher; - QCocoaAutoReleasePool *mPool; QPlatformAccessibility *mAccessibility; QPlatformTheme *mPlatformTheme; }; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 445f67f1e7..6d7770fecc 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -90,8 +90,6 @@ QCocoaIntegration::QCocoaIntegration() : mFontDb(new QCoreTextFontDatabase()) , mEventDispatcher(new QCocoaEventDispatcher()) { - mPool = new QCocoaAutoReleasePool; - qApp->setAttribute(Qt::AA_DontUseNativeMenuBar, false); NSApplication *cocoaApplication = [NSApplication sharedApplication]; @@ -141,7 +139,6 @@ QCocoaIntegration::QCocoaIntegration() QCocoaIntegration::~QCocoaIntegration() { delete mAccessibility; - delete mPool; } bool QCocoaIntegration::hasCapability(QPlatformIntegration::Capability cap) const diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 7c9873a908..4ae268dda5 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -54,6 +54,8 @@ #include #endif +static QTouchDevice *touchDevice = 0; + @interface NSEvent (Qt_Compile_Leopard_DeviceDelta) - (CGFloat)deviceDeltaX; - (CGFloat)deviceDeltaY; @@ -69,6 +71,12 @@ m_cgImage = 0; m_window = 0; m_buttons = Qt::NoButton; + if (!touchDevice) { + touchDevice = new QTouchDevice; + touchDevice->setType(QTouchDevice::TouchPad); + touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(touchDevice); + } } return self; } @@ -287,28 +295,28 @@ { const NSTimeInterval timestamp = [event timestamp]; const QList points = QCocoaTouch::getCurrentTouchPointList(event, /*acceptSingleTouch= ### true or false?*/false); - QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchBegin, QTouchEvent::TouchPad, points); + QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchBegin, touchDevice, points); } - (void)touchesMovedWithEvent:(NSEvent *)event { const NSTimeInterval timestamp = [event timestamp]; const QList points = QCocoaTouch::getCurrentTouchPointList(event, /*acceptSingleTouch= ### true or false?*/false); - QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchUpdate, QTouchEvent::TouchPad, points); + QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchUpdate, touchDevice, points); } - (void)touchesEndedWithEvent:(NSEvent *)event { const NSTimeInterval timestamp = [event timestamp]; const QList points = QCocoaTouch::getCurrentTouchPointList(event, /*acceptSingleTouch= ### true or false?*/false); - QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchEnd, QTouchEvent::TouchPad, points); + QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchEnd, touchDevice, points); } - (void)touchesCancelledWithEvent:(NSEvent *)event { const NSTimeInterval timestamp = [event timestamp]; const QList points = QCocoaTouch::getCurrentTouchPointList(event, /*acceptSingleTouch= ### true or false?*/false); - QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchEnd, QTouchEvent::TouchPad, points); + QWindowSystemInterface::handleTouchEvent(m_window, timestamp * 1000, QEvent::TouchEnd, touchDevice, points); } #ifndef QT_NO_WHEELEVENT diff --git a/src/plugins/platforms/directfb/qdirectfb_egl.cpp b/src/plugins/platforms/directfb/qdirectfb_egl.cpp index 399e90a9fb..958a3be5e3 100644 --- a/src/plugins/platforms/directfb/qdirectfb_egl.cpp +++ b/src/plugins/platforms/directfb/qdirectfb_egl.cpp @@ -48,6 +48,7 @@ #include #include +#include #include @@ -158,6 +159,20 @@ QDirectFbWindowEGL::~QDirectFbWindowEGL() } } +EGLSurface QDirectFbWindowEGL::eglSurface() +{ + if (m_eglSurface == EGL_NO_SURFACE) { + QDirectFbScreenEGL *dfbScreen = static_cast(screen()); + EGLConfig config = q_configFromGLFormat(dfbScreen->eglDisplay(), format(), true); + m_eglSurface = eglCreateWindowSurface(dfbScreen->eglDisplay(), config, dfbSurface(), NULL); + + if (m_eglSurface == EGL_NO_SURFACE) + eglGetError(); + } + + return m_eglSurface; +} + QSurfaceFormat QDirectFbWindowEGL::format() const { return window()->requestedFormat(); diff --git a/src/plugins/platforms/directfb/qdirectfbscreen.h b/src/plugins/platforms/directfb/qdirectfbscreen.h index b719146c90..b9d53beaa5 100644 --- a/src/plugins/platforms/directfb/qdirectfbscreen.h +++ b/src/plugins/platforms/directfb/qdirectfbscreen.h @@ -43,6 +43,7 @@ #define QDIRECTFBSCREEN_H #include "qdirectfbconvenience.h" +#include "qdirectfbcursor.h" #include @@ -50,7 +51,6 @@ QT_BEGIN_NAMESPACE -class QDirectFBCursor; class QDirectFbScreen : public QPlatformScreen { diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp index 3ac4b24f1e..a2b6aa8d68 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp +++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp @@ -124,7 +124,8 @@ static inline void compressMouseMove(MSG *msg) */ QWindowsMouseHandler::QWindowsMouseHandler() : - m_windowUnderMouse(0) + m_windowUnderMouse(0), + m_touchDevice(0) { } @@ -277,10 +278,17 @@ bool QWindowsMouseHandler::translateTouchEvent(QWindow *window, HWND, if ((allStates & Qt::TouchPointStateMask) == Qt::TouchPointReleased) m_touchInputIDToTouchPointID.clear(); + if (!m_touchDevice) { + m_touchDevice = new QTouchDevice; + m_touchDevice->setType(QTouchDevice::TouchScreen); + m_touchDevice->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(m_touchDevice); + } + // TODO: Device used to be hardcoded to screen in previous code. // What is the correct event type? Which parts of translateRawTouchEvent() are required? QWindowSystemInterface::handleTouchEvent(window, QEvent::TouchBegin, - QTouchEvent::TouchScreen, + m_touchDevice, touchPoints); return true; } diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.h b/src/plugins/platforms/windows/qwindowsmousehandler.h index 8d62becb74..178936e2ec 100644 --- a/src/plugins/platforms/windows/qwindowsmousehandler.h +++ b/src/plugins/platforms/windows/qwindowsmousehandler.h @@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE class QWindow; +class QTouchDevice; class QWindowsMouseHandler { @@ -76,6 +77,7 @@ private: QPointer m_windowUnderMouse; QHash m_touchInputIDToTouchPointID; + QTouchDevice *m_touchDevice; }; Qt::MouseButtons QWindowsMouseHandler::keyStateToMouseButtons(int wParam) diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 550a5e4184..de41f862bd 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -65,13 +65,21 @@ QGLXContext::QGLXContext(QXcbScreen *screen, const QSurfaceFormat &format, QPlat , m_screen(screen) , m_context(0) { - GLXContext shareGlxContext = 0; + m_shareContext = 0; if (share) - shareGlxContext = static_cast(share)->glxContext(); + m_shareContext = static_cast(share)->glxContext(); GLXFBConfig config = qglx_findConfig(DISPLAY_FROM_XCB(screen),screen->screenNumber(),format); - m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, shareGlxContext, TRUE); - m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); + + m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, m_shareContext, TRUE); + if (!m_context && m_shareContext) { + // re-try without a shared glx context + m_shareContext = 0; + m_context = glXCreateNewContext(DISPLAY_FROM_XCB(screen), config, GLX_RGBA_TYPE, 0, TRUE); + } + + if (m_context) + m_format = qglx_surfaceFormatFromGLXFBConfig(DISPLAY_FROM_XCB(screen), config, m_context); } QGLXContext::~QGLXContext() @@ -137,4 +145,14 @@ QSurfaceFormat QGLXContext::format() const return m_format; } +bool QGLXContext::isSharing() const +{ + return m_shareContext != 0; +} + +bool QGLXContext::isValid() const +{ + return m_context != 0; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/xcb/qglxintegration.h b/src/plugins/platforms/xcb/qglxintegration.h index 2c8fea5874..211a654c03 100644 --- a/src/plugins/platforms/xcb/qglxintegration.h +++ b/src/plugins/platforms/xcb/qglxintegration.h @@ -66,12 +66,15 @@ public: void (*getProcAddress(const QByteArray &procName)) (); QSurfaceFormat format() const; + bool isSharing() const; + bool isValid() const; GLXContext glxContext() const { return m_context; } private: QXcbScreen *m_screen; GLXContext m_context; + GLXContext m_shareContext; QSurfaceFormat m_format; }; diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index a5b8aa9a35..6969124b2a 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -86,6 +86,11 @@ extern "C" { QT_BEGIN_NAMESPACE +static int nullErrorHandler(Display *, XErrorEvent *) +{ + return 0; +} + QXcbConnection::QXcbConnection(const char *displayName) : m_displayName(displayName ? QByteArray(displayName) : qgetenv("DISPLAY")) #ifdef XCB_USE_XINPUT2_MAEMO @@ -106,6 +111,7 @@ QXcbConnection::QXcbConnection(const char *displayName) m_primaryScreen = DefaultScreen(dpy); m_connection = XGetXCBConnection(dpy); XSetEventQueueOwner(dpy, XCBOwnsEventQueue); + XSetErrorHandler(nullErrorHandler); m_xlib_display = dpy; #ifdef XCB_USE_EGL EGLDisplay eglDisplay = eglGetDisplay(dpy); @@ -1002,7 +1008,6 @@ void QXcbConnection::initializeXFixes() xfixes_first_event = 0; } free(xfixes_query); - } void QXcbConnection::initializeXRender() diff --git a/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp b/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp index 327f7c54f6..719fc85ae2 100644 --- a/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection_maemo.cpp @@ -62,6 +62,7 @@ struct XInput2Data { , xideviceinfo(0) , xibuttonclassinfo(0) , xiMaxContacts(0) + , qtTouchDevice(0) { } // true if Qt is compiled w/ XInput2 or Tablet support and we have a tablet. @@ -74,6 +75,7 @@ struct XInput2Data { XIButtonClassInfo *xibuttonclassinfo; int xiMaxContacts; QList allTouchPoints; + QTouchDevice *qtTouchDevice; }; bool QXcbConnection::isUsingXInput2() @@ -277,8 +279,17 @@ void QXcbConnection::handleGenericEvent(xcb_ge_event_t *event) if (!(active & (1 << i)) && touchPoints.at(i).state != Qt::TouchPointReleased) touchPoints[i].state = Qt::TouchPointReleased; - if (QXcbWindow *platformWindow = platformWindowFromId(xideviceevent->event)) - QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xideviceevent->time, (QEvent::Type)0 /*None*/, QTouchEvent::TouchScreen, touchPoints); + if (QXcbWindow *platformWindow = platformWindowFromId(xideviceevent->event)) { + QTouchDevice *dev = m_xinputData->qtTouchDevice; + if (!dev) { + dev = new QTouchDevice; + dev->setType(QTouchDevice::TouchScreen); + dev->setCapabilities(QTouchDevice::Position | QTouchDevice::Area | QTouchDevice::Pressure | QTouchDevice::NormalizedPosition); + QWindowSystemInterface::registerTouchDevice(dev); + m_xinputData->qtTouchDevice = dev; + } + QWindowSystemInterface::handleTouchEvent(platformWindow->window(), xideviceevent->time, (QEvent::Type)0 /*None*/, dev, touchPoints); + } if (xideviceevent->evtype == XI_ButtonRelease) { // final event, forget touch state diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index a2a519c793..581693ccb7 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -239,6 +239,9 @@ #define XF86XK_TopMenu 0x1008FFA2 #define XF86XK_Suspend 0x1008FFA7 #define XF86XK_Hibernate 0x1008FFA8 +#define XF86XK_TouchpadToggle 0x1008FFA9 +#define XF86XK_TouchpadOn 0x1008FFB0 +#define XF86XK_TouchpadOff 0x1008FFB1 // end of XF86keysyms.h @@ -549,6 +552,9 @@ static const unsigned int KeyTbl[] = { XF86XK_Bluetooth, Qt::Key_Bluetooth, XF86XK_Suspend, Qt::Key_Suspend, XF86XK_Hibernate, Qt::Key_Hibernate, + XF86XK_TouchpadToggle, Qt::Key_TouchpadToggle, + XF86XK_TouchpadOn, Qt::Key_TouchpadOn, + XF86XK_TouchpadOff, Qt::Key_TouchpadOff, XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly XF86XK_Launch1, Qt::Key_Launch3, XF86XK_Launch2, Qt::Key_Launch4, diff --git a/src/plugins/platforms/xlib/qxlibkeyboard.cpp b/src/plugins/platforms/xlib/qxlibkeyboard.cpp index 66e48fec93..1d3dc83464 100644 --- a/src/plugins/platforms/xlib/qxlibkeyboard.cpp +++ b/src/plugins/platforms/xlib/qxlibkeyboard.cpp @@ -236,6 +236,9 @@ #define XF86XK_TopMenu 0x1008FFA2 #define XF86XK_Suspend 0x1008FFA7 #define XF86XK_Hibernate 0x1008FFA8 +#define XF86XK_TouchpadToggle 0x1008FFA9 +#define XF86XK_TouchpadOn 0x1008FFB0 +#define XF86XK_TouchpadOff 0x1008FFB1 // end of XF86keysyms.h @@ -544,6 +547,9 @@ static const unsigned int KeyTbl[] = { XF86XK_Bluetooth, Qt::Key_Bluetooth, XF86XK_Suspend, Qt::Key_Suspend, XF86XK_Hibernate, Qt::Key_Hibernate, + XF86XK_TouchpadToggle, Qt::Key_TouchpadToggle, + XF86XK_TouchpadOn, Qt::Key_TouchpadOn, + XF86XK_TouchpadOff, Qt::Key_TouchpadOff, XF86XK_Launch0, Qt::Key_Launch2, // ### Qt 5: remap properly XF86XK_Launch1, Qt::Key_Launch3, XF86XK_Launch2, Qt::Key_Launch4, diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp index 252ebd1bd9..03d58667d4 100644 --- a/src/printsupport/kernel/qprinter.cpp +++ b/src/printsupport/kernel/qprinter.cpp @@ -1652,6 +1652,8 @@ QRect QPrinter::paperRect() const This function sets the \a left, \a top, \a right and \a bottom page margins for this printer. The unit of the margins are specified with the \a unit parameter. + + \sa getPageMargins */ void QPrinter::setPageMargins(qreal left, qreal top, qreal right, qreal bottom, QPrinter::Unit unit) { @@ -1683,6 +1685,8 @@ void QPrinter::setMargins(const Margins &m) Returns the page margins for this printer in \a left, \a top, \a right, \a bottom. The unit of the returned margins are specified with the \a unit parameter. + + \sa setPageMargins */ void QPrinter::getPageMargins(qreal *left, qreal *top, qreal *right, qreal *bottom, QPrinter::Unit unit) const { diff --git a/src/src.pro b/src/src.pro index fcaf478646..0f7a380984 100644 --- a/src/src.pro +++ b/src/src.pro @@ -65,6 +65,7 @@ src_platformsupport.target = sub-platformsupport src_declarative.depends += src_opengl src_webkit.depends += src_opengl } + src_v8.depends += src_tools_mkv8snapshot } diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 742161be04..b37dbc0203 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1927,10 +1927,6 @@ FatalSignalHandler::~FatalSignalHandler() test that was executed with qExec() can't run another test via qExec() and threads are not allowed to call qExec() simultaneously. - If you have programatically created the arguments, as opposed to getting them - from the arguments in \c main(), it is likely of interest to use - QTest::qExec(QObject *, const QStringList &) since it is Unicode safe. - \sa QTEST_MAIN() */ @@ -2040,30 +2036,6 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) return qMin(QTestResult::failCount(), 127); } -/*! - \overload - \since 4.4 - - Behaves identically to qExec(QObject *, int, char**) but takes a - QStringList of \a arguments instead of a \c char** list. - */ -int QTest::qExec(QObject *testObject, const QStringList &arguments) -{ - const int argc = arguments.count(); - QVarLengthArray argv(argc); - - QVector args; - args.reserve(argc); - - for (int i = 0; i < argc; ++i) - { - args.append(arguments.at(i).toLocal8Bit().constData()); - argv[i] = args.last().data(); - } - - return qExec(testObject, argc, argv.data()); -} - /*! \internal */ void QTest::qFail(const char *statementStr, const char *file, int line) diff --git a/src/testlib/qtestcase.h b/src/testlib/qtestcase.h index dffbedab8e..091e9a8d96 100644 --- a/src/testlib/qtestcase.h +++ b/src/testlib/qtestcase.h @@ -180,7 +180,6 @@ namespace QTest Q_TESTLIB_EXPORT char *toString(const void *); Q_TESTLIB_EXPORT int qExec(QObject *testObject, int argc = 0, char **argv = 0); - Q_TESTLIB_EXPORT int qExec(QObject *testObject, const QStringList &arguments); Q_TESTLIB_EXPORT bool qVerify(bool statement, const char *statementStr, const char *description, const char *file, int line); diff --git a/src/testlib/qtesttouch.h b/src/testlib/qtesttouch.h index bee1566d22..6a9909b617 100644 --- a/src/testlib/qtesttouch.h +++ b/src/testlib/qtesttouch.h @@ -64,7 +64,7 @@ QT_MODULE(Test) #ifdef QT_WIDGETS_LIB extern Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, - QTouchEvent::DeviceType deviceType, + QTouchDevice *device, const QList &touchPoints, ulong timestamp); #endif @@ -136,13 +136,13 @@ namespace QTest if (!points.isEmpty()) { if (targetWindow) { - QWindowSystemInterface::handleTouchEvent(targetWindow,QEvent::None,deviceType, touchPointList(points.values())); + QWindowSystemInterface::handleTouchEvent(targetWindow,QEvent::None, device, touchPointList(points.values())); QTest::qWait(10); } #ifdef QT_WIDGETS_LIB else if (targetWidget) { - qt_translateRawTouchEvent(targetWidget, deviceType, points.values(), 0); + qt_translateRawTouchEvent(targetWidget, device, points.values(), 0); } #endif } @@ -152,17 +152,17 @@ namespace QTest private: #ifdef QT_WIDGETS_LIB - QTouchEventSequence(QWidget *widget, QTouchEvent::DeviceType aDeviceType) - : targetWidget(widget), targetWindow(0), deviceType(aDeviceType) + QTouchEventSequence(QWidget *widget, QTouchDevice *aDevice) + : targetWidget(widget), targetWindow(0), device(aDevice) { } #endif - QTouchEventSequence(QWindow *window, QTouchEvent::DeviceType aDeviceType) + QTouchEventSequence(QWindow *window, QTouchDevice *aDevice) : #ifdef QT_WIDGETS_LIB targetWidget(0), #endif - targetWindow(window), deviceType(aDeviceType) + targetWindow(window), device(aDevice) { } @@ -226,26 +226,26 @@ namespace QTest QWidget *targetWidget; #endif QWindow *targetWindow; - QTouchEvent::DeviceType deviceType; + QTouchDevice *device; #ifdef QT_WIDGETS_LIB - friend QTouchEventSequence touchEvent(QWidget *, QTouchEvent::DeviceType); + friend QTouchEventSequence touchEvent(QWidget *, QTouchDevice*); #endif - friend QTouchEventSequence touchEvent(QWindow *, QTouchEvent::DeviceType); + friend QTouchEventSequence touchEvent(QWindow *, QTouchDevice*); }; #ifdef QT_WIDGETS_LIB inline - QTouchEventSequence touchEvent(QWidget *widget = 0, - QTouchEvent::DeviceType deviceType = QTouchEvent::TouchScreen) + QTouchEventSequence touchEvent(QWidget *widget, + QTouchDevice *device) { - return QTouchEventSequence(widget, deviceType); + return QTouchEventSequence(widget, device); } #endif inline - QTouchEventSequence touchEvent(QWindow *window = 0, - QTouchEvent::DeviceType deviceType = QTouchEvent::TouchScreen) + QTouchEventSequence touchEvent(QWindow *window, + QTouchDevice *device) { - return QTouchEventSequence(window, deviceType); + return QTouchEventSequence(window, device); } } diff --git a/src/tools/mkv8snapshot/mkv8snapshot.pro b/src/tools/mkv8snapshot/mkv8snapshot.pro index 8070b5426b..cd2b20456a 100644 --- a/src/tools/mkv8snapshot/mkv8snapshot.pro +++ b/src/tools/mkv8snapshot/mkv8snapshot.pro @@ -33,3 +33,6 @@ SOURCES += \ unix:LIBS += -lpthread # We don't need to install this tool, it's only used for building v8. +# However we do have to make sure that 'make install' builds it. +dummytarget.CONFIG = dummy_install +INSTALLS += dummytarget diff --git a/src/tools/uic/qclass_lib_map.h b/src/tools/uic/qclass_lib_map.h index 094dcd28e2..5ad6a4a12c 100644 --- a/src/tools/uic/qclass_lib_map.h +++ b/src/tools/uic/qclass_lib_map.h @@ -820,7 +820,6 @@ QT_CLASS_LIB(QPlatformWindowFormat, QtGui, qplatformwindowformat_qpa.h) QT_CLASS_LIB(QSessionManager, QtGui, qsessionmanager.h) QT_CLASS_LIB(QShortcut, QtWidgets, qshortcut.h) QT_CLASS_LIB(QSizePolicy, QtWidgets, qsizepolicy.h) -QT_CLASS_LIB(QSound, QtWidgets, qsound.h) QT_CLASS_LIB(QStackedLayout, QtWidgets, qstackedlayout.h) QT_CLASS_LIB(QToolTip, QtWidgets, qtooltip.h) QT_CLASS_LIB(QWhatsThis, QtWidgets, qwhatsthis.h) diff --git a/src/widgets/Qt5WidgetsMacros.cmake b/src/widgets/Qt5WidgetsMacros.cmake index cf9682f62c..7ebc7e6673 100644 --- a/src/widgets/Qt5WidgetsMacros.cmake +++ b/src/widgets/Qt5WidgetsMacros.cmake @@ -36,30 +36,20 @@ # ###################################### -include(MacroAddFileDependencies) - -MACRO (QT5_EXTRACT_OPTIONS _qt5_files _qt5_options) - SET(${_qt5_files}) - SET(${_qt5_options}) - SET(_QT5_DOING_OPTIONS FALSE) - FOREACH(_currentArg ${ARGN}) - IF ("${_currentArg}" STREQUAL "OPTIONS") - SET(_QT5_DOING_OPTIONS TRUE) - ELSE ("${_currentArg}" STREQUAL "OPTIONS") - IF(_QT5_DOING_OPTIONS) - LIST(APPEND ${_qt5_options} "${_currentArg}") - ELSE(_QT5_DOING_OPTIONS) - LIST(APPEND ${_qt5_files} "${_currentArg}") - ENDIF(_QT5_DOING_OPTIONS) - ENDIF ("${_currentArg}" STREQUAL "OPTIONS") - ENDFOREACH(_currentArg) -ENDMACRO (QT5_EXTRACT_OPTIONS) +include(CMakeParseArguments) # QT5_WRAP_UI(outfiles inputfile ... ) MACRO (QT5_WRAP_UI outfiles ) - QT5_EXTRACT_OPTIONS(ui_files ui_options ${ARGN}) + set(options) + set(oneValueArgs) + set(multiValueArgs OPTIONS) + + cmake_parse_arguments(_WRAP_UI "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + set(ui_files ${_WRAP_UI_UNPARSED_ARGUMENTS}) + set(ui_options ${_WRAP_UI_OPTIONS}) FOREACH (it ${ui_files}) GET_FILENAME_COMPONENT(outfile ${it} NAME_WE) @@ -68,7 +58,7 @@ MACRO (QT5_WRAP_UI outfiles ) ADD_CUSTOM_COMMAND(OUTPUT ${outfile} COMMAND ${QT_UIC_EXECUTABLE} ARGS ${ui_options} -o ${outfile} ${infile} - MAIN_DEPENDENCY ${infile}) + MAIN_DEPENDENCY ${infile} VERBATIM) SET(${outfiles} ${${outfiles}} ${outfile}) ENDFOREACH (it) diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 30b21d3146..a1c53e934e 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -178,7 +178,7 @@ public: \a role and \a name are optional parameters that set the object's role and name properties. */ -QAccessibleWidget::QAccessibleWidget(QWidget *w, Role role, const QString &name) +QAccessibleWidget::QAccessibleWidget(QWidget *w, QAccessible::Role role, const QString &name) : QAccessibleObject(w) { Q_ASSERT(widget()); @@ -350,7 +350,7 @@ static inline bool isAncestor(const QObject *obj, const QObject *child) /*! \reimp */ QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface *other) const { - Relation relation = Unrelated; + QAccessible::Relation relation = QAccessible::Unrelated; if (d->asking == this) // recursive call return relation; @@ -360,12 +360,12 @@ QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface * QWidget *focus = widget()->focusWidget(); if (object() == focus && isAncestor(o, focus)) - relation |= FocusChild; + relation |= QAccessible::FocusChild; QACConnectionObject *connectionObject = (QACConnectionObject*)object(); for (int sig = 0; sig < d->primarySignals.count(); ++sig) { if (connectionObject->isSender(o, d->primarySignals.at(sig).toAscii())) { - relation |= Controller; + relation |= QAccessible::Controller; break; } } @@ -375,21 +375,21 @@ QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface * int inverse = other->relationTo(this); d->asking = 0; - if (inverse & Controller) - relation |= Controlled; - if (inverse & Label) - relation |= Labelled; + if (inverse & QAccessible::Controller) + relation |= QAccessible::Controlled; + if (inverse & QAccessible::Label) + relation |= QAccessible::Labelled; if(o == object()) { - return relation | Self; + return relation | QAccessible::Self; } QObject *parent = object()->parent(); if (o == parent) - return relation | Child; + return relation | QAccessible::Child; if (o->parent() == parent) { - relation |= Sibling; + relation |= QAccessible::Sibling; QAccessibleInterface *sibIface = QAccessible::queryAccessibleInterface(o); Q_ASSERT(sibIface); QRect wg = rect(); @@ -397,7 +397,7 @@ QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface * if (wg.intersects(sg)) { QAccessibleInterface *pIface = 0; pIface = sibIface->parent(); - if (pIface && !((sibIface->state() | state()) & Invisible)) { + if (pIface && !((sibIface->state() | state()) & QAccessible::Invisible)) { int wi = pIface->indexOfChild(this); int si = pIface->indexOfChild(sibIface); @@ -425,9 +425,9 @@ QAccessible::Relation QAccessibleWidget::relationTo(const QAccessibleInterface * } if (isAncestor(o, object())) - return relation | Descendent; + return relation | QAccessible::Descendent; if (isAncestor(object(), o)) - return relation | Ancestor; + return relation | QAccessible::Ancestor; return relation; } @@ -449,7 +449,7 @@ QAccessibleInterface *QAccessibleWidget::child(int index) const } /*! \reimp */ -int QAccessibleWidget::navigate(RelationFlag relation, int entry, +int QAccessibleWidget::navigate(QAccessible::RelationFlag relation, int entry, QAccessibleInterface **target) const { if (!target) @@ -460,18 +460,18 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, switch (relation) { // Hierarchical - case Self: + case QAccessible::Self: targetObject = object(); break; - case Child: + case QAccessible::Child: qWarning() << "QAccessibleWidget::navigate is deprecated for QAccessible::Child in:" << object()->metaObject()->className(); *target = child(entry - 1); return *target ? 0 : -1; - case Ancestor: + case QAccessible::Ancestor: qWarning() << "QAccessibleWidget::navigate is deprecated for QAccessible::Ancestor in:" << object()->metaObject()->className(); *target = parent(); return *target ? 0 : -1; - case Sibling: + case QAccessible::Sibling: { QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(parentObject()); if (!iface) @@ -506,7 +506,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface *sibling = 0; sibling = pIface->child(i); Q_ASSERT(sibling); - if ((relationTo(sibling) & Self) || (sibling->state() & QAccessible::Invisible)) { + if ((relationTo(sibling) & QAccessible::Self) || (sibling->state() & QAccessible::Invisible)) { //ignore ourself and invisible siblings delete sibling; continue; @@ -573,7 +573,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, return 0; } break; - case Covers: + case QAccessible::Covers: if (entry > 0) { QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject()); if (!pIface) @@ -584,7 +584,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface *sibling = 0; for (int i = pIface->indexOfChild(this) + 1; i <= sibCount && entry; ++i) { sibling = pIface->child(i - 1); - if (!sibling || (sibling->state() & Invisible)) { + if (!sibling || (sibling->state() & QAccessible::Invisible)) { delete sibling; sibling = 0; continue; @@ -602,7 +602,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, return 0; } break; - case Covered: + case QAccessible::Covered: if (entry > 0) { QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject()); if (!pIface) @@ -614,7 +614,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, for (int i = 1; i < index && entry; ++i) { sibling = pIface->child(i - 1); Q_ASSERT(sibling); - if (!sibling || (sibling->state() & Invisible)) { + if (!sibling || (sibling->state() & QAccessible::Invisible)) { delete sibling; sibling = 0; continue; @@ -634,7 +634,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, break; // Logical - case FocusChild: + case QAccessible::FocusChild: { if (widget()->hasFocus()) { targetObject = object(); @@ -657,7 +657,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, */ } break; - case Label: + case QAccessible::Label: if (entry > 0) { QAccessibleInterface *pIface = QAccessible::queryAccessibleInterface(parentObject()); if (!pIface) @@ -671,7 +671,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, for (int i = 0; i < sibCount && entry; ++i) { candidate = pIface->child(i); Q_ASSERT(candidate); - if (candidate->relationTo(this) & Label) + if (candidate->relationTo(this) & QAccessible::Label) --entry; if (!entry) break; @@ -680,7 +680,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, candidate = 0; } if (!candidate) { - if (pIface->relationTo(this) & Label) + if (pIface->relationTo(this) & QAccessible::Label) --entry; if (!entry) candidate = pIface; @@ -693,9 +693,9 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, return 0; } break; - case Labelled: // only implemented in subclasses + case QAccessible::Labelled: // only implemented in subclasses break; - case Controller: + case QAccessible::Controller: if (entry > 0) { // check all senders we are connected to, // and figure out which one are controllers to us @@ -707,7 +707,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface *candidate = QAccessible::queryAccessibleInterface(sender); if (!candidate) continue; - if (candidate->relationTo(this) & Controller) + if (candidate->relationTo(this) & QAccessible::Controller) senders << sender; delete candidate; } @@ -715,7 +715,7 @@ int QAccessibleWidget::navigate(RelationFlag relation, int entry, targetObject = senders.at(entry-1); } break; - case Controlled: + case QAccessible::Controlled: if (entry > 0) { QObjectList allReceivers; QACConnectionObject *connectionObject = (QACConnectionObject*)object(); @@ -756,12 +756,12 @@ int QAccessibleWidget::indexOfChild(const QAccessibleInterface *child) const extern QString qt_setWindowTitle_helperHelper(const QString &, const QWidget*); /*! \reimp */ -QString QAccessibleWidget::text(Text t) const +QString QAccessibleWidget::text(QAccessible::Text t) const { QString str; switch (t) { - case Name: + case QAccessible::Name: if (!d->name.isEmpty()) { str = d->name; } else if (!widget()->accessibleName().isEmpty()) { @@ -775,7 +775,7 @@ QString QAccessibleWidget::text(Text t) const str = qt_accStripAmp(buddyString(widget())); } break; - case Description: + case QAccessible::Description: if (!d->description.isEmpty()) str = d->description; else if (!widget()->accessibleDescription().isEmpty()) @@ -785,7 +785,7 @@ QString QAccessibleWidget::text(Text t) const str = widget()->toolTip(); #endif break; - case Help: + case QAccessible::Help: if (!d->help.isEmpty()) str = d->help; #ifndef QT_NO_WHATSTHIS @@ -793,13 +793,13 @@ QString QAccessibleWidget::text(Text t) const str = widget()->whatsThis(); #endif break; - case Accelerator: + case QAccessible::Accelerator: if (!d->accelerator.isEmpty()) str = d->accelerator; else str = qt_accHotKey(buddyString(widget())); break; - case Value: + case QAccessible::Value: str = d->value; break; default: @@ -844,22 +844,22 @@ QAccessible::Role QAccessibleWidget::role() const /*! \reimp */ QAccessible::State QAccessibleWidget::state() const { - QAccessible::State state = Normal; + QAccessible::State state = QAccessible::Normal; QWidget *w = widget(); if (w->testAttribute(Qt::WA_WState_Visible) == false) - state |= Invisible; + state |= QAccessible::Invisible; if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow()) - state |= Focusable; + state |= QAccessible::Focusable; if (w->hasFocus()) - state |= Focused; + state |= QAccessible::Focused; if (!w->isEnabled()) - state |= Unavailable; + state |= QAccessible::Unavailable; if (w->isWindow()) { if (w->windowFlags() & Qt::WindowSystemMenuHint) - state |= Movable; + state |= QAccessible::Movable; if (w->minimumSize() != w->maximumSize()) - state |= Sizeable; + state |= QAccessible::Sizeable; } return state; diff --git a/src/widgets/accessible/qaccessiblewidget.h b/src/widgets/accessible/qaccessiblewidget.h index cc86c46581..b807dbc088 100644 --- a/src/widgets/accessible/qaccessiblewidget.h +++ b/src/widgets/accessible/qaccessiblewidget.h @@ -57,23 +57,23 @@ class QAccessibleWidgetPrivate; class Q_WIDGETS_EXPORT QAccessibleWidget : public QAccessibleObject, public QAccessibleActionInterface { public: - explicit QAccessibleWidget(QWidget *o, Role r = Client, const QString& name = QString()); + explicit QAccessibleWidget(QWidget *o, QAccessible::Role r = QAccessible::Client, const QString& name = QString()); QWindow *window() const; int childCount() const; int indexOfChild(const QAccessibleInterface *child) const; - Relation relationTo(const QAccessibleInterface *other) const; + QAccessible::Relation relationTo(const QAccessibleInterface *other) const; int childAt(int x, int y) const; QRect rect() const; QAccessibleInterface *parent() const; QAccessibleInterface *child(int index) const; - int navigate(RelationFlag rel, int entry, QAccessibleInterface **target) const; + int navigate(QAccessible::RelationFlag rel, int entry, QAccessibleInterface **target) const; - QString text(Text t) const; - Role role() const; - State state() const; + QString text(QAccessible::Text t) const; + QAccessible::Role role() const; + QAccessible::State state() const; QColor foregroundColor() const; QColor backgroundColor() const; diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 1eaaf79bf5..1803cba01d 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -1966,12 +1966,6 @@ void QColorDialog::open(QObject *receiver, const char *member) \sa QDialog::open() */ -/* - For Symbian color dialogs -*/ -#ifdef Q_WS_S60 -extern QColor qtSymbianGetColor(const QColor &initial); -#endif /*! \since 4.5 @@ -1981,19 +1975,10 @@ extern QColor qtSymbianGetColor(const QColor &initial); QColor::isValid()) color if the user cancels the dialog. The \a options argument allows you to customize the dialog. - - On Symbian, this static function will use the native color dialog and not a QColorDialog. - On Symbian the parameters \a title and \a parent has no relevance and the - \a options parameter is only used to define if the native color dialog is - used or not. */ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QString &title, ColorDialogOptions options) { -#ifdef Q_WS_S60 - if (!(options & DontUseNativeDialog)) - return qtSymbianGetColor(initial); -#endif QColorDialog dlg(parent); if (!title.isEmpty()) dlg.setWindowTitle(title); @@ -2003,25 +1988,6 @@ QColor QColorDialog::getColor(const QColor &initial, QWidget *parent, const QStr return dlg.selectedColor(); } -/*! - Pops up a modal color dialog, lets the user choose a color, and - returns that color. The color is initially set to \a initial. The - dialog is a child of \a parent. It returns an invalid (see - QColor::isValid()) color if the user cancels the dialog. - - On Symbian, this static function will use the native - color dialog and not a QColorDialog. -*/ - -QColor QColorDialog::getColor(const QColor &initial, QWidget *parent) -{ -#ifdef Q_WS_S60 - return qtSymbianGetColor(initial); -#endif - return getColor(initial, parent, QString(), ColorDialogOptions(0)); -} - - /*! \obsolete diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h index fa217c76bf..1d21c06f99 100644 --- a/src/widgets/dialogs/qcolordialog.h +++ b/src/widgets/dialogs/qcolordialog.h @@ -95,10 +95,10 @@ public: void setVisible(bool visible); - // ### Qt 5: merge overloads with title = QString() - static QColor getColor(const QColor &initial, QWidget *parent, const QString &title, + static QColor getColor(const QColor &initial = Qt::white, + QWidget *parent = 0, + const QString &title = QString(), ColorDialogOptions options = 0); - static QColor getColor(const QColor &initial = Qt::white, QWidget *parent = 0); // obsolete static QRgb getRgba(QRgb rgba = 0xffffffff, bool *ok = 0, QWidget *parent = 0); diff --git a/src/widgets/graphicsview/qgraphicsscene.cpp b/src/widgets/graphicsview/qgraphicsscene.cpp index f99b72ffd0..791f25aa27 100644 --- a/src/widgets/graphicsview/qgraphicsscene.cpp +++ b/src/widgets/graphicsview/qgraphicsscene.cpp @@ -5808,7 +5808,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) // update state QGraphicsItem *item = 0; if (touchPoint.state() == Qt::TouchPointPressed) { - if (sceneTouchEvent->deviceType() == QTouchEvent::TouchPad) { + if (sceneTouchEvent->device()->type() == QTouchDevice::TouchPad) { // on touch-pad devices, send all touch points to the same item item = itemForTouchPointId.isEmpty() ? 0 @@ -5823,7 +5823,7 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) item = cachedItemsUnderMouse.isEmpty() ? 0 : cachedItemsUnderMouse.first(); } - if (sceneTouchEvent->deviceType() == QTouchEvent::TouchScreen) { + if (sceneTouchEvent->device()->type() == QTouchDevice::TouchScreen) { // on touch-screens, combine this touch point with the closest one we find int closestTouchPointId = findClosestTouchPointId(touchPoint.scenePos()); QGraphicsItem *closestItem = itemForTouchPointId.value(closestTouchPointId); @@ -5889,10 +5889,12 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) QTouchEvent touchEvent(eventType); touchEvent.setWidget(sceneTouchEvent->widget()); - touchEvent.setDeviceType(sceneTouchEvent->deviceType()); + touchEvent.setDevice(sceneTouchEvent->device()); touchEvent.setModifiers(sceneTouchEvent->modifiers()); touchEvent.setTouchPointStates(it.value().first); touchEvent.setTouchPoints(it.value().second); + touchEvent.setTimestamp(sceneTouchEvent->timestamp()); + touchEvent.setWindow(sceneTouchEvent->window()); switch (touchEvent.type()) { case QEvent::TouchBegin: diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 8c99ed4b5a..06544e3146 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -3499,6 +3499,16 @@ void QAbstractItemViewPrivate::_q_layoutChanged() #endif } +void QAbstractItemViewPrivate::_q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int) +{ + _q_layoutChanged(); +} + +void QAbstractItemViewPrivate::_q_columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int) +{ + _q_layoutChanged(); +} + /*! This slot is called when the selection is changed. The previous selection (which may be empty), is specified by \a deselected, and the diff --git a/src/widgets/itemviews/qabstractitemview.h b/src/widgets/itemviews/qabstractitemview.h index ae0c0369e5..25501e67c5 100644 --- a/src/widgets/itemviews/qabstractitemview.h +++ b/src/widgets/itemviews/qabstractitemview.h @@ -357,6 +357,8 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_columnsInserted(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_rowsInserted(const QModelIndex&, int, int)) Q_PRIVATE_SLOT(d_func(), void _q_rowsRemoved(const QModelIndex&, int, int)) + Q_PRIVATE_SLOT(d_func(), void _q_columnsMoved(const QModelIndex&, int, int, const QModelIndex&, int)) + Q_PRIVATE_SLOT(d_func(), void _q_rowsMoved(const QModelIndex&, int, int, const QModelIndex&, int)) Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged()) diff --git a/src/widgets/itemviews/qabstractitemview_p.h b/src/widgets/itemviews/qabstractitemview_p.h index e1cda31915..031e325cff 100644 --- a/src/widgets/itemviews/qabstractitemview_p.h +++ b/src/widgets/itemviews/qabstractitemview_p.h @@ -114,6 +114,9 @@ public: virtual void _q_columnsInserted(const QModelIndex &parent, int start, int end); virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); + virtual void _q_rowsMoved(const QModelIndex &source, int sourceStart, int sourceEnd, const QModelIndex &destination, int destinationStart); + virtual void _q_columnsMoved(const QModelIndex &source, int sourceStart, int sourceEnd, const QModelIndex &destination, int destinationStart); + void _q_headerDataChanged() { doDelayedItemsLayout(); } void _q_scrollerStateChanged(); diff --git a/src/widgets/itemviews/qidentityproxymodel.cpp b/src/widgets/itemviews/qidentityproxymodel.cpp index 7885aedabb..c891565794 100644 --- a/src/widgets/itemviews/qidentityproxymodel.cpp +++ b/src/widgets/itemviews/qidentityproxymodel.cpp @@ -51,16 +51,12 @@ QT_BEGIN_NAMESPACE class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate { QIdentityProxyModelPrivate() - : ignoreNextLayoutAboutToBeChanged(false), - ignoreNextLayoutChanged(false) { } Q_DECLARE_PUBLIC(QIdentityProxyModel) - bool ignoreNextLayoutAboutToBeChanged; - bool ignoreNextLayoutChanged; QList layoutChangePersistentIndexes; QModelIndexList proxyIndexes; @@ -481,9 +477,6 @@ void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orie void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged() { - if (ignoreNextLayoutAboutToBeChanged) - return; - Q_Q(QIdentityProxyModel); foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) { @@ -499,9 +492,6 @@ void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged() void QIdentityProxyModelPrivate::_q_sourceLayoutChanged() { - if (ignoreNextLayoutChanged) - return; - Q_Q(QIdentityProxyModel); for (int i = 0; i < proxyIndexes.size(); ++i) { diff --git a/src/widgets/itemviews/qitemselectionmodel.cpp b/src/widgets/itemviews/qitemselectionmodel.cpp index 996b12f805..08470a4300 100644 --- a/src/widgets/itemviews/qitemselectionmodel.cpp +++ b/src/widgets/itemviews/qitemselectionmodel.cpp @@ -565,6 +565,14 @@ void QItemSelectionModelPrivate::initModel(QAbstractItemModel *model) q, SLOT(_q_rowsAboutToBeInserted(QModelIndex,int,int))); QObject::connect(model, SIGNAL(columnsAboutToBeInserted(QModelIndex,int,int)), q, SLOT(_q_columnsAboutToBeInserted(QModelIndex,int,int))); + QObject::connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), + q, SLOT(_q_layoutAboutToBeChanged())); + QObject::connect(model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), + q, SLOT(_q_layoutAboutToBeChanged())); + QObject::connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + q, SLOT(_q_layoutChanged())); + QObject::connect(model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + q, SLOT(_q_layoutChanged())); QObject::connect(model, SIGNAL(layoutAboutToBeChanged()), q, SLOT(_q_layoutAboutToBeChanged())); QObject::connect(model, SIGNAL(layoutChanged()), diff --git a/src/widgets/itemviews/qsortfilterproxymodel.cpp b/src/widgets/itemviews/qsortfilterproxymodel.cpp index f8d5dcb302..f29ad7bc57 100644 --- a/src/widgets/itemviews/qsortfilterproxymodel.cpp +++ b/src/widgets/itemviews/qsortfilterproxymodel.cpp @@ -207,8 +207,8 @@ public: void _q_sourceAboutToBeReset(); void _q_sourceReset(); - void _q_sourceLayoutAboutToBeChanged(); - void _q_sourceLayoutChanged(); + void _q_sourceLayoutAboutToBeChanged(const QList &sourceParents); + void _q_sourceLayoutChanged(const QList &sourceParents); void _q_sourceRowsAboutToBeInserted(const QModelIndex &source_parent, int start, int end); @@ -218,6 +218,12 @@ public: int start, int end); void _q_sourceRowsRemoved(const QModelIndex &source_parent, int start, int end); + void _q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); + void _q_sourceRowsMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); void _q_sourceColumnsAboutToBeInserted(const QModelIndex &source_parent, int start, int end); void _q_sourceColumnsInserted(const QModelIndex &source_parent, @@ -226,6 +232,12 @@ public: int start, int end); void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end); + void _q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); + void _q_sourceColumnsMoved(const QModelIndex &sourceParent, + int sourceStart, int sourceEnd, + const QModelIndex &destParent, int dest); void _q_clearMapping(); @@ -1235,21 +1247,40 @@ void QSortFilterProxyModelPrivate::_q_sourceReset() sort(); } -void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged() +void QSortFilterProxyModelPrivate::_q_sourceLayoutAboutToBeChanged(const QList &sourceParents) { Q_Q(QSortFilterProxyModel); saved_persistent_indexes.clear(); - emit q->layoutAboutToBeChanged(); + + QList parents; + foreach (const QPersistentModelIndex &parent, sourceParents) { + if (!parent.isValid()) { + parents << QModelIndex(); + continue; + } + const QModelIndex mappedParent = q->mapFromSource(parent); + // Might be filtered out. + if (mappedParent.isValid()) + parents << mappedParent; + } + + // All parents filtered out. + if (!sourceParents.isEmpty() && parents.isEmpty()) + return; + + emit q->layoutAboutToBeChanged(parents); if (persistent.indexes.isEmpty()) return; saved_persistent_indexes = store_persistent_indexes(); } -void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged() +void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged(const QList &sourceParents) { Q_Q(QSortFilterProxyModel); + // Optimize: We only actually have to clear the mapping related to the contents of + // sourceParents, not everything. qDeleteAll(source_index_mapping); source_index_mapping.clear(); @@ -1262,7 +1293,21 @@ void QSortFilterProxyModelPrivate::_q_sourceLayoutChanged() source_index_mapping.clear(); } - emit q->layoutChanged(); + QList parents; + foreach (const QPersistentModelIndex &parent, sourceParents) { + if (!parent.isValid()) { + parents << QModelIndex(); + continue; + } + const QModelIndex mappedParent = q->mapFromSource(parent); + if (mappedParent.isValid()) + parents << mappedParent; + } + + if (!sourceParents.isEmpty() && parents.isEmpty()) + return; + + emit q->layoutChanged(parents); } void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeInserted( @@ -1299,6 +1344,54 @@ void QSortFilterProxyModelPrivate::_q_sourceRowsRemoved( source_items_removed(source_parent, start, end, Qt::Vertical); } +void QSortFilterProxyModelPrivate::_q_sourceRowsAboutToBeMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + // Because rows which are contiguous in the source model might not be contiguous + // in the proxy due to sorting, the best thing we can do here is be specific about what + // parents are having their children changed. + // Optimize: Emit move signals if the proxy is not sorted. Will need to account for rows + // being filtered out though. + + saved_persistent_indexes.clear(); + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutAboutToBeChanged(parents); + if (persistent.indexes.isEmpty()) + return; + saved_persistent_indexes = store_persistent_indexes(); +} + +void QSortFilterProxyModelPrivate::_q_sourceRowsMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + + // Optimize: We only need to clear and update the persistent indexes which are children of + // sourceParent or destParent + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + + update_persistent_indexes(saved_persistent_indexes); + saved_persistent_indexes.clear(); + + if (dynamic_sortfilter && update_source_sort_column()) { + //update_source_sort_column might have created wrong mapping so we have to clear it again + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + } + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutChanged(parents); +} + void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeInserted( const QModelIndex &source_parent, int start, int end) { @@ -1355,6 +1448,47 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved( proxy_sort_column = q->mapFromSource(model->index(0,source_sort_column, source_parent)).column(); } +void QSortFilterProxyModelPrivate::_q_sourceColumnsAboutToBeMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + + saved_persistent_indexes.clear(); + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutAboutToBeChanged(parents); + + if (persistent.indexes.isEmpty()) + return; + saved_persistent_indexes = store_persistent_indexes(); +} + +void QSortFilterProxyModelPrivate::_q_sourceColumnsMoved( + const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_Q(QSortFilterProxyModel); + + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + + update_persistent_indexes(saved_persistent_indexes); + saved_persistent_indexes.clear(); + + if (dynamic_sortfilter && update_source_sort_column()) { + qDeleteAll(source_index_mapping); + source_index_mapping.clear(); + } + + QList parents; + parents << q->mapFromSource(sourceParent); + if (sourceParent != destParent) + parents << q->mapFromSource(destParent); + emit q->layoutChanged(parents); +} + /*! \since 4.1 \class QSortFilterProxyModel @@ -1576,11 +1710,23 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int))); - disconnect(d->model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); + disconnect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - disconnect(d->model, SIGNAL(layoutChanged()), - this, SLOT(_q_sourceLayoutChanged())); + disconnect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))); + + disconnect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + + disconnect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))); + + disconnect(d->model, SIGNAL(layoutAboutToBeChanged(QList)), + this, SLOT(_q_sourceLayoutAboutToBeChanged(QList))); + + disconnect(d->model, SIGNAL(layoutChanged(QList)), + this, SLOT(_q_sourceLayoutChanged(QList))); disconnect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); disconnect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); @@ -1617,11 +1763,23 @@ void QSortFilterProxyModel::setSourceModel(QAbstractItemModel *sourceModel) connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)), this, SLOT(_q_sourceColumnsRemoved(QModelIndex,int,int))); - connect(d->model, SIGNAL(layoutAboutToBeChanged()), - this, SLOT(_q_sourceLayoutAboutToBeChanged())); + connect(d->model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); - connect(d->model, SIGNAL(layoutChanged()), - this, SLOT(_q_sourceLayoutChanged())); + connect(d->model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int))); + + connect(d->model, SIGNAL(columnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + + connect(d->model, SIGNAL(columnsMoved(QModelIndex,int,int,QModelIndex,int)), + this, SLOT(_q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int))); + + connect(d->model, SIGNAL(layoutAboutToBeChanged(QList)), + this, SLOT(_q_sourceLayoutAboutToBeChanged(QList))); + + connect(d->model, SIGNAL(layoutChanged(QList)), + this, SLOT(_q_sourceLayoutChanged(QList))); connect(d->model, SIGNAL(modelAboutToBeReset()), this, SLOT(_q_sourceAboutToBeReset())); connect(d->model, SIGNAL(modelReset()), this, SLOT(_q_sourceReset())); diff --git a/src/widgets/itemviews/qsortfilterproxymodel.h b/src/widgets/itemviews/qsortfilterproxymodel.h index 68d92be841..bbeec1470c 100644 --- a/src/widgets/itemviews/qsortfilterproxymodel.h +++ b/src/widgets/itemviews/qsortfilterproxymodel.h @@ -179,16 +179,20 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceAboutToBeReset()) Q_PRIVATE_SLOT(d_func(), void _q_sourceReset()) - Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged()) - Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged(const QList &sourceParents)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged(const QList &sourceParents)) Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(const QModelIndex &source_parent, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &source_parent, int start, int end)) Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(const QModelIndex &source_parent, int start, int end)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)) Q_PRIVATE_SLOT(d_func(), void _q_clearMapping()) }; diff --git a/src/widgets/kernel/kernel.pri b/src/widgets/kernel/kernel.pri index 7f10c24bb0..1f27602466 100644 --- a/src/widgets/kernel/kernel.pri +++ b/src/widgets/kernel/kernel.pri @@ -107,7 +107,6 @@ false:!x11:mac { OBJECTIVE_SOURCES += \ kernel/qcursor_mac.mm \ kernel/qdnd_mac.mm \ - kernel/qsound_mac.mm \ kernel/qapplication_mac.mm \ kernel/qwidget_mac.mm \ kernel/qcocoapanel_mac.mm \ diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 472f19a3c1..afd5fb70e1 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -5214,7 +5214,7 @@ int QApplicationPrivate::findClosestTouchPointId(const QPointF &screenPos) } void QApplicationPrivate::translateRawTouchEvent(QWidget *window, - QTouchEvent::DeviceType deviceType, + QTouchDevice *device, const QList &touchPoints, ulong timestamp) { @@ -5234,7 +5234,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, switch (touchPoint.state()) { case Qt::TouchPointPressed: { - if (deviceType == QTouchEvent::TouchPad) { + if (device->type() == QTouchDevice::TouchPad) { // on touch-pads, send all touch points to the same widget widget = d->widgetForTouchPointId.isEmpty() ? QWeakPointer() @@ -5252,7 +5252,7 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, widget = window; } - if (deviceType == QTouchEvent::TouchScreen) { + if (device->type() == QTouchDevice::TouchScreen) { int closestTouchPointId = d->findClosestTouchPointId(touchPoint.screenPos()); QWidget *closestWidget = d->widgetForTouchPointId.value(closestTouchPointId).data(); if (closestWidget @@ -5348,12 +5348,13 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, } QTouchEvent touchEvent(eventType, - deviceType, + device, QApplication::keyboardModifiers(), it.value().first, it.value().second); updateTouchPointsForWidget(widget, &touchEvent); touchEvent.setTimestamp(timestamp); + touchEvent.setWindow(window->windowHandle()); switch (touchEvent.type()) { case QEvent::TouchBegin: @@ -5376,11 +5377,11 @@ void QApplicationPrivate::translateRawTouchEvent(QWidget *window, } Q_WIDGETS_EXPORT void qt_translateRawTouchEvent(QWidget *window, - QTouchEvent::DeviceType deviceType, + QTouchDevice *device, const QList &touchPoints, ulong timestamp) { - QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints, timestamp); + QApplicationPrivate::translateRawTouchEvent(window, device, touchPoints, timestamp); } #ifndef QT_NO_GESTURES diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h index 7b663608f7..3841cef62f 100644 --- a/src/widgets/kernel/qapplication_p.h +++ b/src/widgets/kernel/qapplication_p.h @@ -83,6 +83,7 @@ class QInputContext; class QObject; class QWidget; class QSocketNotifier; +class QTouchDevice; #ifndef QT_NO_GESTURES class QGestureManager; #endif @@ -482,7 +483,7 @@ public: void appendTouchPoint(const QTouchEvent::TouchPoint &touchPoint); void removeTouchPoint(int touchPointId); static void translateRawTouchEvent(QWidget *widget, - QTouchEvent::DeviceType deviceType, + QTouchDevice *device, const QList &touchPoints, ulong timestamp); @@ -554,8 +555,9 @@ private: }; Q_WIDGETS_EXPORT void qt_translateRawTouchEvent(QWidget *window, - QTouchEvent::DeviceType deviceType, - const QList &touchPoints); + QTouchDevice *device, + const QList &touchPoints, + ulong timestamp); #if defined(Q_WS_WIN) extern void qt_win_set_cursor(QWidget *, bool); diff --git a/src/widgets/kernel/qsound.cpp b/src/widgets/kernel/qsound.cpp deleted file mode 100644 index c6ab9809fb..0000000000 --- a/src/widgets/kernel/qsound.cpp +++ /dev/null @@ -1,367 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qsound.h" - -#ifndef QT_NO_SOUND - -#include "qlist.h" -#include -#include "qsound_p.h" - -QT_BEGIN_NAMESPACE - -static QList *servers=0; - -QAuServer::QAuServer(QObject* parent) - : QObject(parent) -{ - if (!servers) - servers = new QList; - servers->prepend(this); -} - -QAuServer::~QAuServer() -{ - servers->removeAll(this); - if (servers->count() == 0) { - delete servers; - servers = 0; - } -} - -void QAuServer::play(const QString& filename) -{ - QSound s(filename); - play(&s); -} - -extern QAuServer* qt_new_audio_server(); - -static QAuServer& server() -{ - if (!servers) qt_new_audio_server(); - return *servers->first(); -} - -class QSoundPrivate : public QObjectPrivate -{ -public: - QSoundPrivate(const QString& fname) - : filename(fname), bucket(0), looprem(0), looptotal(1) - { - } - - ~QSoundPrivate() - { - delete bucket; - } - - QString filename; - QAuBucket* bucket; - int looprem; - int looptotal; -}; - -/*! - \class QSound - \brief The QSound class provides access to the platform audio facilities. - - \ingroup multimedia - \inmodule QtWidgets - - Qt provides the most commonly required audio operation in GUI - applications: asynchronously playing a sound file. This is most - easily accomplished using the static play() function: - - \snippet doc/src/snippets/code/src_gui_kernel_qsound.cpp 0 - - Alternatively, create a QSound object from the sound file first - and then call the play() slot: - - \snippet doc/src/snippets/code/src_gui_kernel_qsound.cpp 1 - - Once created a QSound object can be queried for its fileName() and - total number of loops() (i.e. the number of times the sound will - play). The number of repetitions can be altered using the - setLoops() function. While playing the sound, the loopsRemaining() - function returns the remaining number of repetitions. Use the - isFinished() function to determine whether the sound has finished - playing. - - Sounds played using a QSound object may use more memory than the - static play() function, but it may also play more immediately - (depending on the underlying platform audio facilities). Use the - static isAvailable() function to determine whether sound - facilities exist on the platform. Which facilities that are - actually used varies: - - \table - \header \o Platform \o Audio Facility - \row - \o Microsoft Windows - \o The underlying multimedia system is used; only WAVE format sound files - are supported. - \row - \o X11 - \o The \l{ftp://ftp.x.org/contrib/audio/nas/}{Network Audio System} - is used if available, otherwise all operations work silently. NAS - supports WAVE and AU files. - \row - \o Mac OS X - \o NSSound is used. All formats that NSSound supports, including QuickTime formats, - are supported by Qt for Mac OS X. - \row - \o Qt for Embedded Linux - \o A built-in mixing sound server is used, accessing \c /dev/dsp - directly. Only the WAVE format is supported. - \row - \o Symbian - \o CMdaAudioPlayerUtility is used. All formats that Symbian OS or devices support - are supported also by Qt. - \endtable - - Note that QSound does not support \l{resources.html}{resources}. - This might be fixed in a future Qt version. -*/ - -/*! - Plays the sound stored in the file specified by the given \a filename. - - \sa stop(), loopsRemaining(), isFinished() -*/ -void QSound::play(const QString& filename) -{ - server().play(filename); -} - -/*! - Constructs a QSound object from the file specified by the given \a - filename and with the given \a parent. - - This may use more memory than the static play() function, but it - may also play more immediately (depending on the underlying - platform audio facilities). - - \sa play() -*/ -QSound::QSound(const QString& filename, QObject* parent) - : QObject(*new QSoundPrivate(filename), parent) -{ - server().init(this); -} - -/*! - Destroys this sound object. If the sound is not finished playing, - the stop() function is called before the sound object is - destructed. - - \sa stop(), isFinished() -*/ -QSound::~QSound() -{ - if (!isFinished()) - stop(); -} - -/*! - Returns true if the sound has finished playing; otherwise returns false. - - \warning On Windows this function always returns true for unlooped sounds. -*/ -bool QSound::isFinished() const -{ - Q_D(const QSound); - return d->looprem == 0; -} - -/*! - \overload - - Starts playing the sound specified by this QSound object. - - The function returns immediately. Depending on the platform audio - facilities, other sounds may stop or be mixed with the new - sound. The sound can be played again at any time, possibly mixing - or replacing previous plays of the sound. - - \sa fileName() -*/ -void QSound::play() -{ - Q_D(QSound); - d->looprem = d->looptotal; - server().play(this); -} - -/*! - Returns the number of times the sound will play. - - \sa loopsRemaining(), setLoops() -*/ -int QSound::loops() const -{ - Q_D(const QSound); - return d->looptotal; -} - -/*! - Returns the remaining number of times the sound will loop (this - value decreases each time the sound is played). - - \sa loops(), isFinished() -*/ -int QSound::loopsRemaining() const -{ - Q_D(const QSound); - return d->looprem; -} - -/*! - \fn void QSound::setLoops(int number) - - Sets the sound to repeat the given \a number of times when it is - played. - - Note that passing the value -1 will cause the sound to loop - indefinitely. - - \sa loops() -*/ -void QSound::setLoops(int n) -{ - Q_D(QSound); - d->looptotal = n; -} - -/*! - Returns the filename associated with this QSound object. - - \sa QSound() -*/ -QString QSound::fileName() const -{ - Q_D(const QSound); - return d->filename; -} - -/*! - Stops the sound playing. - - Note that on Windows the current loop will finish if a sound is - played in a loop. - - \sa play() -*/ -void QSound::stop() -{ - Q_D(QSound); - server().stop(this); - d->looprem = 0; -} - - -/*! - Returns true if sound facilities exist on the platform; otherwise - returns false. - - If no sound is available, all QSound operations work silently and - quickly. An application may choose either to notify the user if - sound is crucial to the application or to operate silently without - bothering the user. - - Note: On Windows this always returns true because some sound card - drivers do not implement a way to find out whether it is available - or not. -*/ -bool QSound::isAvailable() -{ - return server().okay(); -} - -/*! - Sets the internal bucket record of sound \a s to \a b, deleting - any previous setting. -*/ -void QAuServer::setBucket(QSound* s, QAuBucket* b) -{ - delete s->d_func()->bucket; - s->d_func()->bucket = b; -} - -/*! - Returns the internal bucket record of sound \a s. -*/ -QAuBucket* QAuServer::bucket(QSound* s) -{ - return s->d_func()->bucket; -} - -/*! - Decrements the QSound::loopRemaining() value for sound \a s, - returning the result. -*/ -int QAuServer::decLoop(QSound* s) -{ - if (s->d_func()->looprem > 0) - --s->d_func()->looprem; - return s->d_func()->looprem; -} - -/*! - Initializes the sound. The default implementation does nothing. -*/ -void QAuServer::init(QSound*) -{ -} - -QAuBucket::~QAuBucket() -{ -} -/*! - \fn bool QSound::available() - - Use the isAvailable() function instead. -*/ - -QT_END_NAMESPACE - -#endif // QT_NO_SOUND diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index e5ebfba851..7ec37bb929 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8251,7 +8251,7 @@ bool QWidget::event(QEvent *event) #ifndef Q_WS_MAC QTouchEvent *touchEvent = static_cast(event); const QTouchEvent::TouchPoint &touchPoint = touchEvent->touchPoints().first(); - if (touchPoint.isPrimary() || touchEvent->deviceType() == QTouchEvent::TouchPad) + if (touchPoint.isPrimary() || touchEvent->device()->type() == QTouchDevice::TouchPad) break; // fake a mouse event! diff --git a/src/widgets/kernel/qwidgetwindow_qpa.cpp b/src/widgets/kernel/qwidgetwindow_qpa.cpp index 5b7ded9ece..e3178db8c9 100644 --- a/src/widgets/kernel/qwidgetwindow_qpa.cpp +++ b/src/widgets/kernel/qwidgetwindow_qpa.cpp @@ -289,7 +289,7 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) void QWidgetWindow::handleTouchEvent(QTouchEvent *event) { - QApplicationPrivate::translateRawTouchEvent(m_widget, event->deviceType(), event->touchPoints(), event->timestamp()); + QApplicationPrivate::translateRawTouchEvent(m_widget, event->device(), event->touchPoints(), event->timestamp()); } void QWidgetWindow::handleKeyEvent(QKeyEvent *event) diff --git a/src/widgets/platforms/mac/qsound_mac.mm b/src/widgets/platforms/mac/qsound_mac.mm deleted file mode 100644 index 8c8ac0818b..0000000000 --- a/src/widgets/platforms/mac/qsound_mac.mm +++ /dev/null @@ -1,190 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include -#include "qsound.h" -#include "qsound_p.h" -#include -#include -#include -#import - -#include - -QT_BEGIN_NAMESPACE - -void qt_mac_beep() -{ - NSBeep(); -} - -QT_END_NAMESPACE - -#ifndef QT_NO_SOUND - -QT_BEGIN_NAMESPACE - -typedef QHash Sounds; -static Sounds sounds; - -class QAuServerMac : public QAuServer -{ - Q_OBJECT -public: - QAuServerMac(QObject* parent) : QAuServer(parent) { } - void play(const QString& filename); - void play(QSound *s); - void stop(QSound*); - bool okay() { return true; } - using QAuServer::decLoop; // promote to public. -protected: - NSSound *createNSSound(const QString &filename, QSound *qSound); -}; - -QT_END_NAMESPACE - -#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_5 -@protocol NSSoundDelegate --(void)sound:(NSSound *)sound didFinishPlaying:(BOOL)aBool; -@end -#endif - -QT_USE_NAMESPACE - -@interface QT_MANGLE_NAMESPACE(QMacSoundDelegate) : NSObject { - QSound *qSound; // may be null. - QAuServerMac* server; -} --(id)initWithQSound:(QSound*)sound:(QAuServerMac*)server; -@end - -@implementation QT_MANGLE_NAMESPACE(QMacSoundDelegate) --(id)initWithQSound:(QSound*)s:(QAuServerMac*)serv { - self = [super init]; - if(self) { - qSound = s; - server = serv; - } - return self; -} - -// Delegate function that gets called each time a sound finishes. --(void)sound:(NSSound *)sound didFinishPlaying:(BOOL)finishedOk -{ - // qSound is null if this sound was started by play(QString), - // in which case there is no corresponding QSound object. - if (qSound == 0) { - [sound release]; - [self release]; - return; - } - - // finishedOk is false if the sound cold not be played or - // if it was interrupted by stop(). - if (finishedOk == false) { - sounds.remove(qSound); - [sound release]; - [self release]; - return; - } - - // Check if the sound should loop "forever" (until stop). - if (qSound->loops() == -1) { - [sound play]; - return; - } - - const int remainingIterations = server->decLoop(qSound); - if (remainingIterations > 0) { - [sound play]; - } else { - sounds.remove(qSound); - [sound release]; - [self release]; - } -} -@end - -QT_BEGIN_NAMESPACE - -void QAuServerMac::play(const QString &fileName) -{ - QMacCocoaAutoReleasePool pool; - NSSound * const nsSound = createNSSound(fileName, 0); - [nsSound play]; -} - -void QAuServerMac::play(QSound *qSound) -{ - QMacCocoaAutoReleasePool pool; - NSSound * const nsSound = createNSSound(qSound->fileName(), qSound); - [nsSound play]; - // Keep track of the nsSound object so we can find it again in stop(). - sounds[qSound] = nsSound; -} - -void QAuServerMac::stop(QSound *qSound) -{ - Sounds::const_iterator it = sounds.constFind(qSound); - if (it != sounds.constEnd()) - [*it stop]; -} - -// Creates an NSSound object and installs a "sound finished" callack delegate on it. -NSSound *QAuServerMac::createNSSound(const QString &fileName, QSound *qSound) -{ - NSString *nsFileName = const_cast(reinterpret_cast(QCFString::toCFStringRef(fileName))); - NSSound * const nsSound = [[NSSound alloc] initWithContentsOfFile: nsFileName byReference:YES]; - QT_MANGLE_NAMESPACE(QMacSoundDelegate) * const delegate = [[QT_MANGLE_NAMESPACE(QMacSoundDelegate) alloc] initWithQSound:qSound:this]; - [nsSound setDelegate:delegate]; - [nsFileName release]; - return nsSound; -} - -QAuServer* qt_new_audio_server() -{ - return new QAuServerMac(qApp); -} - -QT_END_NAMESPACE - -#include "qsound_mac.moc" - -#endif // QT_NO_SOUND diff --git a/src/widgets/util/qflickgesture.cpp b/src/widgets/util/qflickgesture.cpp index a028b27d72..fbbefcf89f 100644 --- a/src/widgets/util/qflickgesture.cpp +++ b/src/widgets/util/qflickgesture.cpp @@ -551,7 +551,7 @@ QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state, if (!inputType) inputType = QScroller::InputMove; - if (te->deviceType() == QTouchEvent::TouchPad) { + if (te->device()->type() == QTouchDevice::TouchPad) { if (te->touchPoints().count() != 2) // 2 fingers on pad return Ignore; diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 8e87e761db..1fc1ba381c 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -21,7 +21,6 @@ cross_compile: SUBDIRS -= tools # disable 'make check' on Mac OS X for the following subdirs for the time being mac { - gui.CONFIG += no_check_target network.CONFIG += no_check_target widgets.CONFIG += no_check_target } diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 90cd1aedb9..300f30e133 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -199,7 +199,8 @@ private slots: void mapOpenMode_data(); void mapOpenMode(); - void openStandardStreams(); + void openStandardStreamsFileDescriptors(); + void openStandardStreamsBufferedStreams(); void resize_data(); void resize(); @@ -228,9 +229,6 @@ private: NumberOfFileTypes }; - void openStandardStreamsFileDescriptors(); - void openStandardStreamsBufferedStreams(); - bool openFd(QFile &file, QIODevice::OpenMode mode, QFile::FileHandleFlags handleFlags) { int fdMode = QT_OPEN_LARGEFILE | QT_OPEN_BINARY; @@ -2971,29 +2969,35 @@ void tst_QFile::openStandardStreamsFileDescriptors() //it does not have functions to simply open them like below . QSKIP("Opening standard streams on Windows CE via descriptor not implemented"); #endif - // Using file descriptors + /* in/out/err.isSequential() are only true when run in a console (CI); + * it is false when they are redirected from/to files. + * Prevent failures in case someone runs tests with stdout/stderr redirected. */ + { QFile in; in.open(STDIN_FILENO, QIODevice::ReadOnly); + if (!in.isSequential()) + QSKIP("Standard input redirected."); QCOMPARE( in.pos(), (qint64)0 ); QCOMPARE( in.size(), (qint64)0 ); - QVERIFY( in.isSequential() ); } { QFile out; - out.open(STDOUT_FILENO, QIODevice::WriteOnly); + QVERIFY(out.open(STDOUT_FILENO, QIODevice::WriteOnly)); + if (!out.isSequential()) + QSKIP("Standard output redirected."); QCOMPARE( out.pos(), (qint64)0 ); QCOMPARE( out.size(), (qint64)0 ); - QVERIFY( out.isSequential() ); } { QFile err; err.open(STDERR_FILENO, QIODevice::WriteOnly); + if (!err.isSequential()) + QSKIP("Standard error redirected."); QCOMPARE( err.pos(), (qint64)0 ); QCOMPARE( err.size(), (qint64)0 ); - QVERIFY( err.isSequential() ); } } @@ -3028,12 +3032,6 @@ void tst_QFile::openStandardStreamsBufferedStreams() } } -void tst_QFile::openStandardStreams() -{ - openStandardStreamsFileDescriptors(); - openStandardStreamsBufferedStreams(); -} - void tst_QFile::writeNothing() { for (int i = 0; i < NumberOfFileTypes; ++i) { diff --git a/tests/auto/corelib/io/qprocess/test/test.pro b/tests/auto/corelib/io/qprocess/test/test.pro index 39ce734c56..a8dba5eb8b 100644 --- a/tests/auto/corelib/io/qprocess/test/test.pro +++ b/tests/auto/corelib/io/qprocess/test/test.pro @@ -4,12 +4,5 @@ embedded: QT += gui SOURCES = ../tst_qprocess.cpp TARGET = ../tst_qprocess -win32 { - CONFIG(debug, debug|release) { - TARGET = ../../debug/tst_qprocess - } else { - TARGET = ../../release/tst_qprocess - } -} TESTDATA += ../testBatFiles/* diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro index f53e5790ea..0146a6a985 100644 --- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro +++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/onespace.pro @@ -3,7 +3,7 @@ CONFIG -= qt app_bundle CONFIG += console DESTDIR = ./ -TARGET = one space +TARGET = "one space" # This app is testdata for tst_qprocess target.path = $$[QT_INSTALL_TESTS]/tst_qprocess/testProcessSpacesArgs diff --git a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro index a4ee0cfd83..f881c2a824 100644 --- a/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro +++ b/tests/auto/corelib/io/qprocess/testProcessSpacesArgs/twospaces.pro @@ -3,7 +3,7 @@ CONFIG -= qt app_bundle CONFIG += console DESTDIR = ./ -TARGET = two space s +TARGET = "two space s" # This app is testdata for tst_qprocess target.path = $$[QT_INSTALL_TESTS]/tst_qprocess/testProcessSpacesArgs diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp index f5754c07aa..9d0121307c 100644 --- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp +++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp @@ -1421,6 +1421,15 @@ void tst_QProcess::spaceArgsTest_data() << QString::fromLatin1(" \"\"\"\"\"\"\" \"\" \"\"\"\"\"\"\" "); } +static QByteArray startFailMessage(const QString &program, const QProcess &process) +{ + QByteArray result = "Process '"; + result += program.toLocal8Bit(); + result += "' failed to start: "; + result += process.errorString().toLocal8Bit(); + return result; +} + //----------------------------------------------------------------------------- void tst_QProcess::spaceArgsTest() { @@ -1438,13 +1447,17 @@ void tst_QProcess::spaceArgsTest() QString program = programs.at(i); process->start(program, args); -#if !defined(Q_OS_WINCE) - QVERIFY(process->waitForStarted(5000)); - QVERIFY(process->waitForFinished(5000)); +#if defined(Q_OS_WINCE) + const int timeOutMS = 10000; #else - QVERIFY(process->waitForStarted(10000)); - QVERIFY(process->waitForFinished(10000)); + const int timeOutMS = 5000; #endif + QByteArray errorMessage; + bool started = process->waitForStarted(timeOutMS); + if (!started) + errorMessage = startFailMessage(program, *process); + QVERIFY2(started, errorMessage.constData()); + QVERIFY(process->waitForFinished(timeOutMS)); #if !defined(Q_OS_WINCE) QStringList actual = QString::fromLatin1(process->readAll()).split("|"); @@ -1463,9 +1476,13 @@ void tst_QProcess::spaceArgsTest() if (!stringArgs.isEmpty()) program += QString::fromLatin1(" ") + stringArgs; + errorMessage.clear(); process->start(program); + started = process->waitForStarted(5000); + if (!started) + errorMessage = startFailMessage(program, *process); - QVERIFY(process->waitForStarted(5000)); + QVERIFY2(started, errorMessage.constData()); QVERIFY(process->waitForFinished(5000)); #if !defined(Q_OS_WINCE) diff --git a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp index 434b15b125..60c7174f3a 100644 --- a/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp +++ b/tests/auto/corelib/io/qtemporarydir/tst_qtemporarydir.cpp @@ -55,12 +55,7 @@ class tst_QTemporaryDir : public QObject { Q_OBJECT public: - tst_QTemporaryDir(); - virtual ~tst_QTemporaryDir(); public slots: - void init(); - void cleanup(); - void initTestCase(); void cleanupTestCase(); @@ -75,7 +70,6 @@ private slots: void openOnRootDrives(); void stressTest(); void rename(); - void autoRemoveAfterFailedRename(); void QTBUG_4796_data(); void QTBUG_4796(); @@ -115,23 +109,6 @@ void tst_QTemporaryDir::getSetCheck() QCOMPARE(true, obj1.autoRemove()); } -tst_QTemporaryDir::tst_QTemporaryDir() -{ -} - -tst_QTemporaryDir::~tst_QTemporaryDir() -{ - -} - -void tst_QTemporaryDir::init() -{ -} - -void tst_QTemporaryDir::cleanup() -{ -} - void tst_QTemporaryDir::fileTemplate_data() { QTest::addColumn("constructorTemplate"); @@ -142,10 +119,12 @@ void tst_QTemporaryDir::fileTemplate_data() QTest::newRow("constructor with xxx sufix") << "qt_XXXXXXxxx" << "qt_XXXXXXxxx"; QTest::newRow("constructor with xXx sufix") << "qt_XXXXXXxXx" << "qt_XXXXXXxXx"; QTest::newRow("constructor with no suffix") << "qt_XXXXXX" << "qt_"; - QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_XXXX"; + QTest::newRow("constructor with >6 X's, no suffix") << "qt_XXXXXXXXXX" << "qt_"; + // When more than 6 X are present at the end, linux and windows will only replace the last 6, + // while Mac OS will actually replace all of them so we can only expect "qt_" (and check isValid). QTest::newRow("constructor with XXXX suffix") << "qt_XXXXXX_XXXX" << "qt_"; - QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_XXXX"; - QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_XXXXX"; + QTest::newRow("constructor with XXXX prefix") << "qt_XXXX" << "qt_"; + QTest::newRow("constructor with XXXXX prefix") << "qt_XXXXX" << "qt_"; } void tst_QTemporaryDir::fileTemplate() @@ -175,7 +154,7 @@ void tst_QTemporaryDir::fileName() dir.setAutoRemove(true); QString fileName = dir.path(); QVERIFY2(fileName.contains("/tst_qtemporarydir-"), qPrintable(fileName)); - QVERIFY(QFile::exists(fileName)); + QVERIFY(QDir(fileName).exists()); // Get path to the temp dir, without the file name. QString absoluteFilePath = QFileInfo(fileName).absolutePath(); #if defined(Q_OS_WIN) @@ -198,9 +177,9 @@ void tst_QTemporaryDir::autoRemove() #ifdef Q_OS_WIN // Windows seems unreliable here: sometimes it says the directory still exists, // immediately after we deleted it. - QTRY_VERIFY(!QFile::exists(dirName)); + QTRY_VERIFY(!QDir(dirName).exists()); #else - QVERIFY(!QFile::exists(dirName)); + QVERIFY(!QDir(dirName).exists()); #endif // Test if disabling auto remove works. @@ -210,9 +189,9 @@ void tst_QTemporaryDir::autoRemove() QVERIFY(dir.isValid()); dirName = dir.path(); } - QVERIFY(QFile::exists(dirName)); + QVERIFY(QDir(dirName).exists()); QVERIFY(QDir().rmdir(dirName)); - QVERIFY(!QFile::exists(dirName)); + QVERIFY(!QDir(dirName).exists()); // Do not explicitly call setAutoRemove (tests if it really is the default as documented) { @@ -221,9 +200,9 @@ void tst_QTemporaryDir::autoRemove() dirName = dir.path(); } #ifdef Q_OS_WIN - QTRY_VERIFY(!QFile::exists(dirName)); + QTRY_VERIFY(!QDir(dirName).exists()); #else - QVERIFY(!QFile::exists(dirName)); + QVERIFY(!QDir(dirName).exists()); #endif // Test autoremove with files and subdirs in the temp dir @@ -240,25 +219,32 @@ void tst_QTemporaryDir::autoRemove() QCOMPARE(file.write("Hello"), 5LL); } #ifdef Q_OS_WIN - QTRY_VERIFY(!QFile::exists(dirName)); + QTRY_VERIFY(!QDir(dirName).exists()); #else - QVERIFY(!QFile::exists(dirName)); + QVERIFY(!QDir(dirName).exists()); #endif } void tst_QTemporaryDir::nonWritableCurrentDir() { #ifdef Q_OS_UNIX - QString cwd = QDir::currentPath(); - QDir::setCurrent("/"); + struct ChdirOnReturn + { + ChdirOnReturn(const QString& d) : dir(d) {} + ~ChdirOnReturn() { + QDir::setCurrent(dir); + } + QString dir; + }; + ChdirOnReturn cor(QDir::currentPath()); + + QDir::setCurrent("/home"); // QTemporaryDir("tempXXXXXX") is probably a bad idea in any app // where the current dir could anything... - QString fileName; QTemporaryDir dir("tempXXXXXX"); dir.setAutoRemove(true); QVERIFY(!dir.isValid()); - fileName = dir.path(); - QDir::setCurrent(cwd); + QVERIFY(dir.path().isEmpty()); #endif } @@ -267,13 +253,13 @@ void tst_QTemporaryDir::openOnRootDrives() #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) unsigned int lastErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); #endif - // If it's possible to create a dir in the root directory, it + // If it's possible to create a file in the root directory, it // must be possible to create a temp dir there too. foreach (const QFileInfo &driveInfo, QDir::drives()) { - QFile testFile(driveInfo.filePath() + "XXXXXX.txt"); + QFile testFile(driveInfo.filePath() + "XXXXXX"); if (testFile.open(QIODevice::ReadWrite)) { testFile.remove(); - QTemporaryDir dir(driveInfo.filePath() + "XXXXXX.txt"); + QTemporaryDir dir(driveInfo.filePath() + "XXXXXX"); dir.setAutoRemove(true); QVERIFY(dir.isValid()); } @@ -328,41 +314,6 @@ void tst_QTemporaryDir::rename() QVERIFY(!dir.exists()); } -void tst_QTemporaryDir::autoRemoveAfterFailedRename() -{ - struct CleanOnReturn - { - ~CleanOnReturn() - { - if (!tempName.isEmpty()) - QVERIFY(QDir(tempName).removeRecursively()); - } - - void reset() - { - tempName.clear(); - } - - QString tempName; - }; - - CleanOnReturn cleaner; - - { - QTemporaryDir dir; - QVERIFY(dir.isValid()); - cleaner.tempName = dir.path(); - - QVERIFY(QFile::exists(cleaner.tempName)); - QVERIFY(!QFileInfo("i-do-not-exist").isDir()); - QVERIFY(!QDir().rename(cleaner.tempName, "i-do-not-exist/dir.txt")); - QVERIFY(QFile::exists(cleaner.tempName)); - } - - QVERIFY(!QFile::exists(cleaner.tempName)); - cleaner.reset(); -} - void tst_QTemporaryDir::QTBUG_4796_data() { QTest::addColumn("prefix"); @@ -380,7 +331,7 @@ void tst_QTemporaryDir::QTBUG_4796_data() QTest::newRow("XXXXXX") << unicode << QString() << true; } -void tst_QTemporaryDir::QTBUG_4796() +void tst_QTemporaryDir::QTBUG_4796() // unicode support { QVERIFY(QDir("test-XXXXXX").exists()); @@ -443,9 +394,9 @@ void tst_QTemporaryDir::QTBUG_4796() QString fileName5 = currentDir.relativeFilePath(dir5.path()); QString fileName6 = currentDir.relativeFilePath(dir6.path()); - QVERIFY(fileName1.startsWith(fileTemplate1)); - QVERIFY(fileName2.startsWith(fileTemplate2)); - QVERIFY(fileName5.startsWith("test-XXXXXX/" + fileTemplate1)); + QVERIFY(fileName1.startsWith(prefix)); + QVERIFY(fileName2.startsWith(prefix)); + QVERIFY(fileName5.startsWith("test-XXXXXX/" + prefix)); QVERIFY(fileName6.startsWith("test-XXXXXX/" + prefix)); if (!prefix.isEmpty()) { @@ -459,7 +410,7 @@ void tst_QTemporaryDir::QTBUG_4796() QTest::qWait(20); #endif foreach (const QString &tempName, cleaner.tempNames) - QVERIFY2(!QFile::exists(tempName), qPrintable(tempName)); + QVERIFY2(!QDir(tempName).exists(), qPrintable(tempName)); cleaner.reset(); } diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 46c0e19c9e..a1e9d98461 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -256,16 +256,23 @@ void tst_QTemporaryFile::autoRemove() void tst_QTemporaryFile::nonWritableCurrentDir() { #ifdef Q_OS_UNIX - QString cwd = QDir::currentPath(); - QDir::setCurrent("/"); + struct ChdirOnReturn + { + ChdirOnReturn(const QString& d) : dir(d) {} + ~ChdirOnReturn() { + QDir::setCurrent(dir); + } + QString dir; + }; + ChdirOnReturn cor(QDir::currentPath()); + + QDir::setCurrent("/home"); // QTemporaryFile("tempXXXXXX") is probably a bad idea in any app // where the current dir could anything... - QString fileName; QTemporaryFile file("tempXXXXXX"); file.setAutoRemove(true); QVERIFY(!file.open()); - fileName = file.fileName(); - QDir::setCurrent(cwd); + QVERIFY(file.fileName().isEmpty()); #endif } diff --git a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp index 1cb6b7f3f9..e94b6d3fb9 100644 --- a/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/externaltests.cpp @@ -43,6 +43,7 @@ #include "externaltests.h" #include +#include #include #include #include @@ -75,42 +76,6 @@ static QString makespec() return QString::fromLatin1(p + 1); } -static bool removeRecursive(const QString &pathname) -{ - QFileInfo fi(pathname); - if (!fi.exists()) - return true; - - if (fi.isFile()) - return QFile::remove(pathname); - - if (!fi.isDir()) { - // not a file or directory. How do I remove it? - return false; - } - - // not empty -- we must empty it first - QDirIterator di(pathname, QDir::AllEntries | QDir::Hidden | QDir::System | QDir::NoDotAndDotDot); - while (di.hasNext()) { - di.next(); - if (!di.fileInfo().exists() && !di.fileInfo().isSymLink()) - continue; - bool ok; - if (di.fileInfo().isFile() || di.fileInfo().isSymLink()) - ok = QFile::remove(di.filePath()); - else - ok = removeRecursive(di.filePath()); - if (!ok) { - return false; - } - } - - QDir dir(pathname); - QString dirname = dir.dirName(); - dir.cdUp(); - return dir.rmdir(dirname); -} - QT_BEGIN_NAMESPACE namespace QTest { class QExternalProcess: public QProcess @@ -140,7 +105,7 @@ namespace QTest { QExternalTestPrivate() : qtModules(QExternalTest::QtCore | QExternalTest::QtGui | QExternalTest::QtTest), appType(QExternalTest::AutoApplication), - exitCode(-1) + temporaryDir(0), exitCode(-1) { } ~QExternalTestPrivate() @@ -156,7 +121,8 @@ namespace QTest { QExternalTest::QtModules qtModules; QExternalTest::ApplicationType appType; - QString temporaryDir; + QString temporaryDirPath; + QTemporaryDir *temporaryDir; QByteArray sourceCode; QByteArray std_out; QByteArray std_err; @@ -330,9 +296,8 @@ namespace QTest { // actual execution code void QExternalTestPrivate::clear() { - if (!temporaryDir.isEmpty()) - removeTemporaryDirectory(); - + delete temporaryDir; + temporaryDir = 0; sourceCode.clear(); std_out.clear(); std_err.clear(); @@ -340,14 +305,6 @@ namespace QTest { failedStage = QExternalTest::FileStage; } - void QExternalTestPrivate::removeTemporaryDirectory() - { - if (temporaryDir.isEmpty()) - qWarning() << "Temporary directory is expected to be non-empty"; - removeRecursive(temporaryDir); - temporaryDir.clear(); - } - bool QExternalTestPrivate::prepareSourceCode(const QByteArray &body) { sourceCode.clear(); @@ -448,7 +405,7 @@ namespace QTest { " return 0;\n" "}\n"; - QFile sourceFile(temporaryDir + QLatin1String("/project.cpp")); + QFile sourceFile(temporaryDirPath + QLatin1String("/project.cpp")); if (!sourceFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { std_err = sourceFile.errorString().toLocal8Bit(); return false; @@ -457,7 +414,7 @@ namespace QTest { sourceFile.write(sourceCode); sourceFile.close(); - sourceFile.setFileName(temporaryDir + QLatin1String("/user_code.cpp")); + sourceFile.setFileName(temporaryDirPath + QLatin1String("/user_code.cpp")); if (!sourceFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { std_err = sourceFile.errorString().toLocal8Bit(); return false; @@ -469,27 +426,24 @@ namespace QTest { bool QExternalTestPrivate::createTemporaryDirectory() { - QDir temp = QDir::temp(); - QString subdir = QString::fromLatin1("qexternaltest-%1-%2-%3") - .arg(QDateTime::currentDateTime().toString(QLatin1String("yyyyMMddhhmmss"))) - .arg(quintptr(this), 0, 16) - .arg(qrand()); - if (!temp.mkdir(subdir)) + delete temporaryDir; + temporaryDir = new QTemporaryDir; + if (temporaryDir->isValid()) { + temporaryDirPath = temporaryDir->path(); + return true; + } else { + delete temporaryDir; + temporaryDir = 0; return false; - - if (!temp.cd(subdir)) - return false; - - temporaryDir = temp.absolutePath(); - return true; + } } bool QExternalTestPrivate::createProjectFile() { - if (temporaryDir.isEmpty()) + if (temporaryDirPath.isEmpty()) qWarning() << "Temporary directory is expected to be non-empty"; - QFile projectFile(temporaryDir + QLatin1String("/project.pro")); + QFile projectFile(temporaryDirPath + QLatin1String("/project.pro")); if (!projectFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { std_err = projectFile.errorString().toLocal8Bit(); return false; @@ -597,7 +551,7 @@ namespace QTest { bool QExternalTestPrivate::runQmake() { - if (temporaryDir.isEmpty()) + if (temporaryDirPath.isEmpty()) qWarning() << "Temporary directory is expected to be non-empty"; if (!createProjectFile()) @@ -610,7 +564,7 @@ namespace QTest { << QLatin1String("-spec") << makespec() << QLatin1String("project.pro"); - qmake.setWorkingDirectory(temporaryDir); + qmake.setWorkingDirectory(temporaryDirPath); qmake.start(QLatin1String("qmake"), args); std_out += "### --- stdout from qmake --- ###\n"; @@ -633,11 +587,11 @@ namespace QTest { bool QExternalTestPrivate::runMake(Target target) { - if (temporaryDir.isEmpty()) + if (temporaryDirPath.isEmpty()) qWarning() << "Temporary directory is expected to be non-empty"; QExternalProcess make; - make.setWorkingDirectory(temporaryDir); + make.setWorkingDirectory(temporaryDirPath); QStringList environment = QProcess::systemEnvironment(); environment += QLatin1String("LC_ALL=C"); diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index e62ee0f051..7eb1bd2dee 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -1663,7 +1663,13 @@ void tst_QSharedPointer::invalidConstructs_data() // use of forward-declared class QTest::newRow("forward-declaration") +#ifdef Q_CC_CLANG + // Deleting a forward declaration is undefined, which results in a linker error with clang + << &QTest::QExternalTest::tryLinkFail +#else + // Other compilers accept the code, but do not call the destructor at run-time << &QTest::QExternalTest::tryRun +#endif << "forwardDeclaredDestructorRunCount = 0;\n" "{ QSharedPointer ptr = QSharedPointer(forwardPointer()); }\n" "exit(forwardDeclaredDestructorRunCount);"; diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp index f386624092..c15d1e6976 100644 --- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp @@ -57,7 +57,7 @@ #include -#ifdef Q_WS_WIN +#ifdef Q_OS_WIN #include #endif @@ -117,7 +117,7 @@ private slots: void convertFromImageNoDetach(); void convertFromImageDetach(); -#if defined(Q_WS_WIN) +#if defined(Q_OS_WIN) void toWinHBITMAP_data(); void toWinHBITMAP(); void fromWinHBITMAP_data(); @@ -167,32 +167,28 @@ static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) QImage expectedImage = expected.toImage().convertToFormat(QImage::Format_RGB32); QImage actualImage = actual.toImage().convertToFormat(QImage::Format_RGB32); - if (expectedImage.size() != actualImage.size()) + if (expectedImage.size() != actualImage.size()) { + qWarning("Image size comparison failed: expected: %dx%d, got %dx%d", + expectedImage.size().width(), expectedImage.size().height(), + actualImage.size().width(), actualImage.size().height()); return false; + } - int size = actual.width() * actual.height(); - - int threshold = 2; - if (QPixmap::defaultDepth() == 16) - threshold = 10; + const int size = actual.width() * actual.height(); + const int threshold = QPixmap::defaultDepth() == 16 ? 10 : 2; QRgb *a = (QRgb *)actualImage.bits(); QRgb *e = (QRgb *)expectedImage.bits(); for (int i = 0; i < size; ++i) { - QColor ca(a[i]); - QColor ce(e[i]); - - bool result = true; - - if (qAbs(ca.red() - ce.red()) > threshold) - result = false; - if (qAbs(ca.green() - ce.green()) > threshold) - result = false; - if (qAbs(ca.blue() - ce.blue()) > threshold) - result = false; - - if (!result) + const QColor ca(a[i]); + const QColor ce(e[i]); + if (qAbs(ca.red() - ce.red()) > threshold + || qAbs(ca.green() - ce.green()) > threshold + || qAbs(ca.blue() - ce.blue()) > threshold) { + qWarning("Color mismatch at pixel #%d: Expected: %d,%d,%d, got %d,%d,%d", + i, ce.red(), ce.green(), ce.blue(), ca.red(), ca.green(), ca.blue()); return false; + } } return true; @@ -855,7 +851,15 @@ void tst_QPixmap::convertFromImageDetach() QVERIFY(copy.isDetached()); } -#if defined(Q_WS_WIN) +#if defined(Q_OS_WIN) + +Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap); +Q_GUI_EXPORT HBITMAP qt_pixmapToWinHBITMAP(const QPixmap &p, int hbitmapFormat = 0); +Q_GUI_EXPORT QPixmap qt_pixmapFromWinHBITMAP(HBITMAP bitmap, int hbitmapFormat = 0); +Q_GUI_EXPORT HICON qt_pixmapToWinHICON(const QPixmap &p); +Q_GUI_EXPORT QImage qt_imageFromWinHBITMAP(HDC hdc, HBITMAP bitmap, int w, int h); +Q_GUI_EXPORT QPixmap qt_pixmapFromWinHICON(HICON icon); + void tst_QPixmap::toWinHBITMAP_data() { QTest::addColumn("red"); @@ -876,7 +880,7 @@ void tst_QPixmap::toWinHBITMAP() QPixmap pm(100, 100); pm.fill(QColor(red, green, blue)); - HBITMAP bitmap = pm.toWinHBITMAP(); + HBITMAP bitmap = qt_pixmapToWinHBITMAP(pm); QVERIFY(bitmap != 0); @@ -931,7 +935,7 @@ void tst_QPixmap::fromWinHBITMAP() #ifdef Q_OS_WINCE //the device context has to be deleted before QPixmap::fromWinHBITMAP() DeleteDC(bitmap_dc); #endif - QPixmap pixmap = QPixmap::fromWinHBITMAP(bitmap); + QPixmap pixmap = qt_pixmapFromWinHBITMAP(bitmap); QCOMPARE(pixmap.width(), 100); QCOMPARE(pixmap.height(), 100); @@ -949,30 +953,39 @@ void tst_QPixmap::fromWinHBITMAP() ReleaseDC(0, display_dc); } -static void compareImages(const QImage &image1, const QImage &image2) +static bool compareImages(const QImage &actualImage, const QImage &expectedImage) { - QCOMPARE(image1.width(), image2.width()); - QCOMPARE(image1.height(), image2.height()); - QCOMPARE(image1.format(), image2.format()); + if (actualImage.width() != expectedImage.width() + || actualImage.height() != expectedImage.height()) { + qWarning("Image size comparison failed: expected: %dx%d, got %dx%d", + expectedImage.size().width(), expectedImage.size().height(), + actualImage.size().width(), actualImage.size().height()); + return false; + } + if (actualImage.format() != expectedImage.format()) { + qWarning("Image format comparison failed: expected: %d, got %d", + expectedImage.format(), actualImage.format()); + return false; + } static const int fuzz = 1; - for (int y = 0; y < image1.height(); y++) - { - for (int x = 0; x < image2.width(); x++) - { - QRgb p1 = image1.pixel(x, y); - QRgb p2 = image2.pixel(x, y); + for (int y = 0; y < actualImage.height(); ++y) { + for (int x = 0; x < expectedImage.width(); ++x) { + const QRgb p1 = actualImage.pixel(x, y); + const QRgb p2 = expectedImage.pixel(x, y); - bool pixelMatches = - qAbs(qRed(p1) - qRed(p2)) <= fuzz - && qAbs(qGreen(p1) - qGreen(p2)) <= fuzz - && qAbs(qBlue(p1) - qBlue(p2)) <= fuzz - && qAbs(qAlpha(p1) - qAlpha(p2)) <= fuzz; - - QVERIFY(pixelMatches); + if (qAbs(qRed(p1) - qRed(p2)) > fuzz + || qAbs(qGreen(p1) - qGreen(p2)) > fuzz + || qAbs(qBlue(p1) - qBlue(p2)) > fuzz + || qAbs(qAlpha(p1) - qAlpha(p2)) > fuzz) { + qWarning("Color mismatch at pixel %d,%d: Expected: 0x%x. got 0x%x", + x, y, p2, p1); + return false; + } } } + return true; } void tst_QPixmap::toWinHICON_data() @@ -995,9 +1008,7 @@ void tst_QPixmap::toWinHICON_data() void tst_QPixmap::toWinHICON() { -#ifdef Q_OS_WINCE - QSKIP("Test shall be enabled for Windows CE shortly."); -#endif + enum { Alpha = 2 }; QFETCH(int, width); QFETCH(int, height); @@ -1008,28 +1019,27 @@ void tst_QPixmap::toWinHICON() HDC display_dc = GetDC(0); HDC bitmap_dc = CreateCompatibleDC(display_dc); - HBITMAP bitmap = empty.toWinHBITMAP(QPixmap::Alpha); + HBITMAP bitmap = qt_pixmapToWinHBITMAP(empty, Alpha); SelectObject(bitmap_dc, bitmap); QImage imageFromFile(image + QString(QLatin1String("_%1x%2.png")).arg(width).arg(height)); imageFromFile = imageFromFile.convertToFormat(QImage::Format_ARGB32_Premultiplied); - HICON icon = QPixmap::fromImage(imageFromFile).toWinHICON(); + HICON icon = qt_pixmapToWinHICON(QPixmap::fromImage(imageFromFile)); DrawIconEx(bitmap_dc, 0, 0, icon, width, height, 0, 0, DI_NORMAL); DestroyIcon(icon); DeleteDC(bitmap_dc); - QImage imageFromHICON = QPixmap::fromWinHBITMAP(bitmap, QPixmap::Alpha).toImage(); + QImage imageFromHICON = qt_pixmapFromWinHBITMAP(bitmap, Alpha).toImage(); ReleaseDC(0, display_dc); // fuzzy comparison must be used, as the pixel values change slightly during conversion // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere - // QVERIFY(imageFromHICON == imageFromFile); - compareImages(imageFromHICON, imageFromFile); + QVERIFY(compareImages(imageFromHICON, imageFromFile)); } void tst_QPixmap::fromWinHICON_data() @@ -1039,16 +1049,12 @@ void tst_QPixmap::fromWinHICON_data() void tst_QPixmap::fromWinHICON() { -#ifdef Q_OS_WINCE - QSKIP("Test shall be enabled for Windows CE shortly."); - -#else QFETCH(int, width); QFETCH(int, height); QFETCH(QString, image); HICON icon = (HICON)LoadImage(0, (wchar_t*)(image + QLatin1String(".ico")).utf16(), IMAGE_ICON, width, height, LR_LOADFROMFILE); - QImage imageFromHICON = QPixmap::fromWinHICON(icon).toImage(); + QImage imageFromHICON = qt_pixmapFromWinHICON(icon).toImage(); DestroyIcon(icon); QImage imageFromFile(image + QString(QLatin1String("_%1x%2.png")).arg(width).arg(height)); @@ -1057,12 +1063,10 @@ void tst_QPixmap::fromWinHICON() // fuzzy comparison must be used, as the pixel values change slightly during conversion // between QImage::Format_ARGB32 and QImage::Format_ARGB32_Premultiplied, or elsewhere - // QVERIFY(imageFromHICON == imageFromFile); - compareImages(imageFromHICON, imageFromFile); -#endif + QVERIFY(compareImages(imageFromHICON, imageFromFile)); } -#endif // Q_WS_WIN +#endif // Q_OS_WIN void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() { diff --git a/tests/auto/gui/kernel/qclipboard/test/test.pro b/tests/auto/gui/kernel/qclipboard/test/test.pro index 5d28e8e060..1c92fa4107 100644 --- a/tests/auto/gui/kernel/qclipboard/test/test.pro +++ b/tests/auto/gui/kernel/qclipboard/test/test.pro @@ -19,3 +19,5 @@ wince* { DEPLOYMENT += copier paster rsc reg_resource } + +mac: CONFIG += insignificant_test # QTBUG-23057 diff --git a/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro b/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro index 1e0baafd09..c6eb02919e 100644 --- a/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro +++ b/tests/auto/gui/kernel/qkeysequence/qkeysequence.pro @@ -7,3 +7,5 @@ QT += core-private gui-private SOURCES += tst_qkeysequence.cpp RESOURCES += qkeysequence.qrc + +mac: CONFIG += insignificant_test # QTBUG-23058 diff --git a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp index 4583e79561..07afe4a89c 100644 --- a/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp +++ b/tests/auto/gui/kernel/qtouchevent/tst_qtouchevent.cpp @@ -51,6 +51,7 @@ public: bool acceptTouchBegin, acceptTouchUpdate, acceptTouchEnd; bool deleteInTouchBegin, deleteInTouchUpdate, deleteInTouchEnd; ulong timestamp; + QTouchDevice *deviceFromEvent; tst_QTouchEventWidget() : QWidget() @@ -78,6 +79,7 @@ public: seenTouchBegin = !seenTouchBegin && !seenTouchUpdate && !seenTouchEnd; touchBeginPoints = static_cast(event)->touchPoints(); timestamp = static_cast(event)->timestamp(); + deviceFromEvent = static_cast(event)->device(); event->setAccepted(acceptTouchBegin); if (deleteInTouchBegin) delete this; @@ -88,6 +90,7 @@ public: seenTouchUpdate = seenTouchBegin && !seenTouchEnd; touchUpdatePoints = static_cast(event)->touchPoints(); timestamp = static_cast(event)->timestamp(); + deviceFromEvent = static_cast(event)->device(); event->setAccepted(acceptTouchUpdate); if (deleteInTouchUpdate) delete this; @@ -98,6 +101,7 @@ public: seenTouchEnd = seenTouchBegin && !seenTouchEnd; touchEndPoints = static_cast(event)->touchPoints(); timestamp = static_cast(event)->timestamp(); + deviceFromEvent = static_cast(event)->device(); event->setAccepted(acceptTouchEnd); if (deleteInTouchEnd) delete this; @@ -190,7 +194,7 @@ class tst_QTouchEvent : public QObject { Q_OBJECT public: - tst_QTouchEvent() { } + tst_QTouchEvent(); ~tst_QTouchEvent() { } private slots: @@ -205,8 +209,21 @@ private slots: void deleteInRawEventTranslation(); void crashInQGraphicsSceneAfterNotHandlingTouchBegin(); void touchBeginWithGraphicsWidget(); + +private: + QTouchDevice *touchScreenDevice; + QTouchDevice *touchPadDevice; }; +tst_QTouchEvent::tst_QTouchEvent() +{ + touchScreenDevice = new QTouchDevice; + touchPadDevice = new QTouchDevice; + touchPadDevice->setType(QTouchDevice::TouchPad); + QWindowSystemInterface::registerTouchDevice(touchScreenDevice); + QWindowSystemInterface::registerTouchDevice(touchPadDevice); +} + void tst_QTouchEvent::touchDisabledByDefault() { // QWidget @@ -219,7 +236,7 @@ void tst_QTouchEvent::touchDisabledByDefault() QList touchPoints; touchPoints.append(QTouchEvent::TouchPoint(0)); QTouchEvent touchEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); @@ -248,7 +265,7 @@ void tst_QTouchEvent::touchDisabledByDefault() touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint())); touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint())); QTouchEvent touchEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); @@ -272,7 +289,7 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() QList touchPoints; touchPoints.append(QTouchEvent::TouchPoint(0)); QTouchEvent touchEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); @@ -310,7 +327,7 @@ void tst_QTouchEvent::touchEventAcceptedByDefault() touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint())); touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint())); QTouchEvent touchEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); @@ -338,7 +355,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() QList touchPoints; touchPoints.append(QTouchEvent::TouchPoint(0)); QTouchEvent touchEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); @@ -390,7 +407,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint())); touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint())); QTouchEvent touchEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); @@ -426,7 +443,7 @@ void tst_QTouchEvent::touchBeginPropagatesWhenIgnored() touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint())); touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint())); QTouchEvent touchEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); @@ -454,7 +471,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() QList touchPoints; touchPoints.append(QTouchEvent::TouchPoint(0)); QTouchEvent touchBeginEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); @@ -466,7 +483,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() // send the touch update to the child, but ignore it, it doesn't propagate QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointMoved, touchPoints); @@ -478,7 +495,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() // send the touch end, same thing should happen as with touch update QTouchEvent touchEndEvent(QEvent::TouchEnd, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointReleased, touchPoints); @@ -513,7 +530,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() touchPoint.setScreenPos(view.mapToGlobal(touchPoint.pos().toPoint())); touchPoint.setScenePos(view.mapToScene(touchPoint.pos().toPoint())); QTouchEvent touchBeginEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); @@ -526,7 +543,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() // send the touch update to the child, but ignore it, it doesn't propagate touchPoint.setState(Qt::TouchPointMoved); QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointMoved, (QList() << touchPoint)); @@ -540,7 +557,7 @@ void tst_QTouchEvent::touchUpdateAndEndNeverPropagate() // send the touch end, same thing should happen as with touch update touchPoint.setState(Qt::TouchPointReleased); QTouchEvent touchEndEvent(QEvent::TouchEnd, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointReleased, (QList() << touchPoint)); @@ -576,9 +593,12 @@ void tst_QTouchEvent::basicRawEventTranslation() rawTouchPoint.setState(Qt::TouchPointPressed); rawTouchPoint.setScreenPos(screenPos); rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry)); + QList rawPosList; + rawPosList << QPointF(12, 34) << QPointF(56, 78); + rawTouchPoint.setRawScreenPositions(rawPosList); const ulong timestamp = 1234; qt_translateRawTouchEvent(&touchWidget, - QTouchEvent::TouchScreen, + touchScreenDevice, QList() << rawTouchPoint, timestamp); QVERIFY(touchWidget.seenTouchBegin); @@ -605,13 +625,15 @@ void tst_QTouchEvent::basicRawEventTranslation() QCOMPARE(touchBeginPoint.screenRect(), QRectF(rawTouchPoint.screenPos(), QSizeF(0, 0))); QCOMPARE(touchBeginPoint.sceneRect(), touchBeginPoint.screenRect()); QCOMPARE(touchBeginPoint.pressure(), qreal(1.)); + QCOMPARE(touchBeginPoint.velocity(), QVector2D()); + QCOMPARE(touchBeginPoint.rawScreenPositions(), rawPosList); // moving the point should translate to TouchUpdate rawTouchPoint.setState(Qt::TouchPointMoved); rawTouchPoint.setScreenPos(screenPos + delta); rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry)); qt_translateRawTouchEvent(&touchWidget, - QTouchEvent::TouchScreen, + touchScreenDevice, QList() << rawTouchPoint, 0); QVERIFY(touchWidget.seenTouchBegin); @@ -643,7 +665,7 @@ void tst_QTouchEvent::basicRawEventTranslation() rawTouchPoint.setScreenPos(screenPos + delta + delta); rawTouchPoint.setNormalizedPos(normalized(rawTouchPoint.pos(), screenGeometry)); qt_translateRawTouchEvent(&touchWidget, - QTouchEvent::TouchScreen, + touchScreenDevice, QList() << rawTouchPoint, 0); QVERIFY(touchWidget.seenTouchBegin); @@ -709,7 +731,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rawTouchPoints[1].setState(Qt::TouchPointPressed); rawTouchPoints[1].setScreenPos(rightScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); @@ -770,7 +792,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rawTouchPoints[1].setState(Qt::TouchPointMoved); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); @@ -831,7 +853,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchScreen() rawTouchPoints[1].setState(Qt::TouchPointReleased); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); @@ -924,7 +946,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rawTouchPoints[1].setState(Qt::TouchPointPressed); rawTouchPoints[1].setScreenPos(rightScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchPad, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchPadDevice, rawTouchPoints, 0); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); @@ -985,7 +1007,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rawTouchPoints[1].setState(Qt::TouchPointMoved); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchPad, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchPadDevice, rawTouchPoints, 0); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); @@ -1046,7 +1068,7 @@ void tst_QTouchEvent::multiPointRawEventTranslationOnTouchPad() rawTouchPoints[1].setState(Qt::TouchPointReleased); rawTouchPoints[1].setScreenPos(centerScreenPos); rawTouchPoints[1].setNormalizedPos(normalized(rawTouchPoints[1].pos(), screenGeometry)); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchPad, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchPadDevice, rawTouchPoints, 0); QVERIFY(!touchWidget.seenTouchBegin); QVERIFY(!touchWidget.seenTouchUpdate); QVERIFY(!touchWidget.seenTouchEnd); @@ -1123,17 +1145,17 @@ void tst_QTouchEvent::deleteInEventHandler() QList touchPoints; touchPoints.append(QTouchEvent::TouchPoint(0)); QTouchEvent touchBeginEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointStationary, touchPoints); QTouchEvent touchEndEvent(QEvent::TouchEnd, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointReleased, touchPoints); @@ -1200,19 +1222,19 @@ void tst_QTouchEvent::deleteInEventHandler() QList touchPoints; touchPoints.append(touchPoint); QTouchEvent touchBeginEvent(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); touchPoints[0].setState(Qt::TouchPointMoved); QTouchEvent touchUpdateEvent(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointMoved, touchPoints); touchPoints[0].setState(Qt::TouchPointReleased); QTouchEvent touchEndEvent(QEvent::TouchEnd, - QTouchEvent::TouchScreen, + touchScreenDevice, Qt::NoModifier, Qt::TouchPointReleased, touchPoints); @@ -1304,20 +1326,20 @@ void tst_QTouchEvent::deleteInRawEventTranslation() rawTouchPoints[2].setNormalizedPos(normalized(rawTouchPoints[2].pos(), screenGeometry)); // generate begin events on all widgets, the left widget should die - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0); QVERIFY(pl.isNull() && !pc.isNull() && !pr.isNull()); // generate update events on all widget, the center widget should die rawTouchPoints[0].setState(Qt::TouchPointMoved); rawTouchPoints[1].setState(Qt::TouchPointMoved); rawTouchPoints[2].setState(Qt::TouchPointMoved); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0); // generate end events on all widget, the right widget should die rawTouchPoints[0].setState(Qt::TouchPointReleased); rawTouchPoints[1].setState(Qt::TouchPointReleased); rawTouchPoints[2].setState(Qt::TouchPointReleased); - qt_translateRawTouchEvent(&touchWidget, QTouchEvent::TouchScreen, rawTouchPoints, 0); + qt_translateRawTouchEvent(&touchWidget, touchScreenDevice, rawTouchPoints, 0); } void tst_QTouchEvent::crashInQGraphicsSceneAfterNotHandlingTouchBegin() @@ -1343,11 +1365,11 @@ void tst_QTouchEvent::crashInQGraphicsSceneAfterNotHandlingTouchBegin() QPoint centerPos = view.mapFromScene(rect->boundingRect().center()); // Touch the button - QTest::touchEvent(view.viewport()).press(0, centerPos, static_cast(0)); - QTest::touchEvent(view.viewport()).release(0, centerPos, static_cast(0)); + QTest::touchEvent(view.viewport(), touchScreenDevice).press(0, centerPos, static_cast(0)); + QTest::touchEvent(view.viewport(), touchScreenDevice).release(0, centerPos, static_cast(0)); // Touch outside of the button - QTest::touchEvent(view.viewport()).press(0, view.mapFromScene(QPoint(10, 10)), static_cast(0)); - QTest::touchEvent(view.viewport()).release(0, view.mapFromScene(QPoint(10, 10)), static_cast(0)); + QTest::touchEvent(view.viewport(), touchScreenDevice).press(0, view.mapFromScene(QPoint(10, 10)), static_cast(0)); + QTest::touchEvent(view.viewport(), touchScreenDevice).release(0, view.mapFromScene(QPoint(10, 10)), static_cast(0)); } void tst_QTouchEvent::touchBeginWithGraphicsWidget() @@ -1368,12 +1390,12 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() QTest::qWaitForWindowShown(&view); view.fitInView(scene.sceneRect()); - QTest::touchEvent(static_cast(0)) + QTest::touchEvent(static_cast(0), touchScreenDevice) .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()); - QTest::touchEvent(static_cast(0)) + QTest::touchEvent(static_cast(0), touchScreenDevice) .stationary(0) .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); - QTest::touchEvent(static_cast(0)) + QTest::touchEvent(static_cast(0), touchScreenDevice) .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()) .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); @@ -1385,12 +1407,12 @@ void tst_QTouchEvent::touchBeginWithGraphicsWidget() root->reset(); glassWidget->setWindowFlags(Qt::Window); // make the glassWidget a panel - QTest::touchEvent(static_cast(0)) + QTest::touchEvent(static_cast(0), touchScreenDevice) .press(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()); - QTest::touchEvent(static_cast(0)) + QTest::touchEvent(static_cast(0), touchScreenDevice) .stationary(0) .press(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); - QTest::touchEvent(static_cast(0)) + QTest::touchEvent(static_cast(0), touchScreenDevice) .release(0, view.mapFromScene(root->mapToScene(3,3)), view.viewport()) .release(1, view.mapFromScene(root->mapToScene(6,6)), view.viewport()); diff --git a/tests/auto/gui/kernel/qwindow/qwindow.pro b/tests/auto/gui/kernel/qwindow/qwindow.pro index 9fb49e8ceb..0115d96c56 100644 --- a/tests/auto/gui/kernel/qwindow/qwindow.pro +++ b/tests/auto/gui/kernel/qwindow/qwindow.pro @@ -5,3 +5,4 @@ QT += core-private gui-private testlib SOURCES += tst_qwindow.cpp +mac: CONFIG += insignificant_test # QTBUG-23059 diff --git a/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro b/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro index f397f48bb8..b0e69dca2e 100644 --- a/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro +++ b/tests/auto/gui/painting/qprinterinfo/qprinterinfo.pro @@ -5,3 +5,5 @@ SOURCES += tst_qprinterinfo.cpp QT += printsupport network testlib DEFINES += QT_USE_USING_NAMESPACE + +mac: CONFIG += insignificant_test # QTBUG-23060 diff --git a/tests/auto/gui/qopengl/qopengl.pro b/tests/auto/gui/qopengl/qopengl.pro index 0cc574a5bc..f3c020dde2 100644 --- a/tests/auto/gui/qopengl/qopengl.pro +++ b/tests/auto/gui/qopengl/qopengl.pro @@ -7,3 +7,5 @@ TARGET = tst_qopengl QT += gui gui-private core-private testlib SOURCES += tst_qopengl.cpp + +mac: CONFIG += insignificant_test # QTBUG-23061 diff --git a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro index 08442cc0ad..c853aaa100 100644 --- a/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro +++ b/tests/auto/gui/text/qfontdatabase/qfontdatabase.pro @@ -10,3 +10,4 @@ wince* { DEPLOYMENT += additionalFiles } +mac: CONFIG += insignificant_test # QTBUG-23062 diff --git a/tests/auto/gui/text/qstatictext/qstatictext.pro b/tests/auto/gui/text/qstatictext/qstatictext.pro index fff006ca8c..a0955af710 100644 --- a/tests/auto/gui/text/qstatictext/qstatictext.pro +++ b/tests/auto/gui/text/qstatictext/qstatictext.pro @@ -3,3 +3,5 @@ TARGET = tst_qstatictext QT += widgets widgets-private testlib QT += core core-private gui gui-private SOURCES += tst_qstatictext.cpp + +mac: CONFIG += insignificant_test # QTBUG-23063 diff --git a/tests/auto/gui/text/qtextscriptengine/qtextscriptengine.pro b/tests/auto/gui/text/qtextscriptengine/qtextscriptengine.pro index 6dcb1b44a0..516fa67f11 100644 --- a/tests/auto/gui/text/qtextscriptengine/qtextscriptengine.pro +++ b/tests/auto/gui/text/qtextscriptengine/qtextscriptengine.pro @@ -6,3 +6,5 @@ QT += core-private gui-private testlib HEADERS += SOURCES += tst_qtextscriptengine.cpp INCLUDEPATH += $$QT_SOURCE_TREE/src/3rdparty/harfbuzz/src + +mac: CONFIG += insignificant_test # QTBUG-23064 diff --git a/tests/auto/gui/text/text.pro b/tests/auto/gui/text/text.pro index 5055ab61a3..c24fe7553d 100644 --- a/tests/auto/gui/text/text.pro +++ b/tests/auto/gui/text/text.pro @@ -31,3 +31,7 @@ win32:SUBDIRS -= qtextpiecetable qstatictext \ qtextlayout \ qtextpiecetable \ + +mac { + qtextlayout.CONFIG = no_check_target # QTBUG-23050 +} diff --git a/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro b/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro index c7a4308b17..2eb00593e0 100644 --- a/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro +++ b/tests/auto/network/socket/qtcpsocket/stressTest/stressTest.pro @@ -1,6 +1,6 @@ HEADERS += Test.h SOURCES += main.cpp Test.cpp -QT += network +QT = core network testlib CONFIG -= app_bundle CONFIG += console diff --git a/tests/auto/network/socket/qtcpsocket/test/test.pro b/tests/auto/network/socket/qtcpsocket/test/test.pro index 13c39471b3..6c6697bfdc 100644 --- a/tests/auto/network/socket/qtcpsocket/test/test.pro +++ b/tests/auto/network/socket/qtcpsocket/test/test.pro @@ -1,7 +1,6 @@ CONFIG += testcase -QT += widgets testlib -QT += core-private network-private +QT = core-private network-private testlib SOURCES += ../tst_qtcpsocket.cpp win32: { wince*: { @@ -10,8 +9,6 @@ wince*: { LIBS += -lws2_32 } } -QT += network -vxworks:QT -= gui TARGET = tst_qtcpsocket @@ -24,5 +21,3 @@ win32 { } else { DESTDIR = ../ } - -CONFIG+=insignificant_test # unstable, QTBUG-21043 diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp index 98ce112a9e..218e372e4d 100644 --- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp @@ -63,10 +63,6 @@ #include #include #include -#ifndef Q_OS_VXWORKS -#include -#include -#endif #include #include #include @@ -175,7 +171,7 @@ private slots: void socketsInThreads(); void waitForReadyReadInASlot(); void remoteCloseError(); - void openMessageBoxInErrorSlot(); + void nestedEventLoopInErrorSlot(); #ifndef Q_OS_WIN void connectToLocalHostNoService(); #endif @@ -217,7 +213,7 @@ protected slots: void downloadBigFileSlot(); void recursiveReadyReadSlot(); void waitForReadyReadInASlotSlot(); - void messageBoxSlot(); + void enterLoopSlot(); void hostLookupSlot(); void abortiveClose_abortSlot(); void remoteCloseErrorSlot(); @@ -583,6 +579,7 @@ void tst_QTcpSocket::setSocketDescriptor() QVERIFY(socket->setSocketDescriptor(sock, QTcpSocket::UnconnectedState)); QCOMPARE(socket->socketDescriptor(), (int)sock); + qt_qhostinfo_clear_cache(); //avoid the HostLookupState being skipped due to address being in cache from previous test. socket->connectToHost(QtNetworkSettings::serverName(), 143); QCOMPARE(socket->state(), QTcpSocket::HostLookupState); QCOMPARE(socket->socketDescriptor(), (int)sock); @@ -1271,6 +1268,7 @@ void tst_QTcpSocket::disconnectWhileLookingUp() } else { socket->disconnectFromHost(); QVERIFY(socket->openMode() == QIODevice::ReadWrite); + QVERIFY(socket->waitForDisconnected(5000)); } // let anything queued happen @@ -1827,35 +1825,29 @@ void tst_QTcpSocket::remoteCloseErrorSlot() static_cast(sender())->close(); } -void tst_QTcpSocket::messageBoxSlot() +void tst_QTcpSocket::enterLoopSlot() { -#if !defined(Q_OS_VXWORKS) // no gui QTcpSocket *socket = qobject_cast(sender()); socket->deleteLater(); - QMessageBox box; - QTimer::singleShot(100, &box, SLOT(close())); - // This should not delete the socket - box.exec(); + // enter nested event loop + QEventLoop loop; + QTimer::singleShot(100, &loop, SLOT(quit())); + loop.exec(); // Fire a non-0 singleshot to leave time for the delete QTimer::singleShot(250, this, SLOT(exitLoopSlot())); -#endif } //---------------------------------------------------------------------------------- -void tst_QTcpSocket::openMessageBoxInErrorSlot() +void tst_QTcpSocket::nestedEventLoopInErrorSlot() { -#if defined(Q_OS_VXWORKS) // no gui - QSKIP("no default gui available on VxWorks"); -#else QTcpSocket *socket = newSocket(); QPointer p(socket); - connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(messageBoxSlot())); + connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(enterLoopSlot())); socket->connectToHost("hostnotfoundhostnotfound.troll.no", 9999); // Host not found, fyi enterLoop(30); QVERIFY(!p); -#endif } //---------------------------------------------------------------------------------- @@ -1979,16 +1971,9 @@ public slots: //---------------------------------------------------------------------------------- void tst_QTcpSocket::waitForConnectedInHostLookupSlot2() { -#if defined(Q_OS_WIN) || defined(Q_OS_VXWORKS) - QSKIP("waitForConnectedInHostLookupSlot2 is not run on Windows and VxWorks"); -#else - Foo foo; - QPushButton top("Go", 0); - top.show(); - connect(&top, SIGNAL(clicked()), &foo, SLOT(doIt())); - QTimer::singleShot(100, &top, SLOT(animateClick())); + QTimer::singleShot(100, &foo, SLOT(doIt())); QTimer::singleShot(5000, &foo, SLOT(exitLoop())); enterLoop(30); @@ -1997,7 +1982,6 @@ void tst_QTcpSocket::waitForConnectedInHostLookupSlot2() QVERIFY(foo.attemptedToConnect); QCOMPARE(foo.count, 1); -#endif } //---------------------------------------------------------------------------------- diff --git a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp index 378aff924d..a83611e2b5 100644 --- a/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/network/ssl/qsslsocket/tst_qsslsocket.cpp @@ -195,6 +195,7 @@ private slots: void setEmptyDefaultConfiguration(); void versionAccessors(); void sslOptions(); + void encryptWithoutConnecting(); static void exitLoop() { @@ -2122,6 +2123,18 @@ void tst_QSslSocket::sslOptions() #endif } +void tst_QSslSocket::encryptWithoutConnecting() +{ + if (!QSslSocket::supportsSsl()) + return; + + QTest::ignoreMessage(QtWarningMsg, + "QSslSocket::startClientEncryption: cannot start handshake when not connected"); + + QSslSocket sock; + sock.startClientEncryption(); +} + #endif // QT_NO_OPENSSL QTEST_MAIN(tst_QSslSocket) diff --git a/tests/auto/other/gestures/tst_gestures.cpp b/tests/auto/other/gestures/tst_gestures.cpp index 098f84b399..1a71f9170a 100644 --- a/tests/auto/other/gestures/tst_gestures.cpp +++ b/tests/auto/other/gestures/tst_gestures.cpp @@ -2335,7 +2335,10 @@ void tst_Gestures::bug_13501_gesture_not_accepted() w.show(); QTest::qWaitForWindowShown(&w); //QTest::mousePress(&ignoreEvent, Qt::LeftButton); - QTest::touchEvent(&w).press(0, QPoint(10, 10), &w); + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + QTest::touchEvent(&w, device).press(0, QPoint(10, 10), &w); } QTEST_MAIN(tst_Gestures) diff --git a/tests/auto/other/languagechange/languagechange.pro b/tests/auto/other/languagechange/languagechange.pro index 541a2f05fd..efbc524556 100644 --- a/tests/auto/other/languagechange/languagechange.pro +++ b/tests/auto/other/languagechange/languagechange.pro @@ -2,5 +2,3 @@ CONFIG += testcase TARGET = tst_languagechange QT += widgets core-private testlib SOURCES += tst_languagechange.cpp - -CONFIG += insignificant_test # QTBUG-21402 diff --git a/tests/auto/other/languagechange/tst_languagechange.cpp b/tests/auto/other/languagechange/tst_languagechange.cpp index 97a2683a75..3b77b13275 100644 --- a/tests/auto/other/languagechange/tst_languagechange.cpp +++ b/tests/auto/other/languagechange/tst_languagechange.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -88,14 +89,15 @@ class TransformTranslator : public QTranslator public: TransformTranslator() : QTranslator() {} TransformTranslator(QObject *parent) : QTranslator(parent) {} - virtual QString translate(const char *context, const char *sourceText, const char *comment = 0) const + QString translate(const char *context, const char *sourceText, + const char *disambiguation = 0, int = -1) const { QByteArray total(context); total.append("::"); total.append(sourceText); - if (comment) { + if (disambiguation) { total.append("::"); - total.append(comment); + total.append(disambiguation); } m_translations.insert(total); QString res; @@ -201,9 +203,10 @@ void tst_languageChange::retranslatability() QFETCH( TranslationSet, expected); // This will always be queried for when a language changes - expected.insert("QApplication::QT_LAYOUT_DIRECTION::Translate this string to the string 'LTR' in left-to-right " - "languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to " - "get proper widget layout."); + expected.insert("QCoreApplication::QT_LAYOUT_DIRECTION::Translate this string to the string 'LTR' in left-to-right " + "languages or to 'RTL' in right-to-left languages (such as Hebrew and Arabic) to " + "get proper widget layout."); + TransformTranslator translator; QTimer::singleShot(500, &translator, SLOT(install())); switch (dialogType) { @@ -212,25 +215,30 @@ void tst_languageChange::retranslatability() break; case ColorDialog: -#ifdef Q_WS_MAC +#ifdef Q_OS_MAC QSKIP("The native color dialog is used on Mac OS"); #else (void)QColorDialog::getColor(); #endif break; case FileDialog: { -#ifdef Q_WS_MAC +#ifdef Q_OS_MAC QSKIP("The native file dialog is used on Mac OS"); #endif QFileDialog dlg; dlg.setOption(QFileDialog::DontUseNativeDialog); - QString tmpParentDir = QDir::tempPath() + "/languagechangetestdir"; - QString tmpDir = tmpParentDir + "/finaldir"; - QString fooName = tmpParentDir + "/foo"; + QString tmpParentDir = QDir::tempPath(); + if (!tmpParentDir.endsWith(QLatin1Char('/'))) + tmpParentDir += QLatin1Char('/'); + tmpParentDir += QStringLiteral("languagechangetestdir"); + const QString tmpDir = tmpParentDir + QStringLiteral("/finaldir"); + const QString fooName = tmpParentDir + QStringLiteral("/foo"); QDir dir; QCOMPARE(dir.mkpath(tmpDir), true); - QCOMPARE(QFile::copy(QApplication::applicationFilePath(), fooName), true); - + QFile fooFile(fooName); + QVERIFY(fooFile.open(QIODevice::WriteOnly|QIODevice::Text)); + fooFile.write("test"); + fooFile.close(); dlg.setDirectory(tmpParentDir); #ifdef Q_OS_WINCE dlg.setDirectory("\\Windows"); diff --git a/tests/auto/other/modeltest/tst_modeltest.cpp b/tests/auto/other/modeltest/tst_modeltest.cpp index 434537a81f..e5c227d167 100644 --- a/tests/auto/other/modeltest/tst_modeltest.cpp +++ b/tests/auto/other/modeltest/tst_modeltest.cpp @@ -207,8 +207,8 @@ public: , storePersistentFailureCount(0) , checkPersistentFailureCount(0) { - connect(m_proxy, SIGNAL(layoutAboutToBeChanged()), SLOT(storePersistent())); - connect(m_proxy, SIGNAL(layoutChanged()), SLOT(checkPersistent())); + connect(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(storePersistent())); + connect(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(checkPersistent())); } public slots: @@ -235,7 +235,7 @@ public slots: void storePersistent() { - // This method is called from layoutAboutToBeChanged. Persistent indexes should be valid + // This method is called from rowsAboutToBeMoved. Persistent indexes should be valid foreach(const QModelIndex &idx, m_persistentProxyIndexes) if (!idx.isValid()) { qWarning("%s: persistentProxyIndexes contains invalid index", Q_FUNC_INFO); diff --git a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp index 625ed3b82a..2a838c0e3d 100644 --- a/tests/auto/other/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/other/qaccessibility/tst_qaccessibility.cpp @@ -141,7 +141,7 @@ static inline int indexOfChild(QAccessibleInterface *parentInterface, QWidget *c { if (!parentInterface || !childWidget) return -1; - QAccessibleInterface *childInterface = QAccessibleInterface::queryAccessibleInterface(childWidget); + QAccessibleInterface *childInterface = QAccessible::queryAccessibleInterface(childWidget); if (!childInterface) return -1; int index = parentInterface->indexOfChild(childInterface); @@ -344,9 +344,9 @@ class QtTestAccessibleWidgetIface: public QAccessibleWidget { public: QtTestAccessibleWidgetIface(QtTestAccessibleWidget *w): QAccessibleWidget(w) {} - QString text(Text t) const + QString text(QAccessible::Text t) const { - if (t == Help) + if (t == QAccessible::Help) return QString::fromLatin1("Help yourself"); return QAccessibleWidget::text(t); } @@ -1877,8 +1877,8 @@ void tst_QAccessibility::mdiSubWindowTest() QCOMPARE(interface->state(), state); const QRect originalGeometry = testWindow->geometry(); testWindow->showMaximized(); - state &= ~QAccessible::Sizeable; - state &= ~QAccessible::Movable; + state &= (uint)~QAccessible::Sizeable; + state &= (uint)~QAccessible::Movable; QCOMPARE(interface->state(), state); testWindow->showNormal(); testWindow->move(-10, 0); @@ -2526,7 +2526,7 @@ void tst_QAccessibility::listTest() QVERIFY(cellInterface); QCOMPARE(cellInterface->rowIndex(), 3); QCOMPARE(cellInterface->columnIndex(), 0); - QVERIFY(!cellInterface->isExpandable()); + QVERIFY(!(cell4->state() & QAccessible::Expandable)); delete cell4; delete cell1; @@ -2620,7 +2620,7 @@ void tst_QAccessibility::treeTest() QCOMPARE(cell2->role(), QAccessible::TreeItem); QCOMPARE(cell2->tableCellInterface()->rowIndex(), 1); QCOMPARE(cell2->tableCellInterface()->columnIndex(), 0); - QVERIFY(cell2->tableCellInterface()->isExpandable()); + QVERIFY(cell2->state() & QAccessible::Expandable); QCOMPARE(iface->indexOfChild(cell2), 5); QVERIFY(!(cell2->state() & QAccessible::Expanded)); QCOMPARE(table2->columnDescription(1), QString("Work")); @@ -2644,7 +2644,7 @@ void tst_QAccessibility::treeTest() QCOMPARE(cell2->role(), QAccessible::TreeItem); QCOMPARE(cell2->tableCellInterface()->rowIndex(), 4); QCOMPARE(cell2->tableCellInterface()->columnIndex(), 0); - QVERIFY(!cell2->tableCellInterface()->isExpandable()); + QVERIFY(!(cell2->state() & QAccessible::Expandable)); QCOMPARE(iface->indexOfChild(cell2), 11); QCOMPARE(table2->columnDescription(0), QString("Artist")); diff --git a/tests/auto/testlib/selftests/.gitignore b/tests/auto/testlib/selftests/.gitignore index 56ba17abd7..98a3f49081 100644 --- a/tests/auto/testlib/selftests/.gitignore +++ b/tests/auto/testlib/selftests/.gitignore @@ -13,7 +13,6 @@ fetchbogus/tst_fetchbogus globaldata/tst_globaldata maxwarnings/tst_maxwarnings multiexec/tst_multiexec -qexecstringlist/tst_qexecstringlist singleskip/tst_singleskip skip/tst_skip skipglobal/tst_skipglobal diff --git a/tests/auto/testlib/selftests/qexecstringlist/qexecstringlist.pro b/tests/auto/testlib/selftests/qexecstringlist/qexecstringlist.pro deleted file mode 100644 index de8a7da37e..0000000000 --- a/tests/auto/testlib/selftests/qexecstringlist/qexecstringlist.pro +++ /dev/null @@ -1,8 +0,0 @@ -SOURCES += tst_qexecstringlist.cpp -QT = core testlib - -mac:CONFIG -= app_bundle -CONFIG -= debug_and_release_target - - -TARGET = qexecstringlist diff --git a/tests/auto/testlib/selftests/selftests.pro b/tests/auto/testlib/selftests/selftests.pro index 68239754aa..b4c4255dfc 100644 --- a/tests/auto/testlib/selftests/selftests.pro +++ b/tests/auto/testlib/selftests/selftests.pro @@ -3,7 +3,7 @@ TEMPLATE = subdirs SUBDIRS = subtest test warnings maxwarnings cmptest globaldata skip \ strcmp expectfail sleep fetchbogus crashes multiexec failinit failinitdata \ skipinit skipinitdata datetime singleskip assert differentexec \ - exceptionthrow qexecstringlist datatable commandlinedata\ + exceptionthrow datatable commandlinedata \ benchlibwalltime benchlibcallgrind benchlibeventcounter benchlibtickcounter \ benchliboptions xunit badxml longstring float printdatatags \ printdatatagswithglobaltags findtestdata diff --git a/tests/auto/testlib/selftests/selftests.qrc b/tests/auto/testlib/selftests/selftests.qrc index fb303af2b5..5090fa7378 100644 --- a/tests/auto/testlib/selftests/selftests.qrc +++ b/tests/auto/testlib/selftests/selftests.qrc @@ -95,7 +95,6 @@ expected_multiexec.xunitxml expected_printdatatags.txt expected_printdatatagswithglobaltags.txt - expected_qexecstringlist.txt expected_singleskip.lightxml expected_singleskip.txt expected_singleskip.xml diff --git a/tests/auto/testlib/selftests/tst_selftests.cpp b/tests/auto/testlib/selftests/tst_selftests.cpp index b98a02aa4e..f7a485b857 100644 --- a/tests/auto/testlib/selftests/tst_selftests.cpp +++ b/tests/auto/testlib/selftests/tst_selftests.cpp @@ -327,7 +327,6 @@ void tst_Selftests::runSubTest_data() << "multiexec" << "printdatatags" << "printdatatagswithglobaltags" - << "qexecstringlist" << "singleskip" << "skip" << "skipinit" @@ -392,9 +391,6 @@ void tst_Selftests::runSubTest_data() if (subtest == "multiexec") { continue; } - if (subtest == "qexecstringlist") { - continue; - } if (subtest == "benchliboptions") { continue; } @@ -430,11 +426,20 @@ void tst_Selftests::runSubTest_data() } } +static inline QProcessEnvironment processEnvironment() +{ + QProcessEnvironment result; + const QString path = QStringLiteral("PATH"); + result.insert(path, QProcessEnvironment::systemEnvironment().value(path)); + return result; +} + void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& loggers, QStringList const& arguments) { QProcess proc; - proc.setEnvironment(QStringList("")); - proc.start(subdir + "/" + subdir, arguments); + static const QProcessEnvironment environment = processEnvironment(); + proc.setProcessEnvironment(environment); + proc.start(subdir + QLatin1Char('/') + subdir, arguments); QVERIFY2(proc.waitForFinished(), qPrintable(proc.errorString())); QList actualOutputs; @@ -473,6 +478,15 @@ void tst_Selftests::doRunSubTest(QString const& subdir, QStringList const& logge QString logger = loggers[n]; QList res = splitLines(actualOutputs[n]); QList exp = expectedResult(subdir, logger); +#ifdef Q_CC_MSVC + // MSVC formats double numbers differently + if (n == 0 && subdir == QStringLiteral("float")) { + for (int i = 0; i < exp.size(); ++i) { + exp[i].replace("e-07", "e-007"); + exp[i].replace("e+07", "e+007"); + } + } +#endif // For the "crashes" test, there are multiple versions of the // expected output. Load the one with the same line count as diff --git a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp index 8a2fdc97f3..8474293a54 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsitem/tst_qgraphicsitem.cpp @@ -10791,7 +10791,10 @@ void tst_QGraphicsItem::touchEventPropagation() touchPoints << tp; sendMousePress(&scene, tp.scenePos()); - QTouchEvent touchBegin(QEvent::TouchBegin, QTouchEvent::TouchScreen, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + QTouchEvent touchBegin(QEvent::TouchBegin, device, Qt::NoModifier, Qt::TouchPointPressed, touchPoints); qApp->sendEvent(&scene, &touchBegin); QCOMPARE(touchEventReceiver->touchBeginEventCount, expectedCount); diff --git a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp index cc3fd85da6..bf547cc7d9 100644 --- a/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/widgets/itemviews/qheaderview/tst_qheaderview.cpp @@ -60,16 +60,6 @@ Q_DECLARE_METATYPE(IntList) typedef QList BoolList; Q_DECLARE_METATYPE(BoolList) -// Will try to wait for the condition while allowing event processing -// for a maximum of 2 seconds. -#define WAIT_FOR_CONDITION(expr, expected) \ - do { \ - const int step = 100; \ - for (int i = 0; i < 2000 && expr != expected; i+=step) { \ - QTest::qWait(step); \ - } \ - } while(0) - class protected_QHeaderView : public QHeaderView { Q_OBJECT @@ -1447,23 +1437,12 @@ void tst_QHeaderView::focusPolicy() QApplication::setActiveWindow(&widget); QTest::qWaitForWindowShown(&widget); widget.activateWindow(); - QTest::qWait(100); - - qApp->processEvents(); - - WAIT_FOR_CONDITION(widget.hasFocus(), true); - - QVERIFY(widget.hasFocus()); + QTRY_VERIFY(widget.hasFocus()); QVERIFY(!widget.header()->hasFocus()); widget.setFocusPolicy(Qt::NoFocus); widget.clearFocus(); - - qApp->processEvents(); - qApp->processEvents(); - - WAIT_FOR_CONDITION(widget.hasFocus(), false); - QVERIFY(!widget.hasFocus()); + QTRY_VERIFY(!widget.hasFocus()); QVERIFY(!widget.header()->hasFocus()); QTest::keyPress(&widget, Qt::Key_Tab); diff --git a/tests/auto/widgets/itemviews/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/widgets/itemviews/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index fb5fe579a6..cc8299e28f 100644 --- a/tests/auto/widgets/itemviews/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/widgets/itemviews/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -148,6 +148,7 @@ private slots: void filteredColumns(); void testParentLayoutChanged(); + void moveSourceRows(); protected: void buildHierarchy(const QStringList &data, QAbstractItemModel *model); @@ -3232,6 +3233,16 @@ void tst_QSortFilterProxyModel::testParentLayoutChanged() proxy.setDynamicSortFilter(true); proxy.setSourceModel(&model); + proxy.setObjectName("proxy"); + + // When Proxy1 emits layoutChanged(QList) this + // one will too, with mapped indexes. + QSortFilterProxyModel proxy2; + proxy2.sort(0, Qt::AscendingOrder); + proxy2.setDynamicSortFilter(true); + + proxy2.setSourceModel(&proxy); + proxy2.setObjectName("proxy2"); qRegisterMetaType >(); @@ -3244,6 +3255,9 @@ void tst_QSortFilterProxyModel::testParentLayoutChanged() QSignalSpy parentsAboutToBeChangedSpy(&proxy, SIGNAL(layoutAboutToBeChanged(QList))); QSignalSpy parentsChangedSpy(&proxy, SIGNAL(layoutChanged(QList))); + QSignalSpy proxy2ParentsAboutToBeChangedSpy(&proxy2, SIGNAL(layoutAboutToBeChanged(QList))); + QSignalSpy proxy2ParentsChangedSpy(&proxy2, SIGNAL(layoutChanged(QList))); + QStandardItem *item = model.invisibleRootItem()->child(1)->child(1); // Ensure mapped: @@ -3256,6 +3270,8 @@ void tst_QSortFilterProxyModel::testParentLayoutChanged() QCOMPARE(layoutChangedSpy.size(), 1); QCOMPARE(parentsAboutToBeChangedSpy.size(), 1); QCOMPARE(parentsChangedSpy.size(), 1); + QCOMPARE(proxy2ParentsAboutToBeChangedSpy.size(), 1); + QCOMPARE(proxy2ParentsChangedSpy.size(), 1); QVariantList beforeSignal = parentsAboutToBeChangedSpy.first(); QVariantList afterSignal = parentsChangedSpy.first(); @@ -3274,6 +3290,173 @@ void tst_QSortFilterProxyModel::testParentLayoutChanged() QVERIFY(beforeParents.first() == proxy.mapFromSource(model.indexFromItem(model.invisibleRootItem()->child(1)))); + QList proxy2BeforeList = proxy2ParentsAboutToBeChangedSpy.first().first().value >(); + QList proxy2AfterList = proxy2ParentsChangedSpy.first().first().value >(); + + QCOMPARE(proxy2BeforeList.size(), beforeParents.size()); + QCOMPARE(proxy2AfterList.size(), afterParents.size()); + foreach (const QPersistentModelIndex &idx, proxy2BeforeList) + QVERIFY(beforeParents.contains(proxy2.mapToSource(idx))); + foreach (const QPersistentModelIndex &idx, proxy2AfterList) + QVERIFY(afterParents.contains(proxy2.mapToSource(idx))); + +} + +class SignalArgumentChecker : public QObject +{ + Q_OBJECT +public: + SignalArgumentChecker(QAbstractItemModel *model, QAbstractProxyModel *proxy, QObject *parent = 0) + : QObject(parent), m_model(model), m_proxy(proxy) + { + connect(model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + connect(model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)), SLOT(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + connect(proxy, SIGNAL(layoutAboutToBeChanged(QList)), SLOT(layoutAboutToBeChanged(QList))); + connect(proxy, SIGNAL(layoutChanged(QList)), SLOT(layoutChanged(QList))); + } + +private slots: + void rowsAboutToBeMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int) + { + m_p1PersistentBefore = source; + m_p2PersistentBefore = destination; + m_p2FirstProxyChild = m_proxy->index(0, 0, m_proxy->mapFromSource(destination)); + } + + void rowsMoved(const QModelIndex &source, int, int, const QModelIndex &destination, int) + { + m_p1PersistentAfter = source; + m_p2PersistentAfter = destination; + } + + void layoutAboutToBeChanged(const QList &parents) + { + QVERIFY(m_p1PersistentBefore.isValid()); + QVERIFY(m_p2PersistentBefore.isValid()); + QCOMPARE(parents.size(), 2); + QVERIFY(parents.first() != parents.at(1)); + QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentBefore))); + QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentBefore))); + } + + void layoutChanged(const QList &parents) + { + QVERIFY(m_p1PersistentAfter.isValid()); + QVERIFY(m_p2PersistentAfter.isValid()); + QCOMPARE(parents.size(), 2); + QVERIFY(parents.first() != parents.at(1)); + QVERIFY(parents.contains(m_proxy->mapFromSource(m_p1PersistentAfter))); + QVERIFY(parents.contains(m_proxy->mapFromSource(m_p2PersistentAfter))); + + // In the source model, the rows were moved to row 1 in the parent. + // m_p2FirstProxyChild was created with row 0 in the proxy. + // The moved rows in the proxy do not appear at row 1 because of sorting. + // Sorting causes them to appear at row 0 instead, pushing what used to + // be row 0 in the proxy down by two rows. + QCOMPARE(m_p2FirstProxyChild.row(), 2); + } + +private: + QAbstractItemModel *m_model; + QAbstractProxyModel *m_proxy; + QPersistentModelIndex m_p1PersistentBefore; + QPersistentModelIndex m_p2PersistentBefore; + QPersistentModelIndex m_p1PersistentAfter; + QPersistentModelIndex m_p2PersistentAfter; + + QPersistentModelIndex m_p2FirstProxyChild; +}; + +void tst_QSortFilterProxyModel::moveSourceRows() +{ + qRegisterMetaType >(); + + DynamicTreeModel model; + + { + ModelInsertCommand insertCommand(&model); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList() << 2); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList() << 5); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + + QSortFilterProxyModel proxy; + proxy.setDynamicSortFilter(true); + proxy.sort(0, Qt::AscendingOrder); + + // We need to check the arguments at emission time + SignalArgumentChecker checker(&model, &proxy); + + proxy.setSourceModel(&model); + + QSortFilterProxyModel filterProxy; + filterProxy.setDynamicSortFilter(true); + filterProxy.sort(0, Qt::AscendingOrder); + filterProxy.setSourceModel(&proxy); + filterProxy.setFilterRegExp("6"); // One of the parents + + QSortFilterProxyModel filterBothProxy; + filterBothProxy.setDynamicSortFilter(true); + filterBothProxy.sort(0, Qt::AscendingOrder); + filterBothProxy.setSourceModel(&proxy); + filterBothProxy.setFilterRegExp("5"); // The parents are 6 and 3. This filters both out. + + QSignalSpy modelBeforeSpy(&model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy modelAfterSpy(&model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy proxyBeforeMoveSpy(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy proxyAfterMoveSpy(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy proxyBeforeParentLayoutSpy(&proxy, SIGNAL(layoutAboutToBeChanged(QList))); + QSignalSpy proxyAfterParentLayoutSpy(&proxy, SIGNAL(layoutChanged(QList))); + QSignalSpy filterBeforeParentLayoutSpy(&filterProxy, SIGNAL(layoutAboutToBeChanged(QList))); + QSignalSpy filterAfterParentLayoutSpy(&filterProxy, SIGNAL(layoutChanged(QList))); + QSignalSpy filterBothBeforeParentLayoutSpy(&filterBothProxy, SIGNAL(layoutAboutToBeChanged(QList))); + QSignalSpy filterBothAfterParentLayoutSpy(&filterBothProxy, SIGNAL(layoutChanged(QList))); + + { + ModelMoveCommand moveCommand(&model, 0); + moveCommand.setAncestorRowNumbers(QList() << 2); + moveCommand.setDestAncestors(QList() << 5); + moveCommand.setStartRow(3); + moveCommand.setEndRow(4); + moveCommand.setDestRow(1); + moveCommand.doCommand(); + } + + // Proxy notifies layout change + QCOMPARE(modelBeforeSpy.size(), 1); + QCOMPARE(proxyBeforeParentLayoutSpy.size(), 1); + QCOMPARE(modelAfterSpy.size(), 1); + QCOMPARE(proxyAfterParentLayoutSpy.size(), 1); + + // But it doesn't notify a move. + QCOMPARE(proxyBeforeMoveSpy.size(), 0); + QCOMPARE(proxyAfterMoveSpy.size(), 0); + + QCOMPARE(filterBeforeParentLayoutSpy.size(), 1); + QCOMPARE(filterAfterParentLayoutSpy.size(), 1); + + QList filterBeforeParents = filterBeforeParentLayoutSpy.first().first().value >(); + QList filterAfterParents = filterAfterParentLayoutSpy.first().first().value >(); + + QCOMPARE(filterBeforeParents.size(), 1); + QCOMPARE(filterAfterParents.size(), 1); + + QCOMPARE(filterBothBeforeParentLayoutSpy.size(), 0); + QCOMPARE(filterBothAfterParentLayoutSpy.size(), 0); } QTEST_MAIN(tst_QSortFilterProxyModel) diff --git a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp index 84aa8c7180..383fcf8b3f 100644 --- a/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp +++ b/tests/auto/widgets/itemviews/qtableview/tst_qtableview.cpp @@ -46,16 +46,6 @@ #include #include "private/qapplication_p.h" -// Will try to wait for the condition while allowing event processing -// for a maximum of 2 seconds. -#define WAIT_FOR_CONDITION(expr, expected) \ - do { \ - const int step = 100; \ - for (int i = 0; i < 2000 && expr != expected; i+=step) { \ - QTest::qWait(step); \ - } \ - } while(0) - #ifdef QT_BUILD_INTERNAL #define VERIFY_SPANS_CONSISTENCY(TEST_VIEW_) \ QVERIFY(static_cast(QObjectPrivate::get(TEST_VIEW_))->spans.checkConsistency()) @@ -3358,16 +3348,9 @@ void tst_QTableView::tabFocus() window.setFocus(); QTest::qWait(100); window.activateWindow(); - QTest::qWait(100); - - qApp->processEvents(); - - WAIT_FOR_CONDITION(window.hasFocus(), true); - - qApp->processEvents(); // window - QVERIFY(window.hasFocus()); + QTRY_VERIFY(window.hasFocus()); QVERIFY(!view->hasFocus()); QVERIFY(!edit->hasFocus()); diff --git a/tests/auto/widgets/kernel/kernel.pro b/tests/auto/widgets/kernel/kernel.pro index f6d0902533..d1f2304378 100644 --- a/tests/auto/widgets/kernel/kernel.pro +++ b/tests/auto/widgets/kernel/kernel.pro @@ -9,7 +9,6 @@ SUBDIRS=\ qgridlayout \ qinputcontext \ qlayout \ - qsound \ qstackedlayout \ qtooltip \ qwidget \ diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 8cf85dd8ea..81cdffe4e5 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -1933,27 +1933,31 @@ void tst_QApplication::touchEventPropagation() release.setState(Qt::TouchPointReleased); releasedTouchPoints << release; + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + { // touch event behavior on a window TouchEventPropagationTestWidget window; window.setObjectName("1. window"); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(!window.seenTouchEvent); QVERIFY(!window.seenMouseEvent); window.reset(); window.setAttribute(Qt::WA_AcceptTouchEvents); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(window.seenTouchEvent); QVERIFY(!window.seenMouseEvent); window.reset(); window.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(window.seenTouchEvent); QVERIFY(!window.seenMouseEvent); } @@ -1965,8 +1969,8 @@ void tst_QApplication::touchEventPropagation() TouchEventPropagationTestWidget widget(&window); widget.setObjectName("2. widget"); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); @@ -1975,8 +1979,8 @@ void tst_QApplication::touchEventPropagation() window.reset(); widget.reset(); widget.setAttribute(Qt::WA_AcceptTouchEvents); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); @@ -1985,8 +1989,8 @@ void tst_QApplication::touchEventPropagation() window.reset(); widget.reset(); widget.acceptMouseEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); @@ -1995,8 +1999,8 @@ void tst_QApplication::touchEventPropagation() window.reset(); widget.reset(); widget.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(!window.seenTouchEvent); @@ -2006,8 +2010,8 @@ void tst_QApplication::touchEventPropagation() widget.reset(); widget.setAttribute(Qt::WA_AcceptTouchEvents, false); window.setAttribute(Qt::WA_AcceptTouchEvents); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); @@ -2016,8 +2020,8 @@ void tst_QApplication::touchEventPropagation() window.reset(); widget.reset(); window.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); @@ -2027,8 +2031,8 @@ void tst_QApplication::touchEventPropagation() widget.reset(); widget.acceptMouseEvent = true; // doesn't matter, touch events are propagated first window.acceptTouchEvent = true; - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, pressedTouchPoints, 0); - qt_translateRawTouchEvent(&window, QTouchEvent::TouchScreen, releasedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, pressedTouchPoints, 0); + qt_translateRawTouchEvent(&window, device, releasedTouchPoints, 0); QVERIFY(!widget.seenTouchEvent); QVERIFY(!widget.seenMouseEvent); QVERIFY(window.seenTouchEvent); diff --git a/tests/auto/widgets/kernel/qsound/.gitignore b/tests/auto/widgets/kernel/qsound/.gitignore deleted file mode 100644 index c9d313c2cf..0000000000 --- a/tests/auto/widgets/kernel/qsound/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tst_qsound diff --git a/tests/auto/widgets/kernel/qsound/4.wav b/tests/auto/widgets/kernel/qsound/4.wav deleted file mode 100644 index e31b060908..0000000000 Binary files a/tests/auto/widgets/kernel/qsound/4.wav and /dev/null differ diff --git a/tests/auto/widgets/kernel/qsound/qsound.pro b/tests/auto/widgets/kernel/qsound/qsound.pro deleted file mode 100644 index 8317283d54..0000000000 --- a/tests/auto/widgets/kernel/qsound/qsound.pro +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG += testcase -TARGET = tst_qsound -SOURCES += tst_qsound.cpp -QT += testlib widgets - -wince* { - deploy.files += 4.wav - DEPLOYMENT += deploy - DEFINES += SRCDIR=\\\"\\\" -} else { - DEFINES += SRCDIR=\\\"$$PWD/\\\" -} diff --git a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp index c8c8136f44..a7912aedc1 100644 --- a/tests/auto/widgets/util/qscroller/tst_qscroller.cpp +++ b/tests/auto/widgets/util/qscroller/tst_qscroller.cpp @@ -162,8 +162,11 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchPoint.setPos(touchStart); touchPoint.setScenePos(touchStart); touchPoint.setScreenPos(touchStart); + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); QTouchEvent touchEvent1(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + device, Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); @@ -177,7 +180,7 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchPoint.setScenePos(touchUpdate); touchPoint.setScreenPos(touchUpdate); QTouchEvent touchEvent2(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, + device, Qt::NoModifier, Qt::TouchPointMoved, (QList() << touchPoint)); @@ -202,7 +205,7 @@ void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchPoint.setScenePos(touchEnd); touchPoint.setScreenPos(touchEnd); QTouchEvent touchEvent5(QEvent::TouchEnd, - QTouchEvent::TouchScreen, + device, Qt::NoModifier, Qt::TouchPointReleased, (QList() << touchPoint)); @@ -233,8 +236,11 @@ void tst_QScroller::kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, touchPoint.setPos(touchStart); touchPoint.setScenePos(touchStart); touchPoint.setScreenPos(touchStart); + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); QTouchEvent touchEvent1(QEvent::TouchBegin, - QTouchEvent::TouchScreen, + device, Qt::NoModifier, Qt::TouchPointPressed, (QList() << touchPoint)); @@ -246,7 +252,7 @@ void tst_QScroller::kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, touchPoint.setScenePos(touchUpdate); touchPoint.setScreenPos(touchUpdate); QTouchEvent touchEvent2(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, + device, Qt::NoModifier, Qt::TouchPointMoved, (QList() << touchPoint)); @@ -259,7 +265,7 @@ void tst_QScroller::kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, touchPoint.setScenePos(touchEnd); touchPoint.setScreenPos(touchEnd); QTouchEvent touchEvent5(QEvent::TouchEnd, - QTouchEvent::TouchScreen, + device, Qt::NoModifier, Qt::TouchPointReleased, (QList() << touchPoint)); diff --git a/tests/manual/cmake/CMakeLists.txt b/tests/manual/cmake/CMakeLists.txt index b6d5f318fd..1f2bd3e80a 100644 --- a/tests/manual/cmake/CMakeLists.txt +++ b/tests/manual/cmake/CMakeLists.txt @@ -29,3 +29,5 @@ endmacro() # expect_pass(pass1) expect_pass(pass2) expect_pass(pass3) +expect_fail(fail4) +expect_fail(fail5) diff --git a/tests/manual/cmake/fail4/CMakeLists.txt b/tests/manual/cmake/fail4/CMakeLists.txt new file mode 100644 index 0000000000..dcd4b8bd65 --- /dev/null +++ b/tests/manual/cmake/fail4/CMakeLists.txt @@ -0,0 +1,18 @@ + +cmake_minimum_required(VERSION 2.8) + +project(pass4) + +find_package(Qt5Core REQUIRED) + +include_directories(${Qt5Core_INCLUDE_DIRS}) + +qt5_wrap_cpp(moc_files myobject.h) + +# Test options. The -binary option generates a binary to dlopen instead of +# a source file to compile. The compiler will consider it garbage when used +# in the add_executable call. +qt5_add_resources(rcc_files "pass4.qrc" OPTIONS -binary) + +add_executable(myobject myobject.cpp ${moc_files} ${rcc_files}) +target_link_libraries(myobject ${Qt5Core_LIBRARIES}) diff --git a/tests/auto/testlib/selftests/qexecstringlist/tst_qexecstringlist.cpp b/tests/manual/cmake/fail4/myobject.cpp similarity index 59% rename from tests/auto/testlib/selftests/qexecstringlist/tst_qexecstringlist.cpp rename to tests/manual/cmake/fail4/myobject.cpp index aacfab76f1..251239cde0 100644 --- a/tests/auto/testlib/selftests/qexecstringlist/tst_qexecstringlist.cpp +++ b/tests/manual/cmake/fail4/myobject.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -39,58 +39,16 @@ ** ****************************************************************************/ +#include "myobject.h" -#include -#include - -class tst_QExecStringList: public QObject -{ - Q_OBJECT - -private slots: - void testA() const; - void testB() const; - void testB_data() const; - void testC() const; -}; - -void tst_QExecStringList::testA() const +MyObject::MyObject(QObject *parent) + : QObject(parent) { + emit someSignal(); } -void tst_QExecStringList::testB() const +int main(int argc, char **argv) { - QFETCH(bool, dummy); - Q_UNUSED(dummy); -} - -void tst_QExecStringList::testB_data() const -{ - QTest::addColumn("dummy"); - - QTest::newRow("Data1") << false; - QTest::newRow("Data2") << false; - QTest::newRow("Data3") << false; -} - -void tst_QExecStringList::testC() const -{ -} - -int main(int argc,char *argv[]) -{ - QCoreApplication app(argc, argv); - - tst_QExecStringList test; - - QTest::qExec(&test, app.arguments()); - QTest::qExec(&test, QStringList("appName")); - QTest::qExec(&test, QStringList("appName") << "testA"); - QTest::qExec(&test, QStringList("appName") << "testB"); - QTest::qExec(&test, QStringList("appName") << "testB:Data2"); - QTest::qExec(&test, QStringList("appName") << "testC"); - + MyObject myObject; return 0; } - -#include "tst_qexecstringlist.moc" diff --git a/tests/manual/cmake/fail4/myobject.h b/tests/manual/cmake/fail4/myobject.h new file mode 100644 index 0000000000..e2e908d32c --- /dev/null +++ b/tests/manual/cmake/fail4/myobject.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include + +class MyObject : public QObject +{ + Q_OBJECT +public: + MyObject(QObject *parent = 0); + +signals: + void someSignal(); +}; + +#endif diff --git a/tests/manual/cmake/fail4/pass4.qrc b/tests/manual/cmake/fail4/pass4.qrc new file mode 100644 index 0000000000..00a17f541f --- /dev/null +++ b/tests/manual/cmake/fail4/pass4.qrc @@ -0,0 +1,6 @@ + + + resource_file.txt + + + diff --git a/tests/manual/cmake/fail4/resource_file.txt b/tests/manual/cmake/fail4/resource_file.txt new file mode 100644 index 0000000000..2c604a4f18 --- /dev/null +++ b/tests/manual/cmake/fail4/resource_file.txt @@ -0,0 +1 @@ +Ken sent me. diff --git a/tests/manual/cmake/fail5/CMakeLists.txt b/tests/manual/cmake/fail5/CMakeLists.txt new file mode 100644 index 0000000000..f82a62b626 --- /dev/null +++ b/tests/manual/cmake/fail5/CMakeLists.txt @@ -0,0 +1,15 @@ + +cmake_minimum_required(VERSION 2.8) + +project(pass5) + +find_package(Qt5Core REQUIRED) + +include_directories(${Qt5Core_INCLUDE_DIRS}) + +# Test options. The -i option removes the include "myobject.h" from the moc file +# causing a compile failure. -> Options work +qt5_wrap_cpp(moc_files myobject.h OPTIONS -i) + +add_executable(myobject myobject.cpp ${moc_files}) +target_link_libraries(myobject ${Qt5Core_LIBRARIES}) diff --git a/tests/manual/cmake/fail5/myobject.cpp b/tests/manual/cmake/fail5/myobject.cpp new file mode 100644 index 0000000000..251239cde0 --- /dev/null +++ b/tests/manual/cmake/fail5/myobject.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "myobject.h" + +MyObject::MyObject(QObject *parent) + : QObject(parent) +{ + emit someSignal(); +} + +int main(int argc, char **argv) +{ + MyObject myObject; + return 0; +} diff --git a/tests/manual/cmake/fail5/myobject.h b/tests/manual/cmake/fail5/myobject.h new file mode 100644 index 0000000000..e2e908d32c --- /dev/null +++ b/tests/manual/cmake/fail5/myobject.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include + +class MyObject : public QObject +{ + Q_OBJECT +public: + MyObject(QObject *parent = 0); + +signals: + void someSignal(); +}; + +#endif diff --git a/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt b/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt new file mode 100644 index 0000000000..cc1a1bc588 --- /dev/null +++ b/tests/manual/cmake/pass(needsquoting)6/CMakeLists.txt @@ -0,0 +1,18 @@ + +cmake_minimum_required(VERSION 2.8) + +project("pass(needsquoting)6") + +find_package(Qt5Core REQUIRED) +find_package(Qt5Gui REQUIRED) +find_package(Qt5Widgets REQUIRED) + +include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS}) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +qt5_wrap_cpp(moc_files mywidget.h) +qt5_wrap_ui(ui_files mywidget.ui) + +add_executable(mywidget mywidget.cpp ${moc_files} ${ui_files}) +target_link_libraries(mywidget ${Qt5Widgets_LIBRARIES}) diff --git a/tests/manual/cmake/pass(needsquoting)6/mywidget.cpp b/tests/manual/cmake/pass(needsquoting)6/mywidget.cpp new file mode 100644 index 0000000000..75804f9b3c --- /dev/null +++ b/tests/manual/cmake/pass(needsquoting)6/mywidget.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mywidget.h" +#include "ui_mywidget.h" + +MyWidget::MyWidget(QWidget *parent) + : QWidget(parent) +{ + emit someSignal(); +} + +int main(int argc, char **argv) +{ + MyWidget myWidget; + return 0; +} diff --git a/tests/auto/widgets/kernel/qsound/tst_qsound.cpp b/tests/manual/cmake/pass(needsquoting)6/mywidget.h similarity index 66% rename from tests/auto/widgets/kernel/qsound/tst_qsound.cpp rename to tests/manual/cmake/pass(needsquoting)6/mywidget.h index 5f1e5fb47c..0f59d3835e 100644 --- a/tests/auto/widgets/kernel/qsound/tst_qsound.cpp +++ b/tests/manual/cmake/pass(needsquoting)6/mywidget.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** @@ -39,45 +39,27 @@ ** ****************************************************************************/ +#ifndef MYWIDGET_H +#define MYWIDGET_H -#include -#include +#include -class tst_QSound : public QObject +namespace Ui +{ +class MyWidget; +} + +class MyWidget : public QWidget { Q_OBJECT - public: - tst_QSound( QObject* parent=0) : QObject(parent) {} + MyWidget(QWidget *parent = 0); -private slots: - void checkFinished(); +signals: + void someSignal(); - // Manual tests - void staticPlay(); +private: + Ui::MyWidget *ui; }; -void tst_QSound::checkFinished() -{ - QSKIP("QSound is not implemented on Lighthouse"); - QSound sound(SRCDIR"4.wav"); - sound.setLoops(3); - sound.play(); - QTest::qWait(5000); - -#if defined(Q_WS_QWS) - QEXPECT_FAIL("", "QSound buggy on embedded (task QTBUG-157)", Abort); #endif - QVERIFY(sound.isFinished() ); -} - -void tst_QSound::staticPlay() -{ - QSKIP("Test disabled -- only for manual purposes"); - // Check that you hear sound with static play also. - QSound::play(SRCDIR"4.wav"); - QTest::qWait(2000); -} - -QTEST_MAIN(tst_QSound); -#include "tst_qsound.moc" diff --git a/tests/manual/cmake/pass(needsquoting)6/mywidget.ui b/tests/manual/cmake/pass(needsquoting)6/mywidget.ui new file mode 100644 index 0000000000..ac42ac4dc2 --- /dev/null +++ b/tests/manual/cmake/pass(needsquoting)6/mywidget.ui @@ -0,0 +1,34 @@ + + + Form + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + PushButton + + + + + + + + + + + + + + diff --git a/tests/manual/cmake/pass2/CMakeLists.txt b/tests/manual/cmake/pass2/CMakeLists.txt index 153b038c02..ac1bb15846 100644 --- a/tests/manual/cmake/pass2/CMakeLists.txt +++ b/tests/manual/cmake/pass2/CMakeLists.txt @@ -9,5 +9,7 @@ include_directories(${Qt5Core_INCLUDE_DIRS}) qt5_wrap_cpp(moc_files myobject.h) -add_executable(myobject myobject.cpp ${moc_files}) +qt5_add_resources(rcc_files "pass2.qrc") + +add_executable(myobject myobject.cpp ${moc_files} ${rcc_files}) target_link_libraries(myobject ${Qt5Core_LIBRARIES}) diff --git a/tests/manual/cmake/pass2/myobject.cpp b/tests/manual/cmake/pass2/myobject.cpp index 251239cde0..0f3d8b5b50 100644 --- a/tests/manual/cmake/pass2/myobject.cpp +++ b/tests/manual/cmake/pass2/myobject.cpp @@ -50,5 +50,7 @@ MyObject::MyObject(QObject *parent) int main(int argc, char **argv) { MyObject myObject; + // Compile error if the resource file was not created. + Q_INIT_RESOURCE(pass2); return 0; } diff --git a/tests/manual/cmake/pass2/pass2.qrc b/tests/manual/cmake/pass2/pass2.qrc new file mode 100644 index 0000000000..00a17f541f --- /dev/null +++ b/tests/manual/cmake/pass2/pass2.qrc @@ -0,0 +1,6 @@ + + + resource_file.txt + + + diff --git a/tests/manual/cmake/pass2/resource_file.txt b/tests/manual/cmake/pass2/resource_file.txt new file mode 100644 index 0000000000..2c604a4f18 --- /dev/null +++ b/tests/manual/cmake/pass2/resource_file.txt @@ -0,0 +1 @@ +Ken sent me. diff --git a/util/accessibilityinspector/accessibilityscenemanager.cpp b/util/accessibilityinspector/accessibilityscenemanager.cpp index 3d26a80de2..9c987271fc 100644 --- a/util/accessibilityinspector/accessibilityscenemanager.cpp +++ b/util/accessibilityinspector/accessibilityscenemanager.cpp @@ -351,7 +351,7 @@ AccessibilitySceneManager::TreeItem AccessibilitySceneManager::computeLevels(QAc // capture information: currentLevel.name = interface->text(QAccessible::Name); - //currentLevel.description += interface->text(QAccessible::DebugDescription); + currentLevel.description += interface->text(QAccessible::DebugDescription); currentLevel.role = translateRole(interface->role()); currentLevel.rect = interface->rect(); currentLevel.state = interface->state(); diff --git a/util/valgrind/suppressions_mac b/util/valgrind/suppressions_mac deleted file mode 100644 index b7005d360a..0000000000 --- a/util/valgrind/suppressions_mac +++ /dev/null @@ -1,138 +0,0 @@ -{ - __CFInitialize - Memcheck:Leak - ... - fun:dyld::__CFInitialize -} -{ - _objc_init - Memcheck:Leak - ... - fun:_objc_init -} -{ - dyld::initializeMainExecutable - Memcheck:Leak - ... - fun:dyld::initializeMainExecutable -} -{ - dyld::_dyld_start - Memcheck:Leak - ... - fun:_dyld_start -} -{ - _dispatch_mgr_thread - Memcheck:Leak - ... - fun:_dispatch_mgr_thread -} -{ - _Gestalt_SystemVersion - Memcheck:Leak - ... - fun:_Gestalt_SystemVersion -} -{ - _Gestalt_SystemVersion - Memcheck:Leak - ... - fun:start_wqthread -} - -{ - CGColorSpaceAdjustColor - Memcheck:Cond - fun:CGColorSpaceAdjustColor - ... -} -{ - CGSBlendRGBA8888toRGBA8888 - Memcheck:Cond - fun:CGSBlendRGBA8888toRGBA8888 - ... -} -{ - CGSConvertRGBX8888toRGBA8888 - Memcheck:Cond - fun:CGSConvertRGBX8888toRGBA8888 - ... -} -{ - WindowData::GetGlobalBounds - Memcheck:Cond - fun:WindowData::GetGlobalBounds* - ... -} -{ - WindowData::ResetPlatformWindowShape - Memcheck:Cond - fun:WindowData::ResetPlatformWindowShape - ... -} -{ - WindowData::UpdateColorSpace - Memcheck:Cond - fun:WindowData::WindowData::UpdateColorSpace* - ... -} -{ - WindowData::CUIRenderer::CreateImage - Memcheck:Cond - fun:WindowData::WindowData::CUIRenderer::CreateImage - ... -} -{ - WindowData::floor$fenv_access_off - Memcheck:Cond - fun:WindowData::floor$fenv_access_off - ... -} -{ - WindowData::SyncAutoTermination - Memcheck:Cond - fun:WindowData::SyncAutoTermination - ... -} -{ - FlushWindowObject - Memcheck:Cond - fun:FlushWindowObject - ... -} -{ - _HIDataConvert - Memcheck:Cond - fun:_HIDataConvert - ... -} -{ - GetPlatformWindowBoundsCommon - Memcheck:Cond - fun:GetPlatformWindowBoundsCommon - ... -} -{ - CGSBlend - Memcheck:Value8 - fun:CGSBlend* - ... -} -{ - sseCG - Memcheck:Value8 - fun:sseCG* - ... -} -{ - argb32_image_mark_rgb32 - Memcheck:Value8 - fun:argb32_image_mark_rgb32 - ... -} - - - - - diff --git a/util/valgrind/usage_mac b/util/valgrind/usage_mac deleted file mode 100644 index 507d663031..0000000000 --- a/util/valgrind/usage_mac +++ /dev/null @@ -1,16 +0,0 @@ -Valgrind on Mac instructions. - -As of Sept 16 2011, a patched version of valgrind can be used on OS X 10.7 Lion. - -1) Check out valgrind rev 12025 from source: -svn co svn://svn.valgrind.org/valgrind/trunk@12025 valgrind - -2) Download patch: https://bugs.kde.org/show_bug.cgi?id=275168#c20 - -3) Apply patch and build valgrind (see http://valgrind.org/downloads/repository.html) -Important: Use gcc-4.2 for building (export CC=gcc-4.2 before running configure) - -Supression file : suppressions_mac -Tested with valgrind command line: valgrind --log-file=log --show-reachable=yes --num-callers=50 --error-limit=no --leak-check=full --suppressions=suppressions_mac /Volumes/Build/qt5/qtbase/examples/widgets/calculator/calculator.app/Contents/MacOS/calculator - -