diff options
Diffstat (limited to 'src/corelib/kernel')
55 files changed, 2087 insertions, 1437 deletions
diff --git a/src/corelib/kernel/kernel.pri b/src/corelib/kernel/kernel.pri index 8c16e10c27..39fe61ea4e 100644 --- a/src/corelib/kernel/kernel.pri +++ b/src/corelib/kernel/kernel.pri @@ -4,6 +4,7 @@ HEADERS += \ kernel/qabstracteventdispatcher.h \ kernel/qabstractnativeeventfilter.h \ kernel/qbasictimer.h \ + kernel/qelapsedtimer.h \ kernel/qeventloop.h\ kernel/qpointer.h \ kernel/qcorecmdlineargs_p.h \ @@ -45,6 +46,7 @@ SOURCES += \ kernel/qabstracteventdispatcher.cpp \ kernel/qabstractnativeeventfilter.cpp \ kernel/qbasictimer.cpp \ + kernel/qelapsedtimer.cpp \ kernel/qeventloop.cpp \ kernel/qcoreapplication.cpp \ kernel/qcoreevent.cpp \ @@ -69,6 +71,7 @@ SOURCES += \ win32 { SOURCES += \ kernel/qcoreapplication_win.cpp \ + kernel/qelapsedtimer_win.cpp \ kernel/qwineventnotifier.cpp \ kernel/qsharedmemory_win.cpp \ kernel/qsystemsemaphore_win.cpp @@ -84,14 +87,6 @@ win32 { } } -wince { - SOURCES += \ - kernel/qfunctions_wince.cpp - HEADERS += \ - kernel/qfunctions_fake_env_p.h \ - kernel/qfunctions_wince.h -} - winrt { SOURCES += \ kernel/qfunctions_winrt.cpp @@ -109,7 +104,9 @@ mac { SOURCES += \ kernel/qcfsocketnotifier.cpp \ kernel/qcoreapplication_mac.cpp \ - kernel/qcore_mac.cpp + kernel/qcore_mac.cpp \ + kernel/qcore_foundation.mm + !nacl: SOURCES += kernel/qelapsedtimer_mac.cpp OBJECTIVE_SOURCES += \ kernel/qcore_mac_objc.mm \ @@ -119,7 +116,7 @@ mac { osx: LIBS_PRIVATE += -framework CoreServices -framework AppKit - ios { + uikit { # We need UIKit for UIDevice LIBS_PRIVATE += -framework UIKit } @@ -138,6 +135,7 @@ unix|integrity { kernel/qcrashhandler.cpp \ kernel/qeventdispatcher_unix.cpp \ kernel/qtimerinfo_unix.cpp + !darwin|nacl: SOURCES += kernel/qelapsedtimer_unix.cpp HEADERS += \ kernel/qcore_unix_p.h \ @@ -156,8 +154,8 @@ unix|integrity { kernel/qeventdispatcher_glib.cpp HEADERS += \ kernel/qeventdispatcher_glib_p.h - QMAKE_CXXFLAGS += $$QT_CFLAGS_GLIB - LIBS_PRIVATE +=$$QT_LIBS_GLIB + QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_GLIB + LIBS_PRIVATE +=$$QMAKE_LIBS_GLIB } contains(QT_CONFIG, clock-gettime):include($$QT_SOURCE_TREE/config.tests/unix/clock-gettime/clock-gettime.pri) @@ -203,3 +201,5 @@ android { kernel/qjnihelpers_p.h \ kernel/qjni_p.h } + +!darwin:!unix:!win32: SOURCES += kernel/qelapsedtimer_generic.cpp diff --git a/src/corelib/kernel/qcfsocketnotifier_p.h b/src/corelib/kernel/qcfsocketnotifier_p.h index c11c345361..12c5bf6334 100644 --- a/src/corelib/kernel/qcfsocketnotifier_p.h +++ b/src/corelib/kernel/qcfsocketnotifier_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include <QtCore/qabstracteventdispatcher.h> #include <QtCore/qhash.h> diff --git a/src/corelib/kernel/qcore_foundation.mm b/src/corelib/kernel/qcore_foundation.mm new file mode 100644 index 0000000000..2291017a5d --- /dev/null +++ b/src/corelib/kernel/qcore_foundation.mm @@ -0,0 +1,537 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2014 Samuel Gaist <samuel.gaist@edeltech.ch> +** Copyright (C) 2014 Petroules Corporation. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/qstring.h> +#include <QtCore/qurl.h> +#include <QtCore/qdatetime.h> +#include <QtCore/quuid.h> +#include <QtCore/qbytearray.h> +#include <QtCore/qrect.h> + +#import <Foundation/Foundation.h> + +#if defined(QT_PLATFORM_UIKIT) +#import <CoreGraphics/CoreGraphics.h> +#endif + +QT_BEGIN_NAMESPACE + +/*! + \since 5.3 + + Constructs a new QByteArray containing a copy of the CFData \a data. + + \sa fromRawCFData(), fromRawData(), toRawCFData(), toCFData() +*/ +QByteArray QByteArray::fromCFData(CFDataRef data) +{ + if (!data) + return QByteArray(); + + return QByteArray(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data)); +} + +/*! + \since 5.3 + + Constructs a QByteArray that uses the bytes of the CFData \a data. + + The \a data's bytes are not copied. + + The caller guarantees that the CFData will not be deleted + or modified as long as this QByteArray object exists. + + \sa fromCFData(), fromRawData(), toRawCFData(), toCFData() +*/ +QByteArray QByteArray::fromRawCFData(CFDataRef data) +{ + if (!data) + return QByteArray(); + + return QByteArray::fromRawData(reinterpret_cast<const char *>(CFDataGetBytePtr(data)), CFDataGetLength(data)); +} + +/*! + \since 5.3 + + Creates a CFData from a QByteArray. The caller owns the CFData object + and is responsible for releasing it. + + \sa toRawCFData(), fromCFData(), fromRawCFData(), fromRawData() +*/ +CFDataRef QByteArray::toCFData() const +{ + return CFDataCreate(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()), length()); +} + +/*! + \since 5.3 + + Constructs a CFData that uses the bytes of the QByteArray. + + The QByteArray's bytes are not copied. + + The caller guarantees that the QByteArray will not be deleted + or modified as long as this CFData object exists. + + \sa toCFData(), fromRawCFData(), fromCFData(), fromRawData() +*/ +CFDataRef QByteArray::toRawCFData() const +{ + return CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(data()), + length(), kCFAllocatorNull); +} + +/*! + \since 5.3 + + Constructs a new QByteArray containing a copy of the NSData \a data. + + \sa fromRawNSData(), fromRawData(), toNSData(), toRawNSData() +*/ +QByteArray QByteArray::fromNSData(const NSData *data) +{ + if (!data) + return QByteArray(); + return QByteArray(reinterpret_cast<const char *>([data bytes]), [data length]); +} + +/*! + \since 5.3 + + Constructs a QByteArray that uses the bytes of the NSData \a data. + + The \a data's bytes are not copied. + + The caller guarantees that the NSData will not be deleted + or modified as long as this QByteArray object exists. + + \sa fromNSData(), fromRawData(), toRawNSData(), toNSData() +*/ +QByteArray QByteArray::fromRawNSData(const NSData *data) +{ + if (!data) + return QByteArray(); + return QByteArray::fromRawData(reinterpret_cast<const char *>([data bytes]), [data length]); +} + +/*! + \since 5.3 + + Creates a NSData from a QByteArray. The NSData object is autoreleased. + + \sa fromNSData(), fromRawNSData(), fromRawData(), toRawNSData() +*/ +NSData *QByteArray::toNSData() const +{ + return [NSData dataWithBytes:constData() length:size()]; +} + +/*! + \since 5.3 + + Constructs a NSData that uses the bytes of the QByteArray. + + The QByteArray's bytes are not copied. + + The caller guarantees that the QByteArray will not be deleted + or modified as long as this NSData object exists. + + \sa fromRawNSData(), fromNSData(), fromRawData(), toNSData() +*/ +NSData *QByteArray::toRawNSData() const +{ + // const_cast is fine here because NSData is immutable thus will never modify bytes we're giving it + return [NSData dataWithBytesNoCopy:const_cast<char *>(constData()) length:size() freeWhenDone:NO]; +} + +// ---------------------------------------------------------------------------- + +/*! + \since 5.2 + + Constructs a new QString containing a copy of the \a string CFString. + + \note this function is only available on OS X and iOS. +*/ +QString QString::fromCFString(CFStringRef string) +{ + if (!string) + return QString(); + CFIndex length = CFStringGetLength(string); + + // Fast path: CFStringGetCharactersPtr does not copy but may + // return null for any and no reason. + const UniChar *chars = CFStringGetCharactersPtr(string); + if (chars) + return QString(reinterpret_cast<const QChar *>(chars), length); + + QString ret(length, Qt::Uninitialized); + CFStringGetCharacters(string, CFRangeMake(0, length), reinterpret_cast<UniChar *>(ret.data())); + return ret; +} + +/*! + \since 5.2 + + Creates a CFString from a QString. The caller owns the CFString and is + responsible for releasing it. + + \note this function is only available on OS X and iOS. +*/ +CFStringRef QString::toCFString() const +{ + return CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar *>(unicode()), length()); +} + +/*! + \since 5.2 + + Constructs a new QString containing a copy of the \a string NSString. + + \note this function is only available on OS X and iOS. +*/ +QString QString::fromNSString(const NSString *string) +{ + if (!string) + return QString(); + QString qstring; + qstring.resize([string length]); + [string getCharacters: reinterpret_cast<unichar*>(qstring.data()) range: NSMakeRange(0, [string length])]; + return qstring; +} + +/*! + \since 5.2 + + Creates a NSString from a QString. The NSString is autoreleased. + + \note this function is only available on OS X and iOS. +*/ +NSString *QString::toNSString() const +{ + return [NSString stringWithCharacters: reinterpret_cast<const UniChar*>(unicode()) length: length()]; +} + +// ---------------------------------------------------------------------------- + +/*! + \since 5.7 + + Constructs a new QUuid containing a copy of the \a uuid CFUUID. + + \note this function is only available on Apple platforms. +*/ +QUuid QUuid::fromCFUUID(CFUUIDRef uuid) +{ + if (!uuid) + return QUuid(); + const CFUUIDBytes bytes = CFUUIDGetUUIDBytes(uuid); + return QUuid::fromRfc4122(QByteArray::fromRawData(reinterpret_cast<const char *>(&bytes), sizeof(bytes))); +} + +/*! + \since 5.7 + + Creates a CFUUID from a QUuid. The caller owns the CFUUID and is + responsible for releasing it. + + \note this function is only available on Apple platforms. +*/ +CFUUIDRef QUuid::toCFUUID() const +{ + const QByteArray bytes = toRfc4122(); + return CFUUIDCreateFromUUIDBytes(0, *reinterpret_cast<const CFUUIDBytes *>(bytes.constData())); +} + +/*! + \since 5.7 + + Constructs a new QUuid containing a copy of the \a uuid NSUUID. + + \note this function is only available on Apple platforms. +*/ +QUuid QUuid::fromNSUUID(const NSUUID *uuid) +{ + if (!uuid) + return QUuid(); + uuid_t bytes; + [uuid getUUIDBytes:bytes]; + return QUuid::fromRfc4122(QByteArray::fromRawData(reinterpret_cast<const char *>(bytes), sizeof(bytes))); +} + +/*! + \since 5.7 + + Creates a NSUUID from a QUuid. The NSUUID is autoreleased. + + \note this function is only available on Apple platforms. +*/ +NSUUID *QUuid::toNSUUID() const +{ + const QByteArray bytes = toRfc4122(); + return [[[NSUUID alloc] initWithUUIDBytes:*reinterpret_cast<const uuid_t *>(bytes.constData())] autorelease]; +} + +// ---------------------------------------------------------------------------- + + +/*! + \since 5.2 + + Constructs a QUrl containing a copy of the CFURL \a url. +*/ +QUrl QUrl::fromCFURL(CFURLRef url) +{ + return QUrl(QString::fromCFString(CFURLGetString(url))); +} + +/*! + \since 5.2 + + Creates a CFURL from a QUrl. The caller owns the CFURL and is + responsible for releasing it. +*/ +CFURLRef QUrl::toCFURL() const +{ + CFURLRef url = 0; + CFStringRef str = toString(FullyEncoded).toCFString(); + if (str) { + url = CFURLCreateWithString(0, str, 0); + CFRelease(str); + } + return url; +} + +/*! + \since 5.2 + + Constructs a QUrl containing a copy of the NSURL \a url. +*/ +QUrl QUrl::fromNSURL(const NSURL *url) +{ + return QUrl(QString::fromNSString([url absoluteString])); +} + +/*! + \since 5.2 + + Creates a NSURL from a QUrl. The NSURL is autoreleased. +*/ +NSURL *QUrl::toNSURL() const +{ + return [NSURL URLWithString:toString(FullyEncoded).toNSString()]; +} + +// ---------------------------------------------------------------------------- + + +/*! + \since 5.5 + + Constructs a new QDateTime containing a copy of the CFDate \a date. + + \sa toCFDate() +*/ +QDateTime QDateTime::fromCFDate(CFDateRef date) +{ + if (!date) + return QDateTime(); + return QDateTime::fromMSecsSinceEpoch(static_cast<qint64>((CFDateGetAbsoluteTime(date) + + kCFAbsoluteTimeIntervalSince1970) * 1000)); +} + +/*! + \since 5.5 + + Creates a CFDate from a QDateTime. The caller owns the CFDate object + and is responsible for releasing it. + + \sa fromCFDate() +*/ +CFDateRef QDateTime::toCFDate() const +{ + return CFDateCreate(kCFAllocatorDefault, (static_cast<CFAbsoluteTime>(toMSecsSinceEpoch()) + / 1000) - kCFAbsoluteTimeIntervalSince1970); +} + +/*! + \since 5.5 + + Constructs a new QDateTime containing a copy of the NSDate \a date. + + \sa toNSDate() +*/ +QDateTime QDateTime::fromNSDate(const NSDate *date) +{ + if (!date) + return QDateTime(); + return QDateTime::fromMSecsSinceEpoch(static_cast<qint64>([date timeIntervalSince1970] * 1000)); +} + +/*! + \since 5.5 + + Creates an NSDate from a QDateTime. The NSDate object is autoreleased. + + \sa fromNSDate() +*/ +NSDate *QDateTime::toNSDate() const +{ + return [NSDate + dateWithTimeIntervalSince1970:static_cast<NSTimeInterval>(toMSecsSinceEpoch()) / 1000]; +} + +// ---------------------------------------------------------------------------- + +/*! + \since 5.8 + + Creates a CGRect from a QRect. + + \sa fromCGRect() +*/ +CGRect QRect::toCGRect() const Q_DECL_NOTHROW +{ + return CGRectMake(x(), y(), width(), height()); +} + +/*! + \since 5.8 + + Creates a CGRect from a QRectF. + + \sa fromCGRect() +*/ +CGRect QRectF::toCGRect() const Q_DECL_NOTHROW +{ + return CGRectMake(x(), y(), width(), height()); +} + +/*! + \since 5.8 + + Creates a QRectF from a CGRect. + + \sa toCGRect() +*/ +QRectF QRectF::fromCGRect(CGRect rect) Q_DECL_NOTHROW +{ + return QRectF(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); +} + +// ---------------------------------------------------------------------------- + +/*! + \since 5.8 + + Creates a CGPoint from a QPoint. + + \sa fromCGPoint() +*/ +CGPoint QPoint::toCGPoint() const Q_DECL_NOTHROW +{ + return CGPointMake(x(), y()); +} + +/*! + \since 5.8 + + Creates a CGPoint from a QPointF. + + \sa fromCGPoint() +*/ +CGPoint QPointF::toCGPoint() const Q_DECL_NOTHROW +{ + return CGPointMake(x(), y()); +} + +/*! + \since 5.8 + + Creates a QRectF from a CGPoint. + + \sa toCGPoint() +*/ +QPointF QPointF::fromCGPoint(CGPoint point) Q_DECL_NOTHROW +{ + return QPointF(point.x, point.y); +} + +// ---------------------------------------------------------------------------- + +/*! + \since 5.8 + + Creates a CGSize from a QSize. + + \sa fromCGSize() +*/ +CGSize QSize::toCGSize() const Q_DECL_NOTHROW +{ + return CGSizeMake(width(), height()); +} + +/*! + \since 5.8 + + Creates a CGSize from a QSizeF. + + \sa fromCGSize() +*/ +CGSize QSizeF::toCGSize() const Q_DECL_NOTHROW +{ + return CGSizeMake(width(), height()); +} + +/*! + \since 5.8 + + Creates a QRectF from a CGSize. + + \sa toCGSize() +*/ +QSizeF QSizeF::fromCGSize(CGSize size) Q_DECL_NOTHROW +{ + return QSizeF(size.width, size.height); +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_mac_objc.mm b/src/corelib/kernel/qcore_mac_objc.mm index de491dd43d..068b6b0440 100644 --- a/src/corelib/kernel/qcore_mac_objc.mm +++ b/src/corelib/kernel/qcore_mac_objc.mm @@ -47,7 +47,7 @@ #include <qdebug.h> -#ifdef Q_OS_IOS +#if defined(Q_OS_IOS) #import <UIKit/UIKit.h> #endif @@ -101,7 +101,7 @@ QT_FOR_EACH_MUTABLE_CORE_GRAPHICS_TYPE(QT_DECLARE_WEAK_QDEBUG_OPERATOR_FOR_CF_TY QAppleOperatingSystemVersion qt_apple_os_version() { QAppleOperatingSystemVersion v = {0, 0, 0}; -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_8_0) +#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_10, __IPHONE_8_0) || defined(Q_OS_TVOS) if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) { NSOperatingSystemVersion osv = NSProcessInfo.processInfo.operatingSystemVersion; v.major = osv.majorVersion; diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h index b94aac1093..63e1cb48dc 100644 --- a/src/corelib/kernel/qcore_mac_p.h +++ b/src/corelib/kernel/qcore_mac_p.h @@ -61,7 +61,7 @@ #include <CoreFoundation/CoreFoundation.h> #endif -#include "qglobal.h" +#include "private/qglobal_p.h" #ifdef __OBJC__ #include <Foundation/Foundation.h> diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index 125ced6fc9..c393609188 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -52,6 +52,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include "qplatformdefs.h" #include "qatomic.h" #include "qhash.h" @@ -298,8 +299,8 @@ static inline int qt_safe_close(int fd) #undef QT_CLOSE #define QT_CLOSE qt_safe_close -// - VxWorks doesn't have processes -#if !defined(Q_OS_VXWORKS) +// - VxWorks & iOS/tvOS don't have processes +#if !defined(Q_OS_VXWORKS) && !defined(QT_NO_PROCESS) static inline int qt_safe_execve(const char *filename, char *const argv[], char *const envp[]) { diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 78ec004fc9..72645b4d9b 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1299,19 +1299,6 @@ void QCoreApplication::exit(int returnCode) QEventLoop *eventLoop = data->eventLoops.at(i); eventLoop->exit(returnCode); } -#ifdef Q_OS_WINRT - qWarning("QCoreApplication::exit: It is not recommended to explicitly exit an application on Windows Store Apps"); - ComPtr<ICoreApplication> app; - HRESULT hr = RoGetActivationFactory(Wrappers::HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), - IID_PPV_ARGS(&app)); - RETURN_VOID_IF_FAILED("Could not acquire ICoreApplication object"); - ComPtr<ICoreApplicationExit> appExit; - - hr = app.As(&appExit); - RETURN_VOID_IF_FAILED("Could not acquire ICoreApplicationExit object"); - hr = appExit->Exit(); - RETURN_VOID_IF_FAILED("Could not exit application"); -#endif // Q_OS_WINRT } /***************************************************************************** @@ -2259,14 +2246,6 @@ QStringList QCoreApplication::arguments() // classes by index. QString cmdline = QString::fromWCharArray(GetCommandLine()); -#if defined(Q_OS_WINCE) - wchar_t tempFilename[MAX_PATH+1]; - if (GetModuleFileName(0, tempFilename, MAX_PATH)) { - tempFilename[MAX_PATH] = 0; - cmdline.prepend(QLatin1Char('\"') + QString::fromWCharArray(tempFilename) + QLatin1String("\" ")); - } -#endif // Q_OS_WINCE - const QCoreApplicationPrivate *d = self->d_func(); if (d->origArgv) { const QStringList allArguments = qWinCmdArgs(cmdline); @@ -2497,6 +2476,26 @@ QStringList QCoreApplication::libraryPaths() } } +#ifdef Q_OS_DARWIN + // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes. + // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value + // but with a different casing, so it can't be relied upon when the underlying filesystem + // is case sensitive (and this is always the case on newer OSes like iOS). + if (CFBundleRef bundleRef = CFBundleGetMainBundle()) { + if (QCFType<CFURLRef> urlRef = CFBundleCopyBuiltInPlugInsURL(bundleRef)) { + if (QCFType<CFURLRef> absoluteUrlRef = CFURLCopyAbsoluteURL(urlRef)) { + if (QCFString path = CFURLCopyFileSystemPath(absoluteUrlRef, kCFURLPOSIXPathStyle)) { + if (QFile::exists(path)) { + path = QDir(path).canonicalPath(); + if (!app_libpaths->contains(path)) + app_libpaths->append(path); + } + } + } + } + } +#endif // Q_OS_DARWIN + QString installPathPlugins = QLibraryInfo::location(QLibraryInfo::PluginsPath); if (QFile::exists(installPathPlugins)) { // Make sure we convert from backslashes to slashes. diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp index 0e2d4e2324..67e509eeef 100644 --- a/src/corelib/kernel/qcoreapplication_win.cpp +++ b/src/corelib/kernel/qcoreapplication_win.cpp @@ -122,6 +122,7 @@ QString QCoreApplicationPrivate::appName() const #ifndef Q_OS_WINRT +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) Q_CORE_EXPORT HINSTANCE qWinAppInst() // get Windows app handle { return GetModuleHandle(0); @@ -145,12 +146,13 @@ Q_CORE_EXPORT int qWinAppCmdShow() // get main window sho : SW_SHOWDEFAULT; #endif } +#endif /***************************************************************************** qWinMain() - Initializes Windows. Called from WinMain() in qtmain_win.cpp *****************************************************************************/ -#if !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) +#if !defined(Q_OS_WINRT) // ### Qt6: FIXME: Consider removing this function. It is here for Active Qt // servers and for binary for compatibility to applications built with Qt 5.3 @@ -171,30 +173,7 @@ void qWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam, argv.append(_strdup(wArg.toLocal8Bit().constData())); } -#elif defined(Q_OS_WINCE) - -Q_CORE_EXPORT void __cdecl qWinMain(HINSTANCE instance, HINSTANCE prevInstance, LPSTR cmdParam, - int cmdShow, int &argc, QVector<char *> &argv) -{ - static bool already_called = false; - - if (already_called) { - qWarning("Qt: Internal error: qWinMain should be called only once"); - return; - } - already_called = true; - - // Create command line - argv = qWinCmdLine<char>(cmdParam, int(strlen(cmdParam)), argc); - - appCmdShow = cmdShow; - - // Ignore Windows parameters - Q_UNUSED(instance); - Q_UNUSED(prevInstance); -} - -#endif // Q_OS_WINCE +#endif // !Q_OS_WINRT #ifndef QT_NO_QOBJECT @@ -212,11 +191,6 @@ QT_END_INCLUDE_NAMESPACE # define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp)) # define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp)) #endif -#ifdef _WIN32_WCE -# ifndef WM_NCACTIVATE -# define WM_NCACTIVATE 0x86 -# endif -#endif // The values below should never change. Note that none of the usual // WM_...FIRST & WM_...LAST values are in the list, as they normally have other diff --git a/src/corelib/kernel/qcorecmdlineargs_p.h b/src/corelib/kernel/qcorecmdlineargs_p.h index 2d8de08f2d..33445a1625 100644 --- a/src/corelib/kernel/qcorecmdlineargs_p.h +++ b/src/corelib/kernel/qcorecmdlineargs_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include "QtCore/qstring.h" #include "QtCore/qstringlist.h" @@ -81,93 +82,7 @@ static inline QStringList qWinCmdArgs(const QString &cmdLine) return result; } -#elif defined(Q_OS_WINCE) // Q_OS_WIN32 - -// template implementation of the parsing algorithm -// this is used from qcoreapplication_win.cpp and the tools (rcc, uic...) - -template<typename Char> -static QVector<Char*> qWinCmdLine(Char *cmdParam, int length, int &argc) -{ - QVector<Char*> argv(8); - Char *p = cmdParam; - Char *p_end = p + length; - - argc = 0; - - while (*p && p < p_end) { // parse cmd line arguments - while (QChar((short)(*p)).isSpace()) // skip white space - p++; - if (*p && p < p_end) { // arg starts - int quote; - Char *start, *r; - if (*p == Char('\"')) { - quote = *p; - start = ++p; - } else { - quote = 0; - start = p; - } - r = start; - while (*p && p < p_end) { - if (quote) { - if (*p == quote) { - p++; - if (QChar((short)(*p)).isSpace()) - break; - quote = 0; - } - } - if (*p == '\\') { // escape char? - // testing by looking at argc, argv shows that it only escapes quotes - if (p < p_end && (*(p+1) == Char('\"'))) - p++; - } else { - if (!quote && (*p == Char('\"'))) { - quote = *p++; - continue; - } else if (QChar((short)(*p)).isSpace() && !quote) - break; - } - if (*p) - *r++ = *p++; - } - if (*p && p < p_end) - p++; - *r = Char('\0'); - - if (argc >= (int)argv.size()-1) // expand array - argv.resize(argv.size()*2); - argv[argc++] = start; - } - } - argv[argc] = 0; - - return argv; -} - -static inline QStringList qWinCmdArgs(QString cmdLine) // not const-ref: this might be modified -{ - QStringList args; - - int argc = 0; - QVector<wchar_t*> argv = qWinCmdLine<wchar_t>((wchar_t *)cmdLine.utf16(), cmdLine.length(), argc); - for (int a = 0; a < argc; ++a) { - args << QString::fromWCharArray(argv[a]); - } - - return args; -} - -static inline QStringList qCmdLineArgs(int argc, char *argv[]) -{ - Q_UNUSED(argc) - Q_UNUSED(argv) - QString cmdLine = QString::fromWCharArray(GetCommandLine()); - return qWinCmdArgs(cmdLine); -} - -#elif defined(Q_OS_WINRT) // Q_OS_WINCE +#elif defined(Q_OS_WINRT) // Q_OS_WIN32 static inline QStringList qCmdLineArgs(int argc, char *argv[]) { diff --git a/src/corelib/kernel/qcoreglobaldata_p.h b/src/corelib/kernel/qcoreglobaldata_p.h index 4f97449c75..32b5becf4f 100644 --- a/src/corelib/kernel/qcoreglobaldata_p.h +++ b/src/corelib/kernel/qcoreglobaldata_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include "QtCore/qmap.h" #include "QtCore/qstringlist.h" #include "QtCore/qreadwritelock.h" diff --git a/src/corelib/kernel/qcrashhandler_p.h b/src/corelib/kernel/qcrashhandler_p.h index 1fd0ff3af8..64c15ce66c 100644 --- a/src/corelib/kernel/qcrashhandler_p.h +++ b/src/corelib/kernel/qcrashhandler_p.h @@ -51,7 +51,7 @@ // We mean it. // -#include <QtCore/qglobal.h> +#include <QtCore/private/qglobal_p.h> #ifndef QT_NO_CRASHHANDLER diff --git a/src/corelib/kernel/qelapsedtimer.cpp b/src/corelib/kernel/qelapsedtimer.cpp new file mode 100644 index 0000000000..2eabb4c3a3 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer.cpp @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" + +QT_BEGIN_NAMESPACE + +/*! + \class QElapsedTimer + \inmodule QtCore + \brief The QElapsedTimer class provides a fast way to calculate elapsed times. + \since 4.7 + + \reentrant + \ingroup tools + + The QElapsedTimer class is usually used to quickly calculate how much + time has elapsed between two events. Its API is similar to that of QTime, + so code that was using that can be ported quickly to the new class. + + However, unlike QTime, QElapsedTimer tries to use monotonic clocks if + possible. This means it's not possible to convert QElapsedTimer objects + to a human-readable time. + + The typical use-case for the class is to determine how much time was + spent in a slow operation. The simplest example of such a case is for + debugging purposes, as in the following example: + + \snippet qelapsedtimer/main.cpp 0 + + In this example, the timer is started by a call to start() and the + elapsed timer is calculated by the elapsed() function. + + The time elapsed can also be used to recalculate the time available for + another operation, after the first one is complete. This is useful when + the execution must complete within a certain time period, but several + steps are needed. The \tt{waitFor}-type functions in QIODevice and its + subclasses are good examples of such need. In that case, the code could + be as follows: + + \snippet qelapsedtimer/main.cpp 1 + + Another use-case is to execute a certain operation for a specific + timeslice. For this, QElapsedTimer provides the hasExpired() convenience + function, which can be used to determine if a certain number of + milliseconds has already elapsed: + + \snippet qelapsedtimer/main.cpp 2 + + \section1 Reference Clocks + + QElapsedTimer will use the platform's monotonic reference clock in all + platforms that support it (see QElapsedTimer::isMonotonic()). This has + the added benefit that QElapsedTimer is immune to time adjustments, such + as the user correcting the time. Also unlike QTime, QElapsedTimer is + immune to changes in the timezone settings, such as daylight-saving + periods. + + On the other hand, this means QElapsedTimer values can only be compared + with other values that use the same reference. This is especially true if + the time since the reference is extracted from the QElapsedTimer object + (QElapsedTimer::msecsSinceReference()) and serialised. These values + should never be exchanged across the network or saved to disk, since + there's no telling whether the computer node receiving the data is the + same as the one originating it or if it has rebooted since. + + It is, however, possible to exchange the value with other processes + running on the same machine, provided that they also use the same + reference clock. QElapsedTimer will always use the same clock, so it's + safe to compare with the value coming from another process in the same + machine. If comparing to values produced by other APIs, you should check + that the clock used is the same as QElapsedTimer (see + QElapsedTimer::clockType()). + + \section2 32-bit overflows + + Some of the clocks used by QElapsedTimer have a limited range and may + overflow after hitting the upper limit (usually 32-bit). QElapsedTimer + deals with this overflow issue and presents a consistent timing. However, + when extracting the time since reference from QElapsedTimer, two + different processes in the same machine may have different understanding + of how much time has actually elapsed. + + The information on which clocks types may overflow and how to remedy that + issue is documented along with the clock types. + + \sa QTime, QTimer +*/ + +/*! + \enum QElapsedTimer::ClockType + + This enum contains the different clock types that QElapsedTimer may use. + + QElapsedTimer will always use the same clock type in a particular + machine, so this value will not change during the lifetime of a program. + It is provided so that QElapsedTimer can be used with other non-Qt + implementations, to guarantee that the same reference clock is being + used. + + \value SystemTime The human-readable system time. This clock is not monotonic. + \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is monotonic and does not overflow. + \value TickCounter The system's tick counter, used on Windows systems. This clock may overflow. + \value MachAbsoluteTime The Mach kernel's absolute time (OS X and iOS). This clock is monotonic and does not overflow. + \value PerformanceCounter The high-resolution performance counter provided by Windows. This clock is monotonic and does not overflow. + + \section2 SystemTime + + The system time clock is purely the real time, expressed in milliseconds + since Jan 1, 1970 at 0:00 UTC. It's equivalent to the value returned by + the C and POSIX \tt{time} function, with the milliseconds added. This + clock type is currently only used on Unix systems that do not support + monotonic clocks (see below). + + This is the only non-monotonic clock that QElapsedTimer may use. + + \section2 MonotonicClock + + This is the system's monotonic clock, expressed in milliseconds since an + arbitrary point in the past. This clock type is used on Unix systems + which support POSIX monotonic clocks (\tt{_POSIX_MONOTONIC_CLOCK}). + + This clock does not overflow. + + \section2 TickCounter + + The tick counter clock type is based on the system's or the processor's + tick counter, multiplied by the duration of a tick. This clock type is + used on Windows platforms. If the high-precision performance + counter is available on Windows, the \tt{PerformanceCounter} clock type + is used instead. + + The TickCounter clock type is the only clock type that may overflow. + Windows Vista and Windows Server 2008 support the extended 64-bit tick + counter, which allows avoiding the overflow. + + On Windows systems, the clock overflows after 2^32 milliseconds, which + corresponds to roughly 49.7 days. This means two processes' reckoning of + the time since the reference may be different by multiples of 2^32 + milliseconds. When comparing such values, it's recommended that the high + 32 bits of the millisecond count be masked off. + + \section2 MachAbsoluteTime + + This clock type is based on the absolute time presented by Mach kernels, + such as that found on OS X. This clock type is presented separately + from MonotonicClock since OS X and iOS are also Unix systems and may support + a POSIX monotonic clock with values differing from the Mach absolute + time. + + This clock is monotonic and does not overflow. + + \section2 PerformanceCounter + + This clock uses the Windows functions \tt{QueryPerformanceCounter} and + \tt{QueryPerformanceFrequency} to access the system's high-precision + performance counter. Since this counter may not be available on all + systems, QElapsedTimer will fall back to the \tt{TickCounter} clock + automatically, if this clock cannot be used. + + This clock is monotonic and does not overflow. + + \sa clockType(), isMonotonic() +*/ + +/*! + \fn QElapsedTimer::QElapsedTimer() + \since 5.4 + + Constructs an invalid QElapsedTimer. A timer becomes valid once it has been + started. + + \sa isValid(), start() +*/ + + +/*! + \fn bool QElapsedTimer::operator ==(const QElapsedTimer &other) const + + Returns \c true if this object and \a other contain the same time. +*/ + +/*! + \fn bool QElapsedTimer::operator !=(const QElapsedTimer &other) const + + Returns \c true if this object and \a other contain different times. +*/ + +static const qint64 invalidData = Q_INT64_C(0x8000000000000000); + +/*! + Marks this QElapsedTimer object as invalid. + + An invalid object can be checked with isValid(). Calculations of timer + elapsed since invalid data are undefined and will likely produce bizarre + results. + + \sa isValid(), start(), restart() +*/ +void QElapsedTimer::invalidate() Q_DECL_NOTHROW +{ + t1 = t2 = invalidData; +} + +/*! + Returns \c false if the timer has never been started or invalidated by a + call to invalidate(). + + \sa invalidate(), start(), restart() +*/ +bool QElapsedTimer::isValid() const Q_DECL_NOTHROW +{ + return t1 != invalidData && t2 != invalidData; +} + +/*! + Returns \c true if this QElapsedTimer has already expired by \a timeout + milliseconds (that is, more than \a timeout milliseconds have elapsed). + The value of \a timeout can be -1 to indicate that this timer does not + expire, in which case this function will always return false. + + \sa elapsed() +*/ +bool QElapsedTimer::hasExpired(qint64 timeout) const Q_DECL_NOTHROW +{ + // if timeout is -1, quint64(timeout) is LLINT_MAX, so this will be + // considered as never expired + return quint64(elapsed()) > quint64(timeout); +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer.h b/src/corelib/kernel/qelapsedtimer.h new file mode 100644 index 0000000000..7954b41bf4 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QELAPSEDTIMER_H +#define QELAPSEDTIMER_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE + + +class Q_CORE_EXPORT QElapsedTimer +{ +public: + enum ClockType { + SystemTime, + MonotonicClock, + TickCounter, + MachAbsoluteTime, + PerformanceCounter + }; + + Q_DECL_CONSTEXPR QElapsedTimer() + : t1(Q_INT64_C(0x8000000000000000)), + t2(Q_INT64_C(0x8000000000000000)) + { + } + + static ClockType clockType() Q_DECL_NOTHROW; + static bool isMonotonic() Q_DECL_NOTHROW; + + void start() Q_DECL_NOTHROW; + qint64 restart() Q_DECL_NOTHROW; + void invalidate() Q_DECL_NOTHROW; + bool isValid() const Q_DECL_NOTHROW; + + qint64 nsecsElapsed() const Q_DECL_NOTHROW; + qint64 elapsed() const Q_DECL_NOTHROW; + bool hasExpired(qint64 timeout) const Q_DECL_NOTHROW; + + qint64 msecsSinceReference() const Q_DECL_NOTHROW; + qint64 msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW; + qint64 secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW; + + bool operator==(const QElapsedTimer &other) const Q_DECL_NOTHROW + { return t1 == other.t1 && t2 == other.t2; } + bool operator!=(const QElapsedTimer &other) const Q_DECL_NOTHROW + { return !(*this == other); } + + friend bool Q_CORE_EXPORT operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW; + +private: + qint64 t1; + qint64 t2; +}; + +QT_END_NAMESPACE + +#endif // QELAPSEDTIMER_H diff --git a/src/corelib/kernel/qelapsedtimer_generic.cpp b/src/corelib/kernel/qelapsedtimer_generic.cpp new file mode 100644 index 0000000000..8c724247be --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_generic.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include "qdatetime.h" + +QT_BEGIN_NAMESPACE + +/*! + Returns the clock type that this QElapsedTimer implementation uses. + + \sa isMonotonic() +*/ +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + return SystemTime; +} + +/*! + Returns \c true if this is a monotonic clock, false otherwise. See the + information on the different clock types to understand which ones are + monotonic. + + \sa clockType(), QElapsedTimer::ClockType +*/ +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return false; +} + +/*! + Starts this timer. Once started, a timer value can be checked with elapsed() or msecsSinceReference(). + + Normally, a timer is started just before a lengthy operation, such as: + \snippet qelapsedtimer/main.cpp 0 + + Also, starting a timer makes it valid again. + + \sa restart(), invalidate(), elapsed() +*/ +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + restart(); +} + +/*! + Restarts the timer and returns the time elapsed since the previous start. + This function is equivalent to obtaining the elapsed time with elapsed() + and then starting the timer again with start(), but it does so in one + single operation, avoiding the need to obtain the clock value twice. + + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. + + The following example illustrates how to use this function to calibrate a + parameter to a slow operation (for example, an iteration count) so that + this operation takes at least 250 milliseconds: + + \snippet qelapsedtimer/main.cpp 3 + + \sa start(), invalidate(), elapsed(), isValid() +*/ +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + qint64 old = t1; + t1 = QDateTime::currentMSecsSinceEpoch(); + t2 = 0; + return t1 - old; +} + +/*! \since 4.8 + + Returns the number of nanoseconds since this QElapsedTimer was last + started. + + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. + + On platforms that do not provide nanosecond resolution, the value returned + will be the best estimate available. + + \sa start(), restart(), hasExpired(), invalidate() +*/ +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + return elapsed() * 1000000; +} + +/*! + Returns the number of milliseconds since this QElapsedTimer was last + started. + + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. + + \sa start(), restart(), hasExpired(), isValid(), invalidate() +*/ +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + return QDateTime::currentMSecsSinceEpoch() - t1; +} + +/*! + Returns the number of milliseconds between last time this QElapsedTimer + object was started and its reference clock's start. + + This number is usually arbitrary for all clocks except the + QElapsedTimer::SystemTime clock. For that clock type, this number is the + number of milliseconds since January 1st, 1970 at 0:00 UTC (that is, it + is the Unix time expressed in milliseconds). + + On Linux, Windows and OS X/iOS systems, this value is usually the time + since the system boot, though it usually does not include the time the + system has spent in sleep states. + + \sa clockType(), elapsed() +*/ +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return t1; +} + +/*! + Returns the number of milliseconds between this QElapsedTimer and \a + other. If \a other was started before this object, the returned value + will be negative. If it was started later, the returned value will be + positive. + + The return value is undefined if this object or \a other were invalidated. + + \sa secsTo(), elapsed() +*/ +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + qint64 diff = other.t1 - t1; + return diff; +} + +/*! + Returns the number of seconds between this QElapsedTimer and \a other. If + \a other was started before this object, the returned value will be + negative. If it was started later, the returned value will be positive. + + Calling this function on or with a QElapsedTimer that is invalid + results in undefined behavior. + + \sa msecsTo(), elapsed() +*/ +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return msecsTo(other) / 1000; +} + +/*! + \relates QElapsedTimer + + Returns \c true if \a v1 was started before \a v2, false otherwise. + + The returned value is undefined if one of the two parameters is invalid + and the other isn't. However, two invalid timers are equal and thus this + function will return false. +*/ +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return v1.t1 < v2.t1; +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer_mac.cpp b/src/corelib/kernel/qelapsedtimer_mac.cpp new file mode 100644 index 0000000000..886e0f41b2 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_mac.cpp @@ -0,0 +1,149 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// ask for the latest POSIX, just in case +#define _POSIX_C_SOURCE 200809L + +#include "qelapsedtimer.h" +#include <sys/time.h> +#include <time.h> +#include <unistd.h> + +#include <mach/mach_time.h> +#include <private/qcore_unix_p.h> + +QT_BEGIN_NAMESPACE + +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + return MachAbsoluteTime; +} + +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return true; +} + +static mach_timebase_info_data_t info = {0,0}; +static qint64 absoluteToNSecs(qint64 cpuTime) +{ + if (info.denom == 0) + mach_timebase_info(&info); +#ifdef __LP64__ + __uint128_t nsecs = static_cast<__uint128_t>(cpuTime) * info.numer / info.denom; + return static_cast<qint64>(nsecs); +#else + qint64 nsecs = cpuTime * info.numer / info.denom; + return nsecs; +#endif +} + +static qint64 absoluteToMSecs(qint64 cpuTime) +{ + return absoluteToNSecs(cpuTime) / 1000000; +} + +timespec qt_gettime() Q_DECL_NOTHROW +{ + timespec tv; + + uint64_t cpu_time = mach_absolute_time(); + uint64_t nsecs = absoluteToNSecs(cpu_time); + tv.tv_sec = nsecs / 1000000000ull; + tv.tv_nsec = nsecs - (tv.tv_sec * 1000000000ull); + return tv; +} + +void qt_nanosleep(timespec amount) +{ + // Mac doesn't have clock_nanosleep, but it does have nanosleep. + // nanosleep is POSIX.1-1993 + + int r; + EINTR_LOOP(r, nanosleep(&amount, &amount)); +} + +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + t1 = mach_absolute_time(); + t2 = 0; +} + +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + qint64 old = t1; + t1 = mach_absolute_time(); + t2 = 0; + + return absoluteToMSecs(t1 - old); +} + +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + uint64_t cpu_time = mach_absolute_time(); + return absoluteToNSecs(cpu_time - t1); +} + +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + uint64_t cpu_time = mach_absolute_time(); + return absoluteToMSecs(cpu_time - t1); +} + +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return absoluteToMSecs(t1); +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return absoluteToMSecs(other.t1 - t1); +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return msecsTo(other) / 1000; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return v1.t1 < v2.t1; +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer_unix.cpp b/src/corelib/kernel/qelapsedtimer_unix.cpp new file mode 100644 index 0000000000..e2c3ae6280 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_unix.cpp @@ -0,0 +1,251 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#if defined(Q_OS_VXWORKS) +#include "qfunctions_vxworks.h" +#else +#include <sys/time.h> +#include <time.h> +#endif +#include <unistd.h> + +#include <qatomic.h> +#include "private/qcore_unix_p.h" + +#if defined(QT_NO_CLOCK_MONOTONIC) || defined(QT_BOOTSTRAPPED) +// turn off the monotonic clock +# ifdef _POSIX_MONOTONIC_CLOCK +# undef _POSIX_MONOTONIC_CLOCK +# endif +# define _POSIX_MONOTONIC_CLOCK -1 +#endif + +QT_BEGIN_NAMESPACE + +/* + * Design: + * + * POSIX offers a facility to select the system's monotonic clock when getting + * the current timestamp. Whereas the functions are mandatory in POSIX.1-2008, + * the presence of a monotonic clock is a POSIX Option (see the document + * http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap02.html#tag_02_01_06 ) + * + * The macro _POSIX_MONOTONIC_CLOCK can therefore assume the following values: + * -1 monotonic clock is never supported on this system + * 0 monotonic clock might be supported, runtime check is needed + * >1 (such as 200809L) monotonic clock is always supported + * + * The unixCheckClockType() function will return the clock to use: either + * CLOCK_MONOTONIC or CLOCK_REALTIME. In the case the POSIX option has a value + * of zero, then this function stores a static that contains the clock to be + * used. + * + * There's one extra case, which is when CLOCK_REALTIME isn't defined. When + * that's the case, we'll emulate the clock_gettime function with gettimeofday. + * + * Conforming to: + * POSIX.1b-1993 section "Clocks and Timers" + * included in UNIX98 (Single Unix Specification v2) + * included in POSIX.1-2001 + * see http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock_getres.html + */ + +#if !defined(CLOCK_REALTIME) +# define CLOCK_REALTIME 0 +static inline void qt_clock_gettime(int, struct timespec *ts) +{ + // support clock_gettime with gettimeofday + struct timeval tv; + gettimeofday(&tv, 0); + ts->tv_sec = tv.tv_sec; + ts->tv_nsec = tv.tv_usec * 1000; +} + +# ifdef _POSIX_MONOTONIC_CLOCK +# undef _POSIX_MONOTONIC_CLOCK +# define _POSIX_MONOTONIC_CLOCK -1 +# endif +#else +static inline void qt_clock_gettime(clockid_t clock, struct timespec *ts) +{ + clock_gettime(clock, ts); +} +#endif + +static int unixCheckClockType() +{ +#ifdef Q_OS_LINUX + // Despite glibc claiming that we should check at runtime, the Linux kernel + // always supports the monotonic clock + return CLOCK_MONOTONIC; +#elif (_POSIX_MONOTONIC_CLOCK-0 == 0) && defined(_SC_MONOTONIC_CLOCK) + // we need a value we can store in a clockid_t that isn't a valid clock + // check if the valid ones are both non-negative or both non-positive +# if CLOCK_MONOTONIC >= 0 && CLOCK_REALTIME >= 0 +# define IS_VALID_CLOCK(clock) (clock >= 0) +# define INVALID_CLOCK -1 +# elif CLOCK_MONOTONIC <= 0 && CLOCK_REALTIME <= 0 +# define IS_VALID_CLOCK(clock) (clock <= 0) +# define INVALID_CLOCK 1 +# else +# error "Sorry, your system has weird values for CLOCK_MONOTONIC and CLOCK_REALTIME" +# endif + + static QBasicAtomicInt clockToUse = Q_BASIC_ATOMIC_INITIALIZER(INVALID_CLOCK); + int clock = clockToUse.loadAcquire(); + if (Q_LIKELY(IS_VALID_CLOCK(clock))) + return clock; + + // detect if the system supports monotonic timers + clock = sysconf(_SC_MONOTONIC_CLOCK) > 0 ? CLOCK_MONOTONIC : CLOCK_REALTIME; + clockToUse.storeRelease(clock); + return clock; + +# undef INVALID_CLOCK +# undef IS_VALID_CLOCK +#elif (_POSIX_MONOTONIC_CLOCK-0) > 0 + return CLOCK_MONOTONIC; +#else + return CLOCK_REALTIME; +#endif +} + +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return clockType() == MonotonicClock; +} + +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + return unixCheckClockType() == CLOCK_REALTIME ? SystemTime : MonotonicClock; +} + +static inline void do_gettime(qint64 *sec, qint64 *frac) +{ + timespec ts; + qt_clock_gettime(unixCheckClockType(), &ts); + *sec = ts.tv_sec; + *frac = ts.tv_nsec; +} + +// used in qcore_unix.cpp and qeventdispatcher_unix.cpp +struct timespec qt_gettime() Q_DECL_NOTHROW +{ + qint64 sec, frac; + do_gettime(&sec, &frac); + + timespec tv; + tv.tv_sec = sec; + tv.tv_nsec = frac; + + return tv; +} + +void qt_nanosleep(timespec amount) +{ + // We'd like to use clock_nanosleep. + // + // But clock_nanosleep is from POSIX.1-2001 and both are *not* + // affected by clock changes when using relative sleeps, even for + // CLOCK_REALTIME. + // + // nanosleep is POSIX.1-1993 + + int r; + EINTR_LOOP(r, nanosleep(&amount, &amount)); +} + +static qint64 elapsedAndRestart(qint64 sec, qint64 frac, + qint64 *nowsec, qint64 *nowfrac) +{ + do_gettime(nowsec, nowfrac); + sec = *nowsec - sec; + frac = *nowfrac - frac; + return (sec * Q_INT64_C(1000000000) + frac) / Q_INT64_C(1000000); +} + +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + do_gettime(&t1, &t2); +} + +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + return elapsedAndRestart(t1, t2, &t1, &t2); +} + +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + qint64 sec, frac; + do_gettime(&sec, &frac); + sec = sec - t1; + frac = frac - t2; + return sec * Q_INT64_C(1000000000) + frac; +} + +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + return nsecsElapsed() / Q_INT64_C(1000000); +} + +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return t1 * Q_INT64_C(1000) + t2 / Q_INT64_C(1000000); +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + qint64 secs = other.t1 - t1; + qint64 fraction = other.t2 - t2; + return (secs * Q_INT64_C(1000000000) + fraction) / Q_INT64_C(1000000); +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return other.t1 - t1; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return v1.t1 < v2.t1 || (v1.t1 == v2.t1 && v1.t2 < v2.t2); +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qelapsedtimer_win.cpp b/src/corelib/kernel/qelapsedtimer_win.cpp new file mode 100644 index 0000000000..520126d262 --- /dev/null +++ b/src/corelib/kernel/qelapsedtimer_win.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qelapsedtimer.h" +#include <qt_windows.h> + +QT_BEGIN_NAMESPACE + +// Result of QueryPerformanceFrequency, 0 indicates that the high resolution timer is unavailable +static quint64 counterFrequency = 0; + +static void resolveCounterFrequency() +{ + static bool done = false; + if (done) + return; + + // Retrieve the number of high-resolution performance counter ticks per second + LARGE_INTEGER frequency; + if (!QueryPerformanceFrequency(&frequency)) { + qFatal("QueryPerformanceFrequency failed, even though Microsoft documentation promises it wouldn't."); + counterFrequency = 0; + } else { + counterFrequency = frequency.QuadPart; + } + + done = true; +} + +static inline qint64 ticksToNanoseconds(qint64 ticks) +{ + if (counterFrequency > 0) { + // QueryPerformanceCounter uses an arbitrary frequency + qint64 seconds = ticks / counterFrequency; + qint64 nanoSeconds = (ticks - seconds * counterFrequency) * 1000000000 / counterFrequency; + return seconds * 1000000000 + nanoSeconds; + } else { + // GetTickCount(64) return milliseconds + return ticks * 1000000; + } +} + +static quint64 getTickCount() +{ + resolveCounterFrequency(); + + // This avoids a division by zero and disables the high performance counter if it's not available + if (counterFrequency > 0) { + LARGE_INTEGER counter; + + bool ok = QueryPerformanceCounter(&counter); + Q_ASSERT_X(ok, "QElapsedTimer::start()", + "QueryPerformanceCounter failed, although QueryPerformanceFrequency succeeded."); + Q_UNUSED(ok); + return counter.QuadPart; + } + + return GetTickCount64(); +} + +quint64 qt_msectime() +{ + return ticksToNanoseconds(getTickCount()) / 1000000; +} + +QElapsedTimer::ClockType QElapsedTimer::clockType() Q_DECL_NOTHROW +{ + resolveCounterFrequency(); + + if (counterFrequency > 0) + return PerformanceCounter; + else + return TickCounter; +} + +bool QElapsedTimer::isMonotonic() Q_DECL_NOTHROW +{ + return true; +} + +void QElapsedTimer::start() Q_DECL_NOTHROW +{ + t1 = getTickCount(); + t2 = 0; +} + +qint64 QElapsedTimer::restart() Q_DECL_NOTHROW +{ + qint64 oldt1 = t1; + t1 = getTickCount(); + t2 = 0; + return ticksToNanoseconds(t1 - oldt1) / 1000000; +} + +qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW +{ + qint64 elapsed = getTickCount() - t1; + return ticksToNanoseconds(elapsed); +} + +qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW +{ + qint64 elapsed = getTickCount() - t1; + return ticksToNanoseconds(elapsed) / 1000000; +} + +qint64 QElapsedTimer::msecsSinceReference() const Q_DECL_NOTHROW +{ + return ticksToNanoseconds(t1) / 1000000; +} + +qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + qint64 difference = other.t1 - t1; + return ticksToNanoseconds(difference) / 1000000; +} + +qint64 QElapsedTimer::secsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW +{ + return msecsTo(other) / 1000; +} + +bool operator<(const QElapsedTimer &v1, const QElapsedTimer &v2) Q_DECL_NOTHROW +{ + return (v1.t1 - v2.t1) < 0; +} + +QT_END_NAMESPACE diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm index 55f27a5b60..437e4062ad 100644 --- a/src/corelib/kernel/qeventdispatcher_cf.mm +++ b/src/corelib/kernel/qeventdispatcher_cf.mm @@ -210,6 +210,13 @@ QEventDispatcherCoreFoundation::~QEventDispatcherCoreFoundation() m_cfSocketNotifier.removeSocketNotifiers(); } +QEventLoop *QEventDispatcherCoreFoundation::currentEventLoop() const +{ + QEventLoop *eventLoop = QThreadData::current()->eventLoops.top(); + Q_ASSERT(eventLoop); + return eventLoop; +} + /*! Processes all pending events that match \a flags until there are no more events to process. Returns \c true if pending events were handled; @@ -302,10 +309,7 @@ bool QEventDispatcherCoreFoundation::processEvents(QEventLoop::ProcessEventsFlag // to exit, and then unwind back to the previous event loop which will break // immediately, since it has already been exited. - QEventLoop *currentEventLoop = QThreadData::current()->eventLoops.top(); - Q_ASSERT(currentEventLoop); - - if (!currentEventLoop->isRunning()) { + if (!currentEventLoop()->isRunning()) { qEventDispatcherDebug() << "Top level event loop was exited"; break; } else { diff --git a/src/corelib/kernel/qeventdispatcher_cf_p.h b/src/corelib/kernel/qeventdispatcher_cf_p.h index c2592cacc8..e6581e2bac 100644 --- a/src/corelib/kernel/qeventdispatcher_cf_p.h +++ b/src/corelib/kernel/qeventdispatcher_cf_p.h @@ -228,6 +228,8 @@ public: void flush(); protected: + QEventLoop *currentEventLoop() const; + virtual bool processPostedEvents(); struct ProcessEventsState diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 166e509635..1a0efae2dc 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -55,7 +55,6 @@ QT_BEGIN_NAMESPACE -HINSTANCE qWinAppInst(); extern uint qGlobalPostedEventsCount(); #ifndef TIME_KILL_SYNCHRONOUS @@ -63,11 +62,7 @@ extern uint qGlobalPostedEventsCount(); #endif #ifndef QS_RAWINPUT -# ifdef Q_OS_WINCE -# define QS_RAWINPUT 0x0000 -# else # define QS_RAWINPUT 0x0400 -# endif #endif #ifndef WM_TOUCH @@ -89,230 +84,14 @@ enum { SendPostedEventsWindowsTimerId = ~1u }; -#if defined(Q_OS_WINCE) -QT_BEGIN_INCLUDE_NAMESPACE -#include <winsock.h> -QT_END_INCLUDE_NAMESPACE -// Asynchronous Winsocks ------------------------------------------ -#ifndef QT_NO_THREAD -QT_BEGIN_INCLUDE_NAMESPACE -#include <qthread.h> -#include <qmap.h> -#include <qmutex.h> -QT_END_INCLUDE_NAMESPACE - -//#define QCE_ASYNC_DEBUG - -namespace { - class SocketAsyncHandler; - - class SocketAsyncHandler : public QThread - { - public: - SocketAsyncHandler(); - ~SocketAsyncHandler(); - void run(); - void select(SOCKET sock, HWND handle, unsigned int msg, long ev); - void removeSelect(SOCKET sock); - void safeRemove(SOCKET sock); - private: - struct SockInfo { - HWND handle; - unsigned int msg; - long ev; - }; - QMap<SOCKET, SockInfo> sockets; - QMutex mutex; - QWaitCondition cond; - bool supposedToDie; - }; - - SocketAsyncHandler::SocketAsyncHandler() - : supposedToDie(false) - { - } - - SocketAsyncHandler::~SocketAsyncHandler() - { - mutex.lock(); - supposedToDie = true; - mutex.unlock(); - cond.wakeOne(); - wait(); - while (sockets.size() > 0) - removeSelect(sockets.begin().key()); - } - - void SocketAsyncHandler::removeSelect(SOCKET sock) - { - if (!sockets.contains(sock)) - return; - sockets.remove(sock); - return; - } - - void SocketAsyncHandler::safeRemove(SOCKET sock) - { - QMutexLocker locker(&mutex); - removeSelect(sock); - } - - void SocketAsyncHandler::select(SOCKET sock, HWND handle, unsigned int msg, long ev) - { - QMutexLocker locker(&mutex); - - if (sockets.contains(sock)) - sockets.remove(sock); - - SockInfo info; - info.handle = handle; - info.msg = msg; - info.ev = ev; - sockets.insert(sock, info); - cond.wakeOne(); - } - - void SocketAsyncHandler::run() - { - do { - mutex.lock(); - - while (!supposedToDie && sockets.isEmpty()) { - cond.wait(&mutex); - } - - if (supposedToDie) { - mutex.unlock(); - break; - } - - // Copy current items to reduce lock time - // and to be able to use SendMessage - QMap<SOCKET, SockInfo> currentSockets = sockets; - mutex.unlock(); - - fd_set readS, writeS, exS; - FD_ZERO(&readS); - FD_ZERO(&writeS); - FD_ZERO(&exS); - - int maxFd = 0; - - for (QMap<SOCKET, SockInfo>::iterator it = currentSockets.begin(); it != currentSockets.end(); ++it) { - const SockInfo &info = it.value(); - int socket = it.key(); - maxFd = qMax(maxFd, socket); - - if ((info.ev & FD_READ) || (info.ev & FD_CLOSE) || (info.ev & FD_ACCEPT)) - FD_SET(socket, &readS); - if ((info.ev & FD_WRITE)|| (info.ev & FD_CONNECT)) - FD_SET(socket, &writeS); - if (info.ev & FD_OOB) - FD_SET(socket, &exS); - } - - timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 50000; - int result = ::select(maxFd + 1, &readS, &writeS, &exS, &timeout); - if (result > 0) { - HWND handle; - unsigned int tmpMsg; - SOCKET sock; - HRESULT ret; - for (QMap<SOCKET, SockInfo>::const_iterator it = currentSockets.constBegin(); - it != currentSockets.constEnd(); ++it) { - handle = (*it).handle; - tmpMsg = (*it).msg; - sock = it.key(); - if (FD_ISSET(sock, &readS)) - ret = SendMessage(handle, tmpMsg, sock, FD_READ); - - if (FD_ISSET(sock, &writeS)) - ret = SendMessage(handle, tmpMsg, sock, FD_WRITE); - - if (FD_ISSET(sock, &exS)) - ret = SendMessage(handle, tmpMsg, sock, FD_OOB); - } - } - -#ifdef QCE_ASYNC_DEBUG - else if (result == 0) { //timeout - qDebug(" WSAAsync select timeout"); - } else if (result < 0) { // SocketError - // This might happen because of two reasons - // 1. We already closed a socket in between the copy and the select - // and thus select() returns an error - // 2. Something is really wrong, then - // ### Loop on all descriptors, try to select and remove the - // ### broken one. - qWarning("WSAAsync select error %d", WSAGetLastError()); - } -#endif - } while(true); - } -} // namespace - -Q_GLOBAL_STATIC(SocketAsyncHandler, qt_async_handler) - -int WSAAsyncSelect(SOCKET sock, HWND handle, unsigned int msg, long ev) -{ - if (sock == 0 || handle == 0 || handle == INVALID_HANDLE_VALUE) { - WSASetLastError(WSAEINVAL); - return SOCKET_ERROR; - } - - if (msg == 0 && ev == 0) - qt_async_handler()->safeRemove(sock); - else - qt_async_handler()->select(sock, handle, msg, ev); - - qt_async_handler()->start(QThread::LowPriority); - WSASetLastError(0); - return 0; -} -#else // QT_NO_THREAD -int WSAAsyncSelect(SOCKET, HWND, unsigned int, long) -{ - return SOCKET_ERROR; -} -#endif -#endif // Q_OS_WINCE - class QEventDispatcherWin32Private; #if !defined(DWORD_PTR) && !defined(Q_OS_WIN64) #define DWORD_PTR DWORD #endif -typedef MMRESULT(WINAPI *ptimeSetEvent)(UINT, UINT, LPTIMECALLBACK, DWORD_PTR, UINT); -typedef MMRESULT(WINAPI *ptimeKillEvent)(UINT); - -static ptimeSetEvent qtimeSetEvent = 0; -static ptimeKillEvent qtimeKillEvent = 0; - LRESULT QT_WIN_CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp); -static void resolveTimerAPI() -{ - static bool triedResolve = false; - if (!triedResolve) { -#ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&triedResolve)); - if (triedResolve) - return; -#endif - triedResolve = true; -#if !defined(Q_OS_WINCE) - qtimeSetEvent = (ptimeSetEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeSetEvent"); - qtimeKillEvent = (ptimeKillEvent)QSystemLibrary::resolve(QLatin1String("winmm"), "timeKillEvent"); -#else - qtimeSetEvent = (ptimeSetEvent)QSystemLibrary::resolve(QLatin1String("Mmtimer"), "timeSetEvent"); - qtimeKillEvent = (ptimeKillEvent)QSystemLibrary::resolve(QLatin1String("Mmtimer"), "timeKillEvent"); -#endif - } -} - QEventDispatcherWin32Private::QEventDispatcherWin32Private() : threadId(GetCurrentThreadId()), interrupt(false), closingDown(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), sendPostedEventsWindowsTimerId(0), @@ -321,7 +100,6 @@ QEventDispatcherWin32Private::QEventDispatcherWin32Private() , activateNotifiersPosted(false) #endif { - resolveTimerAPI(); } QEventDispatcherWin32Private::~QEventDispatcherWin32Private() @@ -502,11 +280,7 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp) } } } -#ifdef Q_OS_WINCE - return 0; -#else return q->d_func()->getMessageHook ? CallNextHookEx(0, code, wp, lp) : 0; -#endif } // Provide class name and atom for the message window used by @@ -535,7 +309,7 @@ QWindowsMessageWindowClassContext::QWindowsMessageWindowClassContext() wc.lpfnWndProc = qt_internal_proc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; - wc.hInstance = qWinAppInst(); + wc.hInstance = GetModuleHandle(0); wc.hIcon = 0; wc.hCursor = 0; wc.hbrBackground = 0; @@ -552,7 +326,7 @@ QWindowsMessageWindowClassContext::QWindowsMessageWindowClassContext() QWindowsMessageWindowClassContext::~QWindowsMessageWindowClassContext() { if (className) { - UnregisterClass(className, qWinAppInst()); + UnregisterClass(className, GetModuleHandle(0)); delete [] className; } } @@ -564,18 +338,13 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch QWindowsMessageWindowClassContext *ctx = qWindowsMessageWindowClassContext(); if (!ctx->atom) return 0; -#ifdef Q_OS_WINCE - HWND parent = 0; -#else - HWND parent = HWND_MESSAGE; -#endif HWND wnd = CreateWindow(ctx->className, // classname ctx->className, // window name 0, // style 0, 0, 0, 0, // geometry - parent, // parent + HWND_MESSAGE, // parent 0, // menu handle - qWinAppInst(), // application + GetModuleHandle(0), // application 0); // windows creation data. if (!wnd) { @@ -609,24 +378,27 @@ void QEventDispatcherWin32Private::registerTimer(WinTimerInfo *t) Q_Q(QEventDispatcherWin32); - int ok = 0; + bool ok = false; calculateNextTimeout(t, qt_msectime()); uint interval = t->interval; if (interval == 0u) { // optimization for single-shot-zero-timer QCoreApplication::postEvent(q, new QZeroTimerEvent(t->timerId)); - ok = 1; - } else if ((interval < 20u || t->timerType == Qt::PreciseTimer) && qtimeSetEvent) { - ok = t->fastTimerId = qtimeSetEvent(interval, 1, qt_fast_timer_proc, (DWORD_PTR)t, - TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS); + ok = true; + } else if (interval < 20u || t->timerType == Qt::PreciseTimer) { + // 3/2016: Although MSDN states timeSetEvent() is deprecated, the function + // is still deemed to be the most reliable precision timer. + t->fastTimerId = timeSetEvent(interval, 1, qt_fast_timer_proc, DWORD_PTR(t), + TIME_CALLBACK_FUNCTION | TIME_PERIODIC | TIME_KILL_SYNCHRONOUS); + ok = t->fastTimerId; } - if (ok == 0) { + if (!ok) { // user normal timers for (Very)CoarseTimers, or if no more multimedia timers available ok = SetTimer(internalHwnd, t->timerId, interval, 0); } - if (ok == 0) + if (!ok) qErrnoWarning("QEventDispatcherWin32::registerTimer: Failed to create a timer"); } @@ -635,7 +407,7 @@ void QEventDispatcherWin32Private::unregisterTimer(WinTimerInfo *t) if (t->interval == 0) { QCoreApplicationPrivate::removePostedTimerEvent(t->dispatcher, t->timerId); } else if (t->fastTimerId != 0) { - qtimeKillEvent(t->fastTimerId); + timeKillEvent(t->fastTimerId); QCoreApplicationPrivate::removePostedTimerEvent(t->dispatcher, t->timerId); } else if (internalHwnd) { KillTimer(internalHwnd, t->timerId); @@ -702,7 +474,6 @@ void QEventDispatcherWin32::installMessageHook() if (d->getMessageHook) return; -#ifndef Q_OS_WINCE // setup GetMessage hook needed to drive our posted events d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId()); if (Q_UNLIKELY(!d->getMessageHook)) { @@ -710,17 +481,14 @@ void QEventDispatcherWin32::installMessageHook() qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s", errorCode, qPrintable(qt_error_string(errorCode))); } -#endif } void QEventDispatcherWin32::uninstallMessageHook() { Q_D(QEventDispatcherWin32); -#ifndef Q_OS_WINCE if (d->getMessageHook) UnhookWindowsHookEx(d->getMessageHook); -#endif d->getMessageHook = 0; } @@ -1166,11 +934,7 @@ void QEventDispatcherWin32::activateEventNotifiers() Q_D(QEventDispatcherWin32); //### this could break if events are removed/added in the activation for (int i=0; i<d->winEventNotifierList.count(); i++) { -#if !defined(Q_OS_WINCE) if (WaitForSingleObjectEx(d->winEventNotifierList.at(i)->handle(), 0, TRUE) == WAIT_OBJECT_0) -#else - if (WaitForSingleObject(d->winEventNotifierList.at(i)->handle(), 0) == WAIT_OBJECT_0) -#endif d->activateEventNotifier(d->winEventNotifierList.at(i)); } } diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index a87b56cd38..773315c04f 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -138,7 +138,7 @@ struct WinTimerInfo { // internal timer info quint64 timeout; // - when to actually fire QObject *obj; // - object to receive events bool inTimerEvent; - int fastTimerId; + UINT fastTimerId; }; class QZeroTimerEvent : public QTimerEvent diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index 2ffcf03eb2..3b2321aa49 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -95,6 +95,51 @@ private: std::function<HRESULT()> delegate; }; +class QWorkHandler : public IWorkItemHandler +{ +public: + QWorkHandler(const std::function<HRESULT()> &delegate) + : m_delegate(delegate) + { + } + + STDMETHODIMP Invoke(ABI::Windows::Foundation::IAsyncAction *operation) + { + HRESULT res = m_delegate(); + Q_UNUSED(operation); + return res; + } + + STDMETHODIMP QueryInterface(REFIID riid, void FAR* FAR* ppvObj) + { + if (riid == IID_IUnknown || riid == IID_IWorkItemHandler) { + *ppvObj = this; + AddRef(); + return NOERROR; + } + *ppvObj = NULL; + return ResultFromScode(E_NOINTERFACE); + } + + STDMETHODIMP_(ULONG) AddRef(void) + { + return ++m_refs; + } + + STDMETHODIMP_(ULONG) Release(void) + { + if (--m_refs == 0) { + delete this; + return 0; + } + return m_refs; + } + +private: + std::function<HRESULT()> m_delegate; + ULONG m_refs{0}; +}; + class QEventDispatcherWinRTPrivate : public QAbstractEventDispatcherPrivate { Q_DECLARE_PUBLIC(QEventDispatcherWinRT) @@ -175,48 +220,62 @@ QEventDispatcherWinRT::~QEventDispatcherWinRT() HRESULT QEventDispatcherWinRT::runOnXamlThread(const std::function<HRESULT ()> &delegate, bool waitForRun) { static __declspec(thread) ICoreDispatcher *dispatcher = nullptr; + HRESULT hr; if (!dispatcher) { - HRESULT hr; ComPtr<ICoreImmersiveApplication> application; hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(), IID_PPV_ARGS(&application)); ComPtr<ICoreApplicationView> view; hr = application->get_MainView(&view); - Q_ASSERT_SUCCEEDED(hr); - ComPtr<ICoreWindow> window; - hr = view->get_CoreWindow(&window); - Q_ASSERT_SUCCEEDED(hr); - if (!window) { - // In case the application is launched via activation - // there might not be a main view (eg ShareTarget). - // Hence iterate through the available views and try to find - // a dispatcher in there - ComPtr<IVectorView<CoreApplicationView*>> appViews; - hr = application->get_Views(&appViews); + if (SUCCEEDED(hr) && view) { + ComPtr<ICoreWindow> window; + hr = view->get_CoreWindow(&window); Q_ASSERT_SUCCEEDED(hr); - quint32 count; - hr = appViews->get_Size(&count); - Q_ASSERT_SUCCEEDED(hr); - for (quint32 i = 0; i < count; ++i) { - hr = appViews->GetAt(i, &view); + if (!window) { + // In case the application is launched via activation + // there might not be a main view (eg ShareTarget). + // Hence iterate through the available views and try to find + // a dispatcher in there + ComPtr<IVectorView<CoreApplicationView*>> appViews; + hr = application->get_Views(&appViews); Q_ASSERT_SUCCEEDED(hr); - hr = view->get_CoreWindow(&window); + quint32 count; + hr = appViews->get_Size(&count); Q_ASSERT_SUCCEEDED(hr); - if (window) { - hr = window->get_Dispatcher(&dispatcher); + for (quint32 i = 0; i < count; ++i) { + hr = appViews->GetAt(i, &view); + Q_ASSERT_SUCCEEDED(hr); + hr = view->get_CoreWindow(&window); Q_ASSERT_SUCCEEDED(hr); - if (dispatcher) - break; + if (window) { + hr = window->get_Dispatcher(&dispatcher); + Q_ASSERT_SUCCEEDED(hr); + if (dispatcher) + break; + } } + } else { + hr = window->get_Dispatcher(&dispatcher); + Q_ASSERT_SUCCEEDED(hr); } - Q_ASSERT(dispatcher); - } else { - hr = window->get_Dispatcher(&dispatcher); - Q_ASSERT_SUCCEEDED(hr); } } - HRESULT hr; + if (Q_UNLIKELY(!dispatcher)) { + // In case the application is launched in a way that has no UI and + // also does not allow to create one, e.g. as a background task. + // Features like network operations do still work, others might cause + // errors in that case. + ComPtr<IThreadPoolStatics> tpStatics; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_System_Threading_ThreadPool).Get(), + IID_PPV_ARGS(&tpStatics)); + ComPtr<IAsyncAction> op; + hr = tpStatics.Get()->RunAsync(new QWorkHandler(delegate), &op); + if (FAILED(hr) || !waitForRun) + return hr; + return QWinRTFunctions::await(op); + } + boolean onXamlThread; hr = dispatcher->get_HasThreadAccess(&onXamlThread); Q_ASSERT_SUCCEEDED(hr); diff --git a/src/corelib/kernel/qeventdispatcher_winrt_p.h b/src/corelib/kernel/qeventdispatcher_winrt_p.h index abcb3bf99c..f69bb9cf3f 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt_p.h +++ b/src/corelib/kernel/qeventdispatcher_winrt_p.h @@ -52,6 +52,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include "QtCore/qabstracteventdispatcher.h" #include <qt_windows.h> diff --git a/src/corelib/kernel/qfunctions_p.h b/src/corelib/kernel/qfunctions_p.h index 06f5ea09da..715c553dc5 100644 --- a/src/corelib/kernel/qfunctions_p.h +++ b/src/corelib/kernel/qfunctions_p.h @@ -51,11 +51,9 @@ #ifndef QFUNCTIONS_P_H #define QFUNCTIONS_P_H -#include <QtCore/qglobal.h> +#include <QtCore/private/qglobal_p.h> -#if defined(Q_OS_WINCE) -# include "QtCore/qfunctions_wince.h" -#elif defined(Q_OS_VXWORKS) +#if defined(Q_OS_VXWORKS) # include "QtCore/qfunctions_vxworks.h" #elif defined(Q_OS_NACL) # include "QtCore/qfunctions_nacl.h" diff --git a/src/corelib/kernel/qfunctions_wince.cpp b/src/corelib/kernel/qfunctions_wince.cpp deleted file mode 100644 index 104c6fb27c..0000000000 --- a/src/corelib/kernel/qfunctions_wince.cpp +++ /dev/null @@ -1,407 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifdef _WIN32_WCE //Q_OS_WINCE - -#include <windows.h> -#include <winbase.h> -#include <kfuncs.h> -#include <stdio.h> -#if _WIN32_WCE < 0x800 -# include <altcecrt.h> -#else -# include <fcntl.h> -#endif - -#include "qplatformdefs.h" -#include "qfunctions_wince.h" -#include "qfunctions_fake_env_p.h" -#include "qstring.h" - -QT_USE_NAMESPACE - -#ifdef __cplusplus -extern "C" { -#endif - -wchar_t* CEPrivConvCharToWide(const char* string) -{ - size_t length = strlen(string); - wchar_t* wString = new wchar_t[length +1]; - for (unsigned int i = 0; i < (length +1); i++) - wString[i] = string[i]; - return wString; -} - -// Time ------------------------------------------------------------- -time_t qt_wince_ftToTime_t( const FILETIME ft ) -{ - ULARGE_INTEGER li; - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - - // 100-nanosec to seconds - li.QuadPart /= 10000000; - - // FILETIME is from 1601-01-01 T 00:00:00 - // time_t is from 1970-01-01 T 00:00:00 - // 1970 - 1601 = 369 year (89 leap years) - // - // ((369y*365d) + 89d) *24h *60min *60sec - // = 11644473600 seconds - li.QuadPart -= 11644473600; - return li.LowPart; -} - -FILETIME qt_wince_time_tToFt( time_t tt ) -{ - ULARGE_INTEGER li; - li.QuadPart = tt; - li.QuadPart += 11644473600; - li.QuadPart *= 10000000; - - FILETIME ft; - ft.dwLowDateTime = li.LowPart; - ft.dwHighDateTime = li.HighPart; - return ft; -} - -// File I/O --------------------------------------------------------- -#if _WIN32_WCE < 0x800 -int errno = 0; -#endif - -int qt_wince__getdrive( void ) -{ - return 1; -} - -int qt_wince__waccess( const wchar_t *path, int pmode ) -{ - DWORD res = GetFileAttributes( path ); - if ( 0xFFFFFFFF == res ) - return -1; - - if ( (pmode & W_OK) && (res & FILE_ATTRIBUTE_READONLY) ) - return -1; - - if ( (pmode & X_OK) && !(res & FILE_ATTRIBUTE_DIRECTORY) ) { - QString file = QString::fromWCharArray(path); - if ( !(file.endsWith(QString::fromLatin1(".exe")) || - file.endsWith(QString::fromLatin1(".com"))) ) - return -1; - } - - return 0; -} - -int qt_wince_open( const char *filename, int oflag, int pmode ) -{ - QString fn( QString::fromLatin1(filename) ); - return _wopen( (wchar_t*)fn.utf16(), oflag, pmode ); -} - -int qt_wince__wopen( const wchar_t *filename, int oflag, int /*pmode*/ ) -{ - wchar_t *flag; - - if ( oflag & _O_APPEND ) { - if ( oflag & _O_WRONLY ) { - flag = L"a"; - } else if ( oflag & _O_RDWR ) { - flag = L"a+"; - } - } else if (oflag & _O_BINARY) { - if ( oflag & _O_WRONLY ) { - flag = L"wb"; - } else if ( oflag & _O_RDWR ) { - flag = L"w+b"; // slightly different from "r+" where the file must exist - } else if ( oflag & _O_RDONLY ) { - flag = L"rb"; - } else { - flag = L"b"; - } - } else { - if ( oflag & _O_WRONLY ) { - flag = L"wt"; - } else if ( oflag & _O_RDWR ) { - flag = L"w+t"; // slightly different from "r+" where the file must exist - } else if ( oflag & _O_RDONLY ) { - flag = L"rt"; - } else { - flag = L"t"; - } - } - - int retval = (int)_wfopen( filename, flag ); - return (retval == NULL) ? -1 : retval; -} - -long qt_wince__lseek( int handle, long offset, int origin ) -{ - return fseek( (FILE*)handle, offset, origin ); -} - -int qt_wince__read( int handle, void *buffer, unsigned int count ) -{ - return fread( buffer, 1, count, (FILE*)handle ); -} - -int qt_wince__write( int handle, const void *buffer, unsigned int count ) -{ - return fwrite( buffer, 1, count, (FILE*)handle ); -} - -int qt_wince__close( int handle ) -{ - if (!handle) - return 0; - return fclose( (FILE*)handle ); -} - -FILE *qt_wince__fdopen(int handle, const char* /*mode*/) -{ - return (FILE*)handle; -} - -FILE *qt_wince_fdopen( int handle, const char* /*mode*/ ) -{ - return (FILE*)handle; -} - -void qt_wince_rewind( FILE *stream ) -{ - fseek( stream, 0L, SEEK_SET ); -} - -int qt_wince___fileno(FILE *f) -{ - return (int) _fileno(f); -} - -FILE *qt_wince_tmpfile( void ) -{ - static long i = 0; - char name[16]; - sprintf( name, "tmp%i", i++ ); - return fopen( name, "r+" ); -} - -int qt_wince__mkdir(const char *dirname) -{ - return CreateDirectory(reinterpret_cast<const wchar_t *> (QString(QString::fromLatin1(dirname)).utf16()), 0) ? 0 : -1; -} - -int qt_wince__rmdir(const char *dirname) -{ - return RemoveDirectory(reinterpret_cast<const wchar_t *> (QString::fromLatin1(dirname).utf16())) ? 0 : -1; -} - -int qt_wince__access( const char *path, int pmode ) -{ - return _waccess(reinterpret_cast<const wchar_t *> (QString::fromLatin1(path).utf16()),pmode); -} - -int qt_wince__rename( const char *oldname, const char *newname ) -{ - return !MoveFile(reinterpret_cast<const wchar_t *> (QString::fromLatin1(oldname).utf16()), reinterpret_cast<const wchar_t *> (QString::fromLatin1(newname).utf16())); -} - -int qt_wince__remove( const char *name ) -{ - return !DeleteFile(reinterpret_cast<const wchar_t *> (QString::fromLatin1(name).utf16())); -} - -int qt_wince_stat( const char *path, struct stat *buffer ) -{ - WIN32_FIND_DATA finfo; - HANDLE ff = FindFirstFile( reinterpret_cast<const wchar_t *> (QString::fromLatin1(path).utf16()), &finfo ); - - if ( ff == INVALID_HANDLE_VALUE ) - return -1; - - buffer->st_ctime = qt_wince_ftToTime_t( finfo.ftCreationTime ); - buffer->st_atime = qt_wince_ftToTime_t( finfo.ftLastAccessTime ); - buffer->st_mtime = qt_wince_ftToTime_t( finfo.ftLastWriteTime ); - buffer->st_nlink = 0; - buffer->st_size = finfo.nFileSizeLow; // ### missing high! - buffer->st_mode = (finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _S_IFDIR : _S_IFREG; - buffer->st_mode |= (finfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _O_RDONLY : _O_RDWR; - return (FindClose(ff) == 0); -} - -int qt_wince__fstat( int handle, struct stat *buffer) -{ - BY_HANDLE_FILE_INFORMATION fInfo; - BOOL res = GetFileInformationByHandle((HANDLE)handle, &fInfo); - - buffer->st_ctime = qt_wince_ftToTime_t( fInfo.ftCreationTime ); - buffer->st_atime = qt_wince_ftToTime_t( fInfo.ftLastAccessTime ); - buffer->st_mtime = qt_wince_ftToTime_t( fInfo.ftLastWriteTime ); - buffer->st_nlink = 0; - buffer->st_size = fInfo.nFileSizeLow; // ### missing high! - buffer->st_mode = (fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ? _S_IFDIR : _S_IFREG; - buffer->st_mode |= (fInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ? _O_RDONLY : _O_RDWR; - return (res == 0); -} - -int qt_wince_SetErrorMode(int newValue) -{ - static int oldValue; - int result = oldValue; - oldValue = newValue; - return result; -} - -bool qt_wince__chmod(const char *file, int mode) -{ - return _wchmod( reinterpret_cast<const wchar_t *> (QString::fromLatin1(file).utf16()), mode); -} - -bool qt_wince__wchmod(const wchar_t *file, int mode) -{ - BOOL success = FALSE; - // ### Does not work properly, what about just adding one property? - if(mode&_S_IWRITE) { - success = SetFileAttributes(file, FILE_ATTRIBUTE_NORMAL); - } else if((mode&_S_IREAD) && !(mode&_S_IWRITE)) { - success = SetFileAttributes(file, FILE_ATTRIBUTE_READONLY); - } - return success ? 0 : -1; -} - -HANDLE qt_wince_CreateFileA(LPCSTR filename, DWORD access, DWORD share, LPSECURITY_ATTRIBUTES attr, DWORD dispo, DWORD flags, HANDLE tempFile) -{ - return CreateFileW( reinterpret_cast<const wchar_t *>(QString::fromLatin1(filename).utf16()), access, share, attr, dispo, flags, tempFile); -} - -// Graphics --------------------------------------------------------- -BOOL qt_wince_SetWindowOrgEx( HDC /*hdc*/, int /*X*/, int /*Y*/, LPPOINT /*lpPoint*/) { - return TRUE; -} - -// Threading -------------------------------------------------------- -HANDLE qt_wince__beginthread(void( *start_address )( void * ), unsigned stack_size, void *arglist) -{ - unsigned initflag = 0; - if (stack_size > 0) - initflag |= STACK_SIZE_PARAM_IS_A_RESERVATION; - return CreateThread(NULL, stack_size, (LPTHREAD_START_ROUTINE)start_address, arglist, initflag, NULL); -} - -unsigned long qt_wince__beginthreadex( void *security, - unsigned stack_size, - unsigned (__stdcall *start_address)(void *), - void *arglist, - unsigned initflag, - unsigned *thrdaddr) -{ - if (stack_size > 0) - initflag |= STACK_SIZE_PARAM_IS_A_RESERVATION; - return (unsigned long) - CreateThread( (LPSECURITY_ATTRIBUTES)security, - (DWORD)stack_size, - (LPTHREAD_START_ROUTINE)start_address, - (LPVOID)arglist, - (DWORD)initflag | CREATE_SUSPENDED, - (LPDWORD)thrdaddr); -} - -void qt_wince__endthreadex(unsigned nExitCode) { - ExitThread((DWORD)nExitCode); -} - -void *qt_wince_bsearch(const void *key, - const void *base, - size_t num, - size_t size, - int (__cdecl *compare)(const void *, const void *)) -{ - size_t low = 0; - size_t high = num - 1; - while (low <= high) { - size_t mid = (low + high) >> 1; - int c = compare(key, (char*)base + mid * size); - if (c < 0) { - if (!mid) - break; - high = mid - 1; - } else if (c > 0) - low = mid + 1; - else - return (char*) base + mid * size; - } - return 0; -} - -void *lfind(const void* key, const void* base, size_t* elements, size_t size, - int (__cdecl *compare)(const void*, const void*)) -{ - const char* current = (char*) base; - const char* const end = (char*) (current + (*elements) * size); - while (current != end) { - if (compare(current, key) == 0) - return (void*)current; - current += size; - } - return 0; -} - -DWORD qt_wince_GetThreadLocale(void) -{ - return GetUserDefaultLCID(); -} - -void *qt_wince_calloc( size_t num, size_t size ) -{ - void *ptr = malloc( num * size ); - if( ptr ) - memset( ptr, 0, num * size ); - return ptr; -} - -// _getpid is currently only used for creating a temporary filename -int qt_wince__getpid() -{ - return qAbs((int)GetCurrentProcessId()); -} - -#ifdef __cplusplus -} // extern "C" -#endif -#endif // Q_OS_WINCE diff --git a/src/corelib/kernel/qfunctions_wince.h b/src/corelib/kernel/qfunctions_wince.h deleted file mode 100644 index 030950e1bd..0000000000 --- a/src/corelib/kernel/qfunctions_wince.h +++ /dev/null @@ -1,473 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtCore module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QFUNCTIONS_WINCE_H -#define QFUNCTIONS_WINCE_H - -#include <QtCore/qglobal.h> - -#ifdef Q_OS_WINCE -# ifndef NOMINMAX -# define NOMINMAX -# endif -#include <stdio.h> -#include <stdlib.h> -#include <windows.h> -#include <winuser.h> -#include <winbase.h> -#include <objbase.h> -#include <kfuncs.h> -#include <ctype.h> -#include <time.h> -#include <crtdefs.h> -#if _WIN32_WCE < 0x800 -# include <altcecrt.h> -#else -# include <fcntl.h> -# include <stat.h> -#endif -#include <winsock.h> -#include <ceconfig.h> - -QT_BEGIN_NAMESPACE - -#ifdef QT_BUILD_CORE_LIB -#endif - -QT_END_NAMESPACE - -// The standard SDK misses this define... -#define _control87 _controlfp - -#if !defined __cplusplus -#define bool int -#define true 1 -#define false 0 -#endif - -// Environment ------------------------------------------------------ -errno_t qt_fake_getenv_s(size_t*, char*, size_t, const char*); -errno_t qt_fake__putenv_s(const char*, const char*); - -#ifdef __cplusplus // have this as tiff plugin is written in C -extern "C" { -#endif - -#if !defined(NO_ERRNO_H) -#define NO_ERRNO_H -#endif - -// Environment ------------------------------------------------------ -int qt_wince__getpid(void); - - -// Time ------------------------------------------------------------- -#ifndef _TM_DEFINED -#define _TM_DEFINED -struct tm { - int tm_sec; /* seconds after the minute - [0,59] */ - int tm_min; /* minutes after the hour - [0,59] */ - int tm_hour; /* hours since midnight - [0,23] */ - int tm_mday; /* day of the month - [1,31] */ - int tm_mon; /* months since January - [0,11] */ - int tm_year; /* years since 1900 */ - int tm_wday; /* days since Sunday - [0,6] */ - int tm_yday; /* days since January 1 - [0,365] */ - int tm_isdst; /* daylight-saving time flag */ -}; -#endif // _TM_DEFINED - -FILETIME qt_wince_time_tToFt( time_t tt ); -time_t qt_wince_ftToTime_t( const FILETIME ft ); - -#if _WIN32_WCE < 0x800 - -// File I/O --------------------------------------------------------- -#define _O_RDONLY 0x0001 -#define _O_RDWR 0x0002 -#define _O_WRONLY 0x0004 -#define _O_CREAT 0x0008 -#define _O_TRUNC 0x0010 -#define _O_APPEND 0x0020 -#define _O_EXCL 0x0040 - -#define O_RDONLY _O_RDONLY -#define O_RDWR _O_RDWR -#define O_WRONLY _O_WRONLY -#define O_CREAT _O_CREAT -#define O_TRUNC _O_TRUNC -#define O_APPEND _O_APPEND -#define O_EXCL _O_EXCL - -#define _S_IFMT 0x0600 -#define _S_IFDIR 0x0200 -#define _S_IFCHR 0x0100 -#define _S_IFREG 0x0400 -#define _S_IREAD 0x0010 -#define _S_IWRITE 0x0008 - -#define S_IFMT _S_IFMT -#define S_IFDIR _S_IFDIR -#define S_IFCHR _S_IFCHR -#define S_IFREG _S_IFREG -#define S_IREAD _S_IREAD -#define S_IWRITE _S_IWRITE - -#ifndef _IOFBF -#define _IOFBF 0x0000 -#endif - -#ifndef _IOLBF -#define _IOLBF 0x0040 -#endif - -#ifndef _IONBF -#define _IONBF 0x0004 -#endif - -// Regular Berkeley error constants -#ifndef _STAT_DEFINED -#define _STAT_DEFINED -struct stat -{ - int st_mode; - int st_size; - int st_nlink; - time_t st_mtime; - time_t st_atime; - time_t st_ctime; -}; -#endif - -typedef int mode_t; -extern int errno; -#endif // _WIN32_WCE < 0x800 - -int qt_wince__getdrive( void ); -int qt_wince__waccess( const wchar_t *path, int pmode ); -int qt_wince__wopen( const wchar_t *filename, int oflag, int pmode ); -long qt_wince__lseek( int handle, long offset, int origin ); -int qt_wince__read( int handle, void *buffer, unsigned int count ); -int qt_wince__write( int handle, const void *buffer, unsigned int count ); -int qt_wince__close( int handle ); -FILE *qt_wince__fdopen(int handle, const char *mode); -FILE *qt_wince_fdopen(int handle, const char *mode); -void qt_wince_rewind( FILE *stream ); -int qt_wince___fileno(FILE *); -FILE *qt_wince_tmpfile( void ); - -//For zlib we need these helper functions, but they break the build when -//set globally, so just set them for zlib use -#ifdef ZLIB_H -#define open qt_wince_open -#define close qt_wince__close -#define lseek qt_wince__lseek -#define read qt_wince__read -#define write qt_wince__write -#endif - -int qt_wince__mkdir(const char *dirname); -int qt_wince__rmdir(const char *dirname); -int qt_wince__access( const char *path, int pmode ); -int qt_wince__rename( const char *oldname, const char *newname ); -int qt_wince__remove( const char *name ); -#ifdef __cplusplus -int qt_wince_open( const char *filename, int oflag, int pmode = 0 ); -#else -int qt_wince_open( const char *filename, int oflag, int pmode ); -#endif -int qt_wince_stat( const char *path, struct stat *buffer ); -int qt_wince__fstat( int handle, struct stat *buffer); - -#define SEM_FAILCRITICALERRORS 0x0001 -#define SEM_NOOPENFILEERRORBOX 0x0002 -int qt_wince_SetErrorMode(int); -#ifndef CoInitialize -#define CoInitialize(x) CoInitializeEx(x, COINIT_MULTITHREADED) -#endif - -bool qt_wince__chmod(const char *file, int mode); -bool qt_wince__wchmod(const wchar_t *file, int mode); - -QT_WARNING_DISABLE_MSVC(4273) -HANDLE qt_wince_CreateFileA(LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE); - -// Printer ---------------------------------------------------------- -#define ETO_GLYPH_INDEX 0x0010 - -// Graphics --------------------------------------------------------- -#ifndef SM_CXCURSOR -# define SM_CXCURSOR 13 -#endif -#ifndef SM_CYCURSOR -# define SM_CYCURSOR 14 -#endif -BOOL qt_wince_SetWindowOrgEx( HDC hdc, int X, int Y, LPPOINT lpPoint ); - -// Other stuff ------------------------------------------------------ -#define MWMO_ALERTABLE 0x0002 -// ### not the real values -#define CREATE_NO_WINDOW 2 -#define CF_HDROP 15 - -void *qt_wince_calloc(size_t num, size_t size); -#if !defined(TLS_OUT_OF_INDEXES) -# define TLS_OUT_OF_INDEXES 0xffffffff -#endif -DWORD qt_wince_GetThreadLocale(void); - -HANDLE qt_wince__beginthread(void( *start_address )( void * ), unsigned stack_size, void *arglist); - -unsigned long qt_wince__beginthreadex( void *security, - unsigned stack_size, - unsigned (__stdcall *start_address)(void *), - void *arglist, - unsigned initflag, - unsigned *thrdaddr ); -void qt_wince__endthreadex(unsigned nExitCode); - - -// bsearch is needed for building the tiff plugin -// otherwise it could go into qguifunctions_wce -void *qt_wince_bsearch(const void *key, - const void *base, - size_t num, - size_t size, - int (__cdecl *compare)(const void *, const void *)); - -// Missing typedefs -#ifndef _TIME_T_DEFINED -typedef unsigned long time_t; -#define _TIME_T_DEFINED -#endif -typedef HANDLE HDROP; - -#ifndef WS_THICKFRAME -#define WS_THICKFRAME WS_DLGFRAME -#endif - -typedef UINT UWORD; - -// Missing definitions: not necessary equal to their Win32 values -// (the goal is to just have a clean compilation of MFC) -#define WS_MAXIMIZE 0 -#define WS_MINIMIZE 0 -#ifndef WS_EX_TOOLWINDOW -#define WS_EX_TOOLWINDOW 0 -#endif -#define WS_EX_NOPARENTNOTIFY 0 -#define WM_ENTERIDLE 0x0121 -#define WM_PRINT WM_PAINT -#define WM_NCCREATE (0x0081) -#define WM_PARENTNOTIFY 0 -#define WM_NCDESTROY (WM_APP-1) -#ifndef SW_RESTORE -#define SW_RESTORE (SW_SHOWNORMAL) -#endif -#define SW_NORMAL (SW_SHOWNORMAL) -#define WAIT_OBJECT_0 0x00000000L -#define DEFAULT_GUI_FONT SYSTEM_FONT -#ifndef SWP_NOREDRAW -#define SWP_NOREDRAW 0 -#endif -#define WSAGETSELECTEVENT(lParam) LOWORD(lParam) -#define HWND_TOPMOST ((HWND)-1) -#define HWND_NOTOPMOST ((HWND)-2) -#define PS_DOT 2 -#define PD_ALLPAGES 0 -#define PD_USEDEVMODECOPIES 0 -#define PD_NOSELECTION 0 -#define PD_HIDEPRINTTOFILE 0 -#define PD_NOPAGENUMS 0 -#define CF_METAFILEPICT 3 -#define MM_ANISOTROPIC 8 -#define KF_ALTDOWN 0x2000 -#define SPI_GETWORKAREA 48 - -#ifndef WM_SETCURSOR - #define WM_SETCURSOR 0x0020 - #define IDC_ARROW MAKEINTRESOURCE(32512) - #define IDC_IBEAM MAKEINTRESOURCE(32513) - #define IDC_WAIT MAKEINTRESOURCE(32514) - #define IDC_CROSS MAKEINTRESOURCE(32515) - #define IDC_UPARROW MAKEINTRESOURCE(32516) - #define IDC_SIZE MAKEINTRESOURCE(32646) - #define IDC_ICON MAKEINTRESOURCE(32512) - #define IDC_SIZENWSE MAKEINTRESOURCE(32642) - #define IDC_SIZENESW MAKEINTRESOURCE(32643) - #define IDC_SIZEWE MAKEINTRESOURCE(32644) - #define IDC_SIZENS MAKEINTRESOURCE(32645) - #define IDC_SIZEALL MAKEINTRESOURCE(32646) - #define IDC_NO MAKEINTRESOURCE(32648) - #define IDC_APPSTARTING MAKEINTRESOURCE(32650) - #define IDC_HELP MAKEINTRESOURCE(32651) - #define IDC_HAND MAKEINTRESOURCE(32649) -#endif - -#define GMEM_MOVEABLE LMEM_MOVEABLE -#define GPTR LPTR - -// WinCE: CESYSGEN prunes the following FRP defines, -// and INTERNET_TRANSFER_TYPE_ASCII breaks in wininet.h -#undef FTP_TRANSFER_TYPE_ASCII -#define FTP_TRANSFER_TYPE_ASCII 0x00000001 -#undef FTP_TRANSFER_TYPE_BINARY -#define FTP_TRANSFER_TYPE_BINARY 0x00000002 - -typedef DWORD OLE_COLOR; - -// Define the Windows Styles which are not defined by MS -#ifndef WS_POPUPWINDOW -#define WS_POPUPWINDOW WS_POPUP|WS_BORDER|WS_SYSMENU|WS_CAPTION -#endif - -#ifndef WS_OVERLAPPEDWINDOW -#define WS_OVERLAPPEDWINDOW WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX -#endif - -#ifndef WS_TILED -#define WS_TILED WS_OVERLAPPED -#endif - -#ifndef WS_TILEDWINDOW -#define WS_TILEDWINDOW WS_OVERLAPPEDWINDOW -#endif - -#ifndef WS_EX_CAPTIONOKBTN -#define WS_EX_CAPTIONOKBTN 0x80000000L -#endif - -#ifndef WS_EX_NODRAG -#define WS_EX_NODRAG 0x40000000L -#endif - -#ifdef __cplusplus -} // Extern C. -#endif - -#ifdef __cplusplus - - -// As Windows CE lacks some standard functions used in Qt, these got -// reimplemented. Other projects do this as well. Inline functions are used -// that there is a central place to disable functions for newer versions if -// they get available. There are no defines used anymore, because this -// will break member functions of classes which are called like these -// functions. Also inline functions are only supported by C++, so just define -// them for C++, as only 3rd party dependencies are C, this is no issue. -// The other declarations available in this file are being used per -// define inside qplatformdefs.h of the corresponding WinCE mkspec. - -#define generate_inline_return_func0(funcname, returntype) \ - inline returntype funcname() \ - { \ - return qt_wince_##funcname(); \ - } -#define generate_inline_return_func1(funcname, returntype, param1) \ - inline returntype funcname(param1 p1) \ - { \ - return qt_wince_##funcname(p1); \ - } -#define generate_inline_return_func2(funcname, returntype, prependnamespace, param1, param2) \ - inline returntype funcname(param1 p1, param2 p2) \ - { \ - return prependnamespace##funcname(p1, p2); \ - } -#define generate_inline_return_func3(funcname, returntype, param1, param2, param3) \ - inline returntype funcname(param1 p1, param2 p2, param3 p3) \ - { \ - return qt_wince_##funcname(p1, p2, p3); \ - } -#define generate_inline_return_func4(funcname, returntype, prependnamespace, param1, param2, param3, param4) \ - inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4) \ - { \ - return prependnamespace##funcname(p1, p2, p3, p4); \ - } -#define generate_inline_return_func5(funcname, returntype, param1, param2, param3, param4, param5) \ - inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \ - { \ - return qt_wince_##funcname(p1, p2, p3, p4, p5); \ - } -#define generate_inline_return_func6(funcname, returntype, param1, param2, param3, param4, param5, param6) \ - inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \ - { \ - return qt_wince_##funcname(p1, p2, p3, p4, p5, p6); \ - } -#define generate_inline_return_func7(funcname, returntype, param1, param2, param3, param4, param5, param6, param7) \ - inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \ - { \ - return qt_wince_##funcname(p1, p2, p3, p4, p5, p6, p7); \ - } - -typedef unsigned (__stdcall *StartAdressExFunc)(void *); -typedef void(*StartAdressFunc)(void *); -typedef int ( __cdecl *CompareFunc ) (const void *, const void *) ; - -generate_inline_return_func4(getenv_s, errno_t, qt_fake_, size_t *, char *, size_t, const char *) -generate_inline_return_func2(_putenv_s, errno_t, qt_fake_, const char *, const char *) -generate_inline_return_func0(_getpid, int) -generate_inline_return_func1(time_tToFt, FILETIME, time_t) -generate_inline_return_func1(ftToTime_t, time_t, FILETIME) -generate_inline_return_func0(_getdrive, int) -generate_inline_return_func2(_waccess, int, qt_wince_, const wchar_t *, int) -generate_inline_return_func3(_wopen, int, const wchar_t *, int, int) -generate_inline_return_func2(_fdopen, FILE *, qt_wince_, int, const char *) -generate_inline_return_func2(fdopen, FILE *, qt_wince_, int, const char *) -generate_inline_return_func1(rewind, void, FILE *) -generate_inline_return_func0(tmpfile, FILE *) -generate_inline_return_func2(_rename, int, qt_wince_, const char *, const char *) -generate_inline_return_func1(_remove, int, const char *) -generate_inline_return_func1(SetErrorMode, int, int) -#if _WIN32_WCE < 0x800 -generate_inline_return_func2(_chmod, bool, qt_wince_, const char *, int) -generate_inline_return_func2(_wchmod, bool, qt_wince_, const wchar_t *, int) -#endif -generate_inline_return_func7(CreateFileA, HANDLE, LPCSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE) -generate_inline_return_func4(SetWindowOrgEx, BOOL, qt_wince_, HDC, int, int, LPPOINT) -generate_inline_return_func2(calloc, void *, qt_wince_, size_t, size_t) -generate_inline_return_func0(GetThreadLocale, DWORD) -generate_inline_return_func3(_beginthread, HANDLE, StartAdressFunc, unsigned, void *) -generate_inline_return_func6(_beginthreadex, unsigned long, void *, unsigned, StartAdressExFunc, void *, unsigned, unsigned *) -generate_inline_return_func1(_endthreadex, void, unsigned) -generate_inline_return_func5(bsearch, void *, const void *, const void *, size_t, size_t, CompareFunc) - -#endif //__cplusplus - -#endif // Q_OS_WINCE -#endif // QFUNCTIONS_WINCE_H diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index 79cbe1de72..52abd51dc1 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -52,7 +52,7 @@ #define QJNI_P_H #include <jni.h> -#include <QtCore/qglobal.h> +#include <QtCore/private/qglobal_p.h> #include <QtCore/qsharedpointer.h> QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qjnihelpers_p.h b/src/corelib/kernel/qjnihelpers_p.h index 78ad08a09e..d57228b856 100644 --- a/src/corelib/kernel/qjnihelpers_p.h +++ b/src/corelib/kernel/qjnihelpers_p.h @@ -52,7 +52,7 @@ // #include <jni.h> -#include <QtCore/qglobal.h> +#include <QtCore/private/qglobal_p.h> #include <functional> QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qmath.h b/src/corelib/kernel/qmath.h index c24fc3a0ce..773884047a 100644 --- a/src/corelib/kernel/qmath.h +++ b/src/corelib/kernel/qmath.h @@ -45,6 +45,7 @@ #endif #include <QtCore/qglobal.h> +#include <QtCore/qalgorithms.h> #ifndef _USE_MATH_DEFINES # define _USE_MATH_DEFINES @@ -241,20 +242,12 @@ Q_DECL_CONSTEXPR inline double qRadiansToDegrees(double radians) } -#if defined(Q_CC_GNU) -// clz instructions exist in at least MIPS, ARM, PowerPC and X86, so we can assume this builtin always maps to an efficient instruction. +#if defined(QT_HAS_BUILTIN_CLZ) inline quint32 qNextPowerOfTwo(quint32 v) { if (v == 0) return 1; - return 2U << (31 ^ __builtin_clz(v)); -} - -inline quint64 qNextPowerOfTwo(quint64 v) -{ - if (v == 0) - return 1; - return Q_UINT64_C(2) << (63 ^ __builtin_clzll(v)); + return 2U << (31 ^ QAlgorithmsPrivate::qt_builtin_clz(v)); } #else inline quint32 qNextPowerOfTwo(quint32 v) @@ -267,7 +260,16 @@ inline quint32 qNextPowerOfTwo(quint32 v) ++v; return v; } +#endif +#if defined(QT_HAS_BUILTIN_CLZLL) +inline quint64 qNextPowerOfTwo(quint64 v) +{ + if (v == 0) + return 1; + return Q_UINT64_C(2) << (63 ^ QAlgorithmsPrivate::qt_builtin_clzll(v)); +} +#else inline quint64 qNextPowerOfTwo(quint64 v) { v |= v >> 1; diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index f4f75e39e6..2e0dd8e5d2 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -2557,9 +2557,19 @@ int QMetaEnum::value(int index) const */ bool QMetaEnum::isFlag() const { - return mobj && mobj->d.data[handle + 1]; + return mobj && mobj->d.data[handle + 1] & EnumIsFlag; } +/*! + \since 5.8 + + Returns \c true if this enumerator is declared as a C++11 enum class; + otherwise returns false. +*/ +bool QMetaEnum::isScoped() const +{ + return mobj && mobj->d.data[handle + 1] & EnumIsScoped; +} /*! Returns the scope this enumerator was declared in. @@ -2652,15 +2662,16 @@ int QMetaEnum::keysToValue(const char *keys, bool *ok) const return -1; if (ok != 0) *ok = true; - QStringList l = QString::fromLatin1(keys).split(QLatin1Char('|')); - if (l.isEmpty()) + const QString keysString = QString::fromLatin1(keys); + const QVector<QStringRef> splitKeys = keysString.splitRef(QLatin1Char('|')); + if (splitKeys.isEmpty()) return 0; - //#### TODO write proper code, do not use QStringList + // ### TODO write proper code: do not allocate memory, so we can go nothrow int value = 0; int count = mobj->d.data[handle + 2]; int data = mobj->d.data[handle + 3]; - for (int li = 0; li < l.size(); ++li) { - QString trimmed = l.at(li).trimmed(); + for (const QStringRef &untrimmed : splitKeys) { + const QStringRef trimmed = untrimmed.trimmed(); QByteArray qualified_key = trimmed.toLatin1(); const char *key = qualified_key.constData(); uint scope = 0; diff --git a/src/corelib/kernel/qmetaobject.h b/src/corelib/kernel/qmetaobject.h index 85ac7e77e4..40b2aa6402 100644 --- a/src/corelib/kernel/qmetaobject.h +++ b/src/corelib/kernel/qmetaobject.h @@ -168,19 +168,15 @@ public: inline bool isValid() const { return mobj != Q_NULLPTR; } -#ifdef Q_QDOC - static QMetaMethod fromSignal(PointerToMemberFunction signal); -#else - template <typename Func> - static inline QMetaMethod fromSignal(Func signal) + template <typename PointerToMemberFunction> + static inline QMetaMethod fromSignal(PointerToMemberFunction signal) { - typedef QtPrivate::FunctionPointer<Func> SignalType; + typedef QtPrivate::FunctionPointer<PointerToMemberFunction> SignalType; Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value, "No Q_OBJECT in the class with the signal"); return fromSignalImpl(&SignalType::Object::staticMetaObject, reinterpret_cast<void **>(&signal)); } -#endif private: #if QT_DEPRECATED_SINCE(5,0) @@ -214,6 +210,7 @@ public: const char *name() const; bool isFlag() const; + bool isScoped() const; int keyCount() const; const char *key(int index) const; diff --git a/src/corelib/kernel/qmetaobject_moc_p.h b/src/corelib/kernel/qmetaobject_moc_p.h index 1b24837ec0..ad258acfcd 100644 --- a/src/corelib/kernel/qmetaobject_moc_p.h +++ b/src/corelib/kernel/qmetaobject_moc_p.h @@ -52,6 +52,8 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> + QT_BEGIN_NAMESPACE // This function is shared with moc.cpp. This file should be included where needed. diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h index 0790af2bb5..1c540f64c7 100644 --- a/src/corelib/kernel/qmetaobject_p.h +++ b/src/corelib/kernel/qmetaobject_p.h @@ -114,6 +114,11 @@ enum MetaDataFlags { TypeNameIndexMask = 0x7FFFFFFF }; +enum EnumFlags { + EnumIsFlag = 0x1, + EnumIsScoped = 0x2 +}; + extern int qMetaTypeTypeInternal(const char *); class QArgumentType @@ -168,6 +173,7 @@ class QMutex; struct QMetaObjectPrivate { + // revision 7 is Qt 5.0 everything lower is not supported enum { OutputRevision = 7 }; // Used by moc, qmetaobjectbuilder and qdbus int revision; @@ -176,12 +182,9 @@ struct QMetaObjectPrivate int methodCount, methodData; int propertyCount, propertyData; int enumeratorCount, enumeratorData; - int constructorCount, constructorData; //since revision 2 - int flags; //since revision 3 - int signalCount; //since revision 4 - // revision 5 introduces changes in normalized signatures, no new members - // revision 6 added qt_static_metacall as a member of each Q_OBJECT and inside QMetaObject itself - // revision 7 is Qt 5 + int constructorCount, constructorData; + int flags; + int signalCount; static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject) { return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); } diff --git a/src/corelib/kernel/qmetaobjectbuilder_p.h b/src/corelib/kernel/qmetaobjectbuilder_p.h index 0934873ad0..144595330d 100644 --- a/src/corelib/kernel/qmetaobjectbuilder_p.h +++ b/src/corelib/kernel/qmetaobjectbuilder_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include <QtCore/qobject.h> #include <QtCore/qmetaobject.h> #include <QtCore/qdatastream.h> diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 3ac1f28638..cf0e88c7cd 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -870,8 +870,7 @@ const char *QMetaType::typeName(int typeId) return result; } -/*! - \internal +/* Similar to QMetaType::type(), but only looks in the static set of types. */ static inline int qMetaTypeStaticType(const char *typeName, int length) @@ -884,8 +883,7 @@ static inline int qMetaTypeStaticType(const char *typeName, int length) return types[i].type; } -/*! - \internal +/* Similar to QMetaType::type(), but only looks in the custom set of types, and doesn't lock the mutex. The extra \a firstInvalidIndex parameter is an easy way to avoid diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index b68dbacbd3..a36d247c3c 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -506,11 +506,8 @@ public: static int registerTypedef(const char *typeName, int aliasId); static int registerNormalizedTypedef(const QT_PREPEND_NAMESPACE(QByteArray) &normalizedTypeName, int aliasId); static int type(const char *typeName); -#ifndef Q_QDOC + static int type(const QT_PREPEND_NAMESPACE(QByteArray) &typeName); -#else - static int type(const QByteArray &typeName); -#endif static const char *typeName(int type); static int sizeOf(int type); static TypeFlags typeFlags(int type); @@ -600,8 +597,11 @@ public: } #ifdef Q_QDOC + template<typename MemberFunction, int> static bool registerConverter(MemberFunction function); + template<typename MemberFunctionOk, char> static bool registerConverter(MemberFunctionOk function); + template<typename UnaryFunction> static bool registerConverter(UnaryFunction function); #else // member function as in "QString QFont::toString() const" @@ -1857,6 +1857,7 @@ inline int qRegisterMetaTypeStreamOperators() } QT_END_NAMESPACE \ /**/ +#ifndef Q_MOC_RUN #define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE) #define Q_DECLARE_METATYPE_IMPL(TYPE) \ QT_BEGIN_NAMESPACE \ @@ -1876,7 +1877,7 @@ inline int qRegisterMetaTypeStreamOperators() } \ }; \ QT_END_NAMESPACE - +#endif // Q_MOC_RUN #define Q_DECLARE_BUILTIN_METATYPE(TYPE, METATYPEID, NAME) \ QT_BEGIN_NAMESPACE \ @@ -1899,7 +1900,9 @@ QT_FOR_EACH_STATIC_WIDGETS_CLASS(QT_FORWARD_DECLARE_STATIC_TYPES_ITER) typedef QList<QVariant> QVariantList; typedef QMap<QString, QVariant> QVariantMap; typedef QHash<QString, QVariant> QVariantHash; +#ifndef Q_QDOC typedef QList<QByteArray> QByteArrayList; +#endif #define Q_DECLARE_METATYPE_TEMPLATE_1ARG(SINGLE_ARG_TEMPLATE) \ QT_BEGIN_NAMESPACE \ diff --git a/src/corelib/kernel/qmetatype_p.h b/src/corelib/kernel/qmetatype_p.h index 445e912cf7..dd0bce2645 100644 --- a/src/corelib/kernel/qmetatype_p.h +++ b/src/corelib/kernel/qmetatype_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include "qmetatype.h" QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index c235260f1b..c846aada05 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4776,11 +4776,12 @@ bool QObject::disconnect(const QMetaObject::Connection &connection) c->isSlotObject = false; } + c->sender->disconnectNotify(QMetaObjectPrivate::signal(c->sender->metaObject(), + c->signal_index)); + const_cast<QMetaObject::Connection &>(connection).d_ptr = 0; c->deref(); // has been removed from the QMetaObject::Connection object - // disconnectNotify() not called (the signal index is unknown). - return true; } diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index c06f702b30..3cec9802dc 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -210,8 +210,11 @@ public: const char *member, Qt::ConnectionType type = Qt::AutoConnection) const; #ifdef Q_QDOC + template<typename PointerToMemberFunction> static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection); + template<typename PointerToMemberFunction, typename Functor> static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor); + template<typename PointerToMemberFunction, typename Functor> static QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, const QObject *context, Functor functor, Qt::ConnectionType type = Qt::AutoConnection); #else //Connect a signal to a pointer to qobject member function @@ -337,6 +340,7 @@ public: static bool disconnect(const QMetaObject::Connection &); #ifdef Q_QDOC + template<typename PointerToMemberFunction> static bool disconnect(const QObject *sender, PointerToMemberFunction signal, const QObject *receiver, PointerToMemberFunction method); #else template <typename Func1, typename Func2> diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h index aa68c9c1ad..d7ae63a98c 100644 --- a/src/corelib/kernel/qobject_impl.h +++ b/src/corelib/kernel/qobject_impl.h @@ -97,7 +97,7 @@ namespace QtPrivate { inline void destroyIfLastRef() Q_DECL_NOTHROW { if (!m_ref.deref()) m_impl(Destroy, this, Q_NULLPTR, Q_NULLPTR, Q_NULLPTR); } - inline bool compare(void **a) { bool ret; m_impl(Compare, this, Q_NULLPTR, a, &ret); return ret; } + inline bool compare(void **a) { bool ret = false; m_impl(Compare, this, Q_NULLPTR, a, &ret); return ret; } inline void call(QObject *r, void **a) { m_impl(Call, this, r, a, Q_NULLPTR); } protected: ~QSlotObjectBase() {} @@ -143,10 +143,9 @@ namespace QtPrivate { case Call: FuncType::template call<Args, R>(static_cast<QStaticSlotObject*>(this_)->function, r, a); break; - case Compare: - *ret = false; // not implemented - break; - case NumOperations: ; + case Compare: // not implemented + case NumOperations: + Q_UNUSED(ret); } } public: @@ -168,10 +167,9 @@ namespace QtPrivate { case Call: FuncType::template call<Args, R>(static_cast<QFunctorSlotObject*>(this_)->function, r, a); break; - case Compare: - *ret = false; // not implemented - break; - case NumOperations: ; + case Compare: // not implemented + case NumOperations: + Q_UNUSED(ret); } } public: diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index 4383ece245..a7d7ef0889 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -52,6 +52,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include "QtCore/qobject.h" #include "QtCore/qpointer.h" #include "QtCore/qsharedpointer.h" diff --git a/src/corelib/kernel/qppsattribute_p.h b/src/corelib/kernel/qppsattribute_p.h index 1d9cc4484c..035756e002 100644 --- a/src/corelib/kernel/qppsattribute_p.h +++ b/src/corelib/kernel/qppsattribute_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include <QList> #include <QMap> #include <QSharedDataPointer> diff --git a/src/corelib/kernel/qppsobject.cpp b/src/corelib/kernel/qppsobject.cpp index 30498a380d..dd01d48cc0 100644 --- a/src/corelib/kernel/qppsobject.cpp +++ b/src/corelib/kernel/qppsobject.cpp @@ -397,12 +397,12 @@ QByteArray QPpsObjectPrivate::encode(const QVariantMap &ppsData, bool *ok) void QPpsObjectPrivate::encodeData(pps_encoder_t *encoder, const char *name, const QVariant &data, bool *ok) { - QString errorFunction; + const char *errorFunction; pps_encoder_error_t error = PPS_ENCODER_OK; switch (data.type()) { case QVariant::Bool: error = pps_encoder_add_bool(encoder, name, data.toBool()); - errorFunction = QStringLiteral("pps_encoder_add_bool"); + errorFunction = "pps_encoder_add_bool"; break; // We want to support encoding uint even though libpps doesn't support it directly. // We can't encode uint as an int since that will lose precision (e.g. 2^31+1 can't be @@ -411,41 +411,41 @@ void QPpsObjectPrivate::encodeData(pps_encoder_t *encoder, const char *name, con case QVariant::UInt: case QVariant::Double: error = pps_encoder_add_double(encoder, name, data.toDouble()); - errorFunction = QStringLiteral("pps_encoder_add_double"); + errorFunction = "pps_encoder_add_double"; break; case QVariant::Int: error = pps_encoder_add_int(encoder, name, data.toInt()); - errorFunction = QStringLiteral("pps_encoder_add_int"); + errorFunction = "pps_encoder_add_int"; break; case QVariant::LongLong: error = pps_encoder_add_int64(encoder, name, data.toLongLong()); - errorFunction = QStringLiteral("pps_encoder_add_int64"); + errorFunction = "pps_encoder_add_int64"; break; case QVariant::String: error = pps_encoder_add_string(encoder, name, data.toString().toUtf8().constData()); - errorFunction = QStringLiteral("pps_encoder_add_string"); + errorFunction = "pps_encoder_add_string"; break; case QVariant::List: error = pps_encoder_start_array(encoder, name); - errorFunction = QStringLiteral("pps_encoder_start_array"); + errorFunction = "pps_encoder_start_array"; if (error == PPS_ENCODER_OK) { encodeArray(encoder, data.toList(), ok); error = pps_encoder_end_array(encoder); - errorFunction = QStringLiteral("pps_encoder_end_array"); + errorFunction = "pps_encoder_end_array"; } break; case QVariant::Map: error = pps_encoder_start_object(encoder, name); - errorFunction = QStringLiteral("pps_encoder_start_object"); + errorFunction = "pps_encoder_start_object"; if (error == PPS_ENCODER_OK) { encodeObject(encoder, data.toMap(), ok); error = pps_encoder_end_object(encoder); - errorFunction = QStringLiteral("pps_encoder_end_object"); + errorFunction = "pps_encoder_end_object"; } break; case QVariant::Invalid: error = pps_encoder_add_null(encoder, name); - errorFunction = QStringLiteral("pps_encoder_add_null"); + errorFunction = "pps_encoder_add_null"; break; default: qWarning("QPpsObjectPrivate::encodeData: the type of the parameter data is invalid"); @@ -454,7 +454,7 @@ void QPpsObjectPrivate::encodeData(pps_encoder_t *encoder, const char *name, con } if (error != PPS_ENCODER_OK) { - qWarning() << "QPpsObjectPrivate::encodeData: " << errorFunction << " failed"; + qWarning("QPpsObjectPrivate::encodeData: %s failed", errorFunction); *ok = false; } else { *ok = true; diff --git a/src/corelib/kernel/qsharedmemory_win.cpp b/src/corelib/kernel/qsharedmemory_win.cpp index e998b938c7..07d4930332 100644 --- a/src/corelib/kernel/qsharedmemory_win.cpp +++ b/src/corelib/kernel/qsharedmemory_win.cpp @@ -64,8 +64,8 @@ void QSharedMemoryPrivate::setErrorString(QLatin1String function) errorString = QSharedMemory::tr("%1: already exists").arg(function); break; case ERROR_FILE_NOT_FOUND: -#if defined(Q_OS_WINCE) || (defined(Q_OS_WINRT) && _MSC_VER < 1900) - // This happens on CE only if no file is present as CreateFileMappingW +#if defined(Q_OS_WINRT) && _MSC_VER < 1900 + // This happens on WinRT only if no file is present as CreateFileMappingW // bails out with this error code case ERROR_INVALID_PARAMETER: #endif @@ -112,10 +112,6 @@ HANDLE QSharedMemoryPrivate::handle() #else hand = CreateFileMappingFromApp(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, (PCWSTR)nativeKey.utf16()); #endif -#elif defined(Q_OS_WINCE) - // This works for opening a mapping too, but always opens it with read/write access in - // attach as it seems. - hand = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, 0, (wchar_t*)nativeKey.utf16()); #else hand = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, (wchar_t*)nativeKey.utf16()); #endif diff --git a/src/corelib/kernel/qsystemerror.cpp b/src/corelib/kernel/qsystemerror.cpp index 12fd5404da..f38daec4f8 100644 --- a/src/corelib/kernel/qsystemerror.cpp +++ b/src/corelib/kernel/qsystemerror.cpp @@ -39,15 +39,9 @@ #include <qglobal.h> #include "qsystemerror_p.h" -#if !defined(Q_OS_WINCE) -# include <errno.h> -# if defined(Q_CC_MSVC) -# include <crtdbg.h> -# endif -#else -# if (_WIN32_WCE >= 0x700) -# include <errno.h> -# endif +#include <errno.h> +#if defined(Q_CC_MSVC) +# include <crtdbg.h> #endif #ifdef Q_OS_WIN # include <qt_windows.h> @@ -131,16 +125,12 @@ static QString standardLibraryErrorString(int errorCode) s = QT_TRANSLATE_NOOP("QIODevice", "No space left on device"); break; default: { - #ifdef Q_OS_WINCE - ret = windowsErrorString(errorCode); - #else - #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) + #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && _POSIX_VERSION >= 200112L && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_QNX) QByteArray buf(1024, '\0'); ret = fromstrerror_helper(strerror_r(errorCode, buf.data(), buf.size()), buf); - #else + #else ret = QString::fromLocal8Bit(strerror(errorCode)); - #endif - #endif + #endif break; } } if (s) { diff --git a/src/corelib/kernel/qsystemerror_p.h b/src/corelib/kernel/qsystemerror_p.h index c3d8118711..440b763149 100644 --- a/src/corelib/kernel/qsystemerror_p.h +++ b/src/corelib/kernel/qsystemerror_p.h @@ -51,6 +51,7 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> #include <qstring.h> QT_BEGIN_NAMESPACE diff --git a/src/corelib/kernel/qsystemsemaphore_p.h b/src/corelib/kernel/qsystemsemaphore_p.h index 26647db2e1..3b55d80276 100644 --- a/src/corelib/kernel/qsystemsemaphore_p.h +++ b/src/corelib/kernel/qsystemsemaphore_p.h @@ -56,9 +56,7 @@ #ifndef QT_NO_SYSTEMSEMAPHORE #include "qsharedmemory_p.h" -#ifndef Q_OS_WINCE -# include <sys/types.h> -#endif +#include <sys/types.h> #ifdef QT_POSIX_IPC # include <semaphore.h> #endif diff --git a/src/corelib/kernel/qsystemsemaphore_posix.cpp b/src/corelib/kernel/qsystemsemaphore_posix.cpp index 6137239467..9fbf5779b8 100644 --- a/src/corelib/kernel/qsystemsemaphore_posix.cpp +++ b/src/corelib/kernel/qsystemsemaphore_posix.cpp @@ -147,7 +147,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count) if (::sem_post(semaphore) == -1) { setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore (sem_post)")); #if defined QSYSTEMSEMAPHORE_DEBUG - qDebug() << QLatin1String("QSystemSemaphore::modify sem_post failed") << count << errno; + qDebug("QSystemSemaphore::modify sem_post failed %d %d", count, errno); #endif // rollback changes to preserve the SysV semaphore behavior for ( ; cnt < count; ++cnt) { @@ -169,7 +169,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count) } setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore (sem_wait)")); #if defined QSYSTEMSEMAPHORE_DEBUG - qDebug() << QLatin1String("QSystemSemaphore::modify sem_wait failed") << count << errno; + qDebug("QSystemSemaphore::modify sem_wait failed %d %d", count, errno); #endif return false; } diff --git a/src/corelib/kernel/qsystemsemaphore_systemv.cpp b/src/corelib/kernel/qsystemsemaphore_systemv.cpp index f4fdfa5f58..1967899a58 100644 --- a/src/corelib/kernel/qsystemsemaphore_systemv.cpp +++ b/src/corelib/kernel/qsystemsemaphore_systemv.cpp @@ -187,7 +187,8 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count) } setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore")); #if defined QSYSTEMSEMAPHORE_DEBUG - qDebug() << QLatin1String("QSystemSemaphore::modify failed") << count << semctl(semaphore, 0, GETVAL) << errno << EIDRM << EINVAL; + qDebug("QSystemSemaphore::modify failed %d %d %d %d %d", + count, int(semctl(semaphore, 0, GETVAL)), int(errno), int(EIDRM), int(EINVAL); #endif return false; } diff --git a/src/corelib/kernel/qsystemsemaphore_win.cpp b/src/corelib/kernel/qsystemsemaphore_win.cpp index 236e346afe..3395f5641e 100644 --- a/src/corelib/kernel/qsystemsemaphore_win.cpp +++ b/src/corelib/kernel/qsystemsemaphore_win.cpp @@ -121,11 +121,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count) return false; } } else { -#if !defined(Q_OS_WINCE) if (WAIT_OBJECT_0 != WaitForSingleObjectEx(semaphore, INFINITE, FALSE)) { -#else - if (WAIT_OBJECT_0 != WaitForSingleObject(semaphore, INFINITE)) { -#endif setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore")); #if defined QSYSTEMSEMAPHORE_DEBUG qDebug("QSystemSemaphore::modifySemaphore WaitForSingleObject failed"); diff --git a/src/corelib/kernel/qtimer.cpp b/src/corelib/kernel/qtimer.cpp index 80accc0cb8..8ba494ec3d 100644 --- a/src/corelib/kernel/qtimer.cpp +++ b/src/corelib/kernel/qtimer.cpp @@ -533,6 +533,78 @@ void QTimer::singleShot(int msec, Qt::TimerType timerType, const QObject *receiv */ /*! + \fn void QTimer::singleShot(std::chrono::duration<Rep, Period> value, const QObject *receiver, const char *member) + \since 5.8 + \overload + \reentrant + + This static function calls a slot after a given time interval. + + It is very convenient to use this function because you do not need + to bother with a \l{QObject::timerEvent()}{timerEvent} or + create a local QTimer object. + + The \a receiver is the receiving object and the \a member is the slot. The + time interval is given in the duration object \a value. + + \sa start() +*/ + +/*! + \fn void QTimer::singleShot(std::chrono::duration<Rep, Period> value, Qt::TimerType timerType, const QObject *receiver, const char *member) + \since 5.8 + \overload + \reentrant + + This static function calls a slot after a given time interval. + + It is very convenient to use this function because you do not need + to bother with a \l{QObject::timerEvent()}{timerEvent} or + create a local QTimer object. + + The \a receiver is the receiving object and the \a member is the slot. The + time interval is given in the duration object \a value. The \a timerType affects the + accuracy of the timer. + + \sa start() +*/ + +/*! + \fn void QTimer::start(std::chrono::duration<Rep, Period> value) + \since 5.8 + \overload + + Starts or restarts the timer with a timeout of duration \a value. + + If the timer is already running, it will be + \l{QTimer::stop()}{stopped} and restarted. + + If \l singleShot is true, the timer will be activated only once. +*/ + +/*! + \fn std::chrono::milliseconds QTimer::intervalAsDuration() const + \since 5.8 + + Returns the interval of this timer as a \c std::chrono::milliseconds object. + + \sa interval +*/ + +/*! + \fn std::chrono::milliseconds QTimer::remainingTimeAsDuration() const + \since 5.8 + + Returns the time remaining in this timer object as a \c + std::chrono::milliseconds object. If this timer is due or overdue, the + returned value is \c std::chrono::milliseconds::zero(). If the remaining + time could not be found or the timer is not active, this function returns a + negative duration. + + \sa remainingTime() +*/ + +/*! \property QTimer::singleShot \brief whether the timer is a single-shot timer diff --git a/src/corelib/kernel/qtimer.h b/src/corelib/kernel/qtimer.h index dd52d52a1c..1567fe760c 100644 --- a/src/corelib/kernel/qtimer.h +++ b/src/corelib/kernel/qtimer.h @@ -47,6 +47,10 @@ #include <QtCore/qbasictimer.h> // conceptual inheritance #include <QtCore/qobject.h> +#if QT_HAS_INCLUDE(<chrono>) +# include <chrono> +#endif + QT_BEGIN_NAMESPACE @@ -80,21 +84,27 @@ public: static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, const char *member); #ifdef Q_QDOC + template<typename PointerToMemberFunction> static void singleShot(int msec, const QObject *receiver, PointerToMemberFunction method); + template<typename PointerToMemberFunction> static void singleShot(int msec, Qt::TimerType timerType, const QObject *receiver, PointerToMemberFunction method); + template<typename Functor> static void singleShot(int msec, Functor functor); + template<typename Functor> static void singleShot(int msec, Qt::TimerType timerType, Functor functor); + template<typename Functor, int> static void singleShot(int msec, const QObject *context, Functor functor); + template<typename Functor, int> static void singleShot(int msec, Qt::TimerType timerType, const QObject *context, Functor functor); #else // singleShot to a QObject slot - template <typename Func1> - static inline void singleShot(int msec, const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot) + template <typename Duration, typename Func1> + static inline void singleShot(Duration interval, const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot) { - singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, receiver, slot); + singleShot(interval, defaultTypeFor(interval), receiver, slot); } - template <typename Func1> - static inline void singleShot(int msec, Qt::TimerType timerType, const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, + template <typename Duration, typename Func1> + static inline void singleShot(Duration interval, Qt::TimerType timerType, const typename QtPrivate::FunctionPointer<Func1>::Object *receiver, Func1 slot) { typedef QtPrivate::FunctionPointer<Func1> SlotType; @@ -103,42 +113,42 @@ public: Q_STATIC_ASSERT_X(int(SlotType::ArgumentCount) == 0, "The slot must not have any arguments."); - singleShotImpl(msec, timerType, receiver, + singleShotImpl(interval, timerType, receiver, new QtPrivate::QSlotObject<Func1, typename SlotType::Arguments, void>(slot)); } // singleShot to a functor or function pointer (without context) - template <typename Func1> + template <typename Duration, typename Func1> static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && !QtPrivate::is_same<const char*, Func1>::value, void>::Type - singleShot(int msec, Func1 slot) + singleShot(Duration interval, Func1 slot) { - singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, Q_NULLPTR, slot); + singleShot(interval, defaultTypeFor(interval), nullptr, slot); } - template <typename Func1> + template <typename Duration, typename Func1> static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && !QtPrivate::is_same<const char*, Func1>::value, void>::Type - singleShot(int msec, Qt::TimerType timerType, Func1 slot) + singleShot(Duration interval, Qt::TimerType timerType, Func1 slot) { - singleShot(msec, timerType, Q_NULLPTR, slot); + singleShot(interval, timerType, nullptr, slot); } // singleShot to a functor or function pointer (with context) - template <typename Func1> + template <typename Duration, typename Func1> static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && !QtPrivate::is_same<const char*, Func1>::value, void>::Type - singleShot(int msec, QObject *context, Func1 slot) + singleShot(Duration interval, QObject *context, Func1 slot) { - singleShot(msec, msec >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer, context, slot); + singleShot(interval, defaultTypeFor(interval), context, slot); } - template <typename Func1> + template <typename Duration, typename Func1> static inline typename QtPrivate::QEnableIf<!QtPrivate::FunctionPointer<Func1>::IsPointerToMemberFunction && !QtPrivate::is_same<const char*, Func1>::value, void>::Type - singleShot(int msec, Qt::TimerType timerType, QObject *context, Func1 slot) + singleShot(Duration interval, Qt::TimerType timerType, QObject *context, Func1 slot) { //compilation error if the slot has arguments. typedef QtPrivate::FunctionPointer<Func1> SlotType; Q_STATIC_ASSERT_X(int(SlotType::ArgumentCount) <= 0, "The slot must not have any arguments."); - singleShotImpl(msec, timerType, context, + singleShotImpl(interval, timerType, context, new QtPrivate::QFunctorSlotObject<Func1, 0, typename QtPrivate::List_Left<void, 0>::Value, void>(slot)); } @@ -153,6 +163,43 @@ public Q_SLOTS: Q_SIGNALS: void timeout(QPrivateSignal); +public: +#if QT_HAS_INCLUDE(<chrono>) || defined(Q_QDOC) + template <class Rep, class Period> + void setInterval(std::chrono::duration<Rep, Period> value) + { + setInterval(std::chrono::duration_cast<std::chrono::milliseconds>(value).count()); + } + + std::chrono::milliseconds intervalAsDuration() const + { + return std::chrono::milliseconds(interval()); + } + + std::chrono::milliseconds remainingTimeAsDuration() const + { + return std::chrono::milliseconds(remainingTime()); + } + + template <class Rep, class Period> + static void singleShot(std::chrono::duration<Rep, Period> value, const QObject *receiver, const char *member) + { + singleShot(int(std::chrono::duration_cast<std::chrono::milliseconds>(value).count()), receiver, member); + } + + template <class Rep, class Period> + static void singleShot(std::chrono::duration<Rep, Period> value, Qt::TimerType timerType, const QObject *receiver, const char *member) + { + singleShot(int(std::chrono::duration_cast<std::chrono::milliseconds>(value).count()), timerType, receiver, member); + } + + template <class Rep, class Period> + void start(std::chrono::duration<Rep, Period> value) + { + start(int(std::chrono::duration_cast<std::chrono::milliseconds>(value).count())); + } +#endif + protected: void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE; @@ -162,9 +209,25 @@ private: inline int startTimer(int){ return -1;} inline void killTimer(int){} + static Q_DECL_CONSTEXPR Qt::TimerType defaultTypeFor(int msecs) Q_DECL_NOTHROW + { return msecs >= 2000 ? Qt::CoarseTimer : Qt::PreciseTimer; } static void singleShotImpl(int msec, Qt::TimerType timerType, const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj); +#if QT_HAS_INCLUDE(<chrono>) + template <class Rep, class Period> + static Qt::TimerType defaultTypeFor(std::chrono::duration<Rep, Period> interval) + { return defaultTypeFor(int(std::chrono::duration_cast<std::chrono::milliseconds>(interval).count())); } + + template <class Rep, class Period> + static void singleShotImpl(std::chrono::duration<Rep, Period> interval, Qt::TimerType timerType, + const QObject *receiver, QtPrivate::QSlotObjectBase *slotObj) + { + singleShotImpl(int(std::chrono::duration_cast<std::chrono::milliseconds>(interval).count()), + timerType, receiver, slotObj); + } +#endif + int id, inter, del; uint single : 1; uint nulltimer : 1; diff --git a/src/corelib/kernel/qtimerinfo_unix_p.h b/src/corelib/kernel/qtimerinfo_unix_p.h index 2de8a4681f..7bd6f16ea1 100644 --- a/src/corelib/kernel/qtimerinfo_unix_p.h +++ b/src/corelib/kernel/qtimerinfo_unix_p.h @@ -51,6 +51,8 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> + // #define QTIMERINFO_DEBUG #include "qabstracteventdispatcher.h" diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index 2c813b5156..e016773bde 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -487,7 +487,7 @@ bool QTranslator::load(const QString & filename, const QString & directory, } const QString suffixOrDotQM = suffix.isNull() ? dotQmLiteral() : suffix; - QString fname = filename; + QStringRef fname(&filename); QString realname; QString delims; delims = search_delimiters.isNull() ? QStringLiteral("_.") : search_delimiters; diff --git a/src/corelib/kernel/qtranslator_p.h b/src/corelib/kernel/qtranslator_p.h index 21de8e2a8c..e148637ac6 100644 --- a/src/corelib/kernel/qtranslator_p.h +++ b/src/corelib/kernel/qtranslator_p.h @@ -51,6 +51,8 @@ // We mean it. // +#include <QtCore/private/qglobal_p.h> + enum { Q_EQ = 0x01, Q_LT = 0x02, |