summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2011-06-24 13:31:04 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2011-06-24 13:31:04 (GMT)
commit1281617cd15b51f08db392a04387f583197c4cd9 (patch)
tree3f89e82669b12ea49e0586d3ff14c0d01594301e /src
parent181f86f118f5a53abf43bce37758b331b0aabe9a (diff)
parentf6310e6148180d651e95bff482ded47272e38718 (diff)
downloadQt-1281617cd15b51f08db392a04387f583197c4cd9.zip
Qt-1281617cd15b51f08db392a04387f583197c4cd9.tar.gz
Qt-1281617cd15b51f08db392a04387f583197c4cd9.tar.bz2
Merge branch 'master' of git://scm.dev.nokia.troll.no/qt/qt-doc-team
* 'master' of git://scm.dev.nokia.troll.no/qt/qt-doc-team: (63 commits) my changelog for 4.8.0 Add a function that returns the D-Bus local machine ID Add an SSE4.2 even simpler version of toLatin1 Skip boundry neutral characters in bidi itemization symbian socket engine: resolve some fixme and todo items trivial: fix typo in comment Fix QDeclarativeInspector when starting with ,block changelog docu update for QNX 6.5 get rid of anacronysm massive improvements for the QNX screen driver massive improvements for the QNX mouse driver massive improvements for the QNX keyboard driver disable the Embedded Linux data directory permissions check for QNX skip two subtests that are known to fail on QNX implement POSIX IPC based QLock, QWSLock and QWSSharedMemory backends implement POSIX IPC based QSystemSemaphore and QSharedMemory backends add a configure-time check for an IPC support make QProcess really work on QNX make the kernel attempt to emulate an instruction with a misaligned access ...
Diffstat (limited to 'src')
-rw-r--r--src/corelib/global/qglobal.cpp55
-rw-r--r--src/corelib/global/qglobal.h12
-rw-r--r--src/corelib/io/qbuffer.cpp17
-rw-r--r--src/corelib/io/qfilesystemengine_unix.cpp11
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.cpp24
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents_p.h4
-rw-r--r--src/corelib/io/qprocess.cpp10
-rw-r--r--src/corelib/io/qprocess_p.h8
-rw-r--r--src/corelib/io/qprocess_unix.cpp183
-rw-r--r--src/corelib/kernel/qcore_mac.cpp77
-rw-r--r--src/corelib/kernel/qcore_mac_p.h7
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp22
-rw-r--r--src/corelib/kernel/qsharedmemory.cpp5
-rw-r--r--src/corelib/kernel/qsharedmemory_p.h4
-rw-r--r--src/corelib/kernel/qsharedmemory_unix.cpp143
-rw-r--r--src/corelib/kernel/qsystemsemaphore.cpp7
-rw-r--r--src/corelib/kernel/qsystemsemaphore_p.h9
-rw-r--r--src/corelib/kernel/qsystemsemaphore_unix.cpp124
-rw-r--r--src/corelib/thread/qthread_unix.cpp5
-rw-r--r--src/corelib/tools/qstring.cpp23
-rw-r--r--src/corelib/tools/qstring.h1
-rw-r--r--src/dbus/qdbus_symbols_p.h2
-rw-r--r--src/dbus/qdbusconnection.cpp21
-rw-r--r--src/dbus/qdbusconnection.h2
-rw-r--r--src/declarative/debugger/qdeclarativeinspectorservice.cpp14
-rw-r--r--src/declarative/debugger/qdeclarativeinspectorservice_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp4
-rw-r--r--src/declarative/qml/qdeclarativebinding.cpp5
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm3
-rw-r--r--src/gui/egl/qegl_p.h10
-rw-r--r--src/gui/embedded/embedded.pri2
-rw-r--r--src/gui/embedded/qkbdqnx_qws.cpp257
-rw-r--r--src/gui/embedded/qlock.cpp128
-rw-r--r--src/gui/embedded/qmouselinuxinput_qws.cpp18
-rw-r--r--src/gui/embedded/qmouseqnx_qws.cpp96
-rw-r--r--src/gui/embedded/qmouseqnx_qws.h2
-rw-r--r--src/gui/embedded/qscreen_qws.h3
-rw-r--r--src/gui/embedded/qscreenqnx_qws.cpp409
-rw-r--r--src/gui/embedded/qscreenqnx_qws.h1
-rw-r--r--src/gui/embedded/qwslock.cpp67
-rw-r--r--src/gui/embedded/qwslock_p.h8
-rw-r--r--src/gui/embedded/qwssharedmemory.cpp89
-rw-r--r--src/gui/embedded/qwssharedmemory_p.h5
-rw-r--r--src/gui/graphicsview/qgraphicslayout.cpp14
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp19
-rw-r--r--src/gui/graphicsview/qgraphicswidget.h2
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.cpp14
-rw-r--r--src/gui/graphicsview/qgraphicswidget_p.h5
-rw-r--r--src/gui/image/qpixmapdata_p.h5
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp1
-rw-r--r--src/gui/kernel/qapplication_mac.mm1
-rw-r--r--src/gui/kernel/qapplication_qws.cpp7
-rw-r--r--src/gui/kernel/qapplication_s60.cpp5
-rw-r--r--src/gui/kernel/qmime_mac.cpp4
-rw-r--r--src/gui/kernel/qt_mac.cpp1
-rw-r--r--src/gui/kernel/qwidget_mac.mm12
-rw-r--r--src/gui/kernel/qwidget_qpa.cpp10
-rw-r--r--src/gui/painting/qpaintengineex.cpp2
-rw-r--r--src/gui/painting/qwindowsurface_qws.cpp8
-rw-r--r--src/gui/styles/qcommonstyle.cpp2
-rw-r--r--src/gui/text/qfontdatabase_mac.cpp2
-rw-r--r--src/gui/text/qfontdatabase_qws.cpp5
-rw-r--r--src/gui/text/qfontdatabase_x11.cpp55
-rw-r--r--src/gui/text/qfontengine_x11.cpp28
-rw-r--r--src/gui/text/qtextdocument.cpp4
-rw-r--r--src/gui/text/qtextdocumentfragment.cpp9
-rw-r--r--src/gui/text/qtextdocumentfragment_p.h2
-rw-r--r--src/gui/text/qtextengine.cpp26
-rw-r--r--src/network/access/qnetworkcookiejar.cpp27
-rw-r--r--src/network/kernel/kernel.pri2
-rw-r--r--src/network/kernel/qauthenticator.cpp2
-rw-r--r--src/network/socket/qsymbiansocketengine.cpp33
-rw-r--r--src/network/socket/qsymbiansocketengine_p.h5
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp10
-rw-r--r--src/network/ssl/qsslsocket_p.h4
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp61
-rw-r--r--src/opengl/gl2paintengineex/qtriangulator.cpp7
-rw-r--r--src/opengl/opengl.pro4
-rw-r--r--src/opengl/qgl.cpp55
-rw-r--r--src/opengl/qgl.h1
-rw-r--r--src/opengl/qgl_mac.mm1
-rw-r--r--src/opengl/qgl_p.h33
-rw-r--r--src/opengl/qgltexturepool.cpp136
-rw-r--r--src/opengl/qgltexturepool_p.h37
-rw-r--r--src/opengl/qgraphicssystem_gl.cpp3
-rw-r--r--src/opengl/qpixmapdata_gl_p.h28
-rw-r--r--src/opengl/qpixmapdata_symbiangl.cpp (renamed from src/opengl/qpixmapdata_poolgl.cpp)124
-rw-r--r--src/opengl/qwindowsurface_gl.cpp61
-rw-r--r--src/openvg/qpixmapdata_vg_p.h1
-rw-r--r--src/qt3support/dialogs/q3filedialog_mac.cpp2
-rw-r--r--src/qt3support/other/q3process_unix.cpp18
91 files changed, 1905 insertions, 892 deletions
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index e5626b4..84d68e5 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1648,64 +1648,13 @@ static const unsigned int qt_one = 1;
const int QSysInfo::ByteOrder = ((*((unsigned char *) &qt_one) == 0) ? BigEndian : LittleEndian);
#endif
-#if !defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC)
+#if !defined(QWS) && defined(Q_OS_MAC)
QT_BEGIN_INCLUDE_NAMESPACE
#include "private/qcore_mac_p.h"
#include "qnamespace.h"
QT_END_INCLUDE_NAMESPACE
-Q_CORE_EXPORT OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref)
-{
- return FSPathMakeRef(reinterpret_cast<const UInt8 *>(file.toUtf8().constData()), fsref, 0);
-}
-
-// Don't use this function, it won't work in 10.5 (Leopard) and up
-Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &file, FSSpec *spec)
-{
- FSRef fsref;
- OSErr ret = qt_mac_create_fsref(file, &fsref);
- if (ret == noErr)
- ret = FSGetCatalogInfo(&fsref, kFSCatInfoNone, 0, 0, spec, 0);
- return ret;
-}
-
-Q_CORE_EXPORT void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1)
-{
- if(len == -1)
- len = s.length();
-#if 0
- UnicodeMapping mapping;
- mapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
- kTextEncodingDefaultVariant,
- kUnicode16BitFormat);
- mapping.otherEncoding = (encoding ? encoding : );
- mapping.mappingVersion = kUnicodeUseLatestMapping;
-
- UnicodeToTextInfo info;
- OSStatus err = CreateUnicodeToTextInfo(&mapping, &info);
- if(err != noErr) {
- qDebug("Qt: internal: Unable to create pascal string '%s'::%d [%ld]",
- s.left(len).latin1(), (int)encoding, err);
- return;
- }
- const int unilen = len * 2;
- const UniChar *unibuf = (UniChar *)s.unicode();
- ConvertFromUnicodeToPString(info, unilen, unibuf, str);
- DisposeUnicodeToTextInfo(&info);
-#else
- Q_UNUSED(encoding);
- CFStringGetPascalString(QCFString(s), str, 256, CFStringGetSystemEncoding());
-#endif
-}
-
-Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr) {
- return QCFString(CFStringCreateWithPascalString(0, pstr, CFStringGetSystemEncoding()));
-}
-#endif //!defined(QWS) && !defined(Q_WS_QPA) && defined(Q_OS_MAC)
-
-#if !defined(QWS) && defined(Q_OS_MAC)
-
static QSysInfo::MacVersion macVersion()
{
#ifndef QT_NO_CORESERVICES
@@ -2105,7 +2054,7 @@ static void mac_default_handler(const char *msg)
{
if (qt_is_gui_used) {
Str255 pmsg;
- qt_mac_to_pascal_string(msg, pmsg);
+ qt_mac_to_pascal_string(QString::fromAscii(msg), pmsg);
DebugStr(pmsg);
} else {
fprintf(stderr, msg);
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 32b3e6b..1f5f537 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -173,7 +173,6 @@ namespace QT_NAMESPACE {}
RELIANT - Reliant UNIX
DYNIX - DYNIX/ptx
QNX - QNX
- QNX6 - QNX RTP 6.1
LYNX - LynxOS
BSD4 - Any BSD 4.4 system
UNIX - Any UNIX BSD/SYSV system
@@ -2746,17 +2745,6 @@ QT_LICENSED_MODULE(DBus)
# define QT_NO_CONCURRENT_FILTER
#endif
-#ifdef Q_OS_QNX
-// QNX doesn't have SYSV style shared memory. Multiprocess QWS apps,
-// shared fonts and QSystemSemaphore + QSharedMemory are not available
-# define QT_NO_QWS_MULTIPROCESS
-# define QT_NO_QWS_SHARE_FONTS
-# define QT_NO_SYSTEMSEMAPHORE
-# define QT_NO_SHAREDMEMORY
-// QNX currently doesn't support forking in a thread, so disable QProcess
-# define QT_NO_PROCESS
-#endif
-
#if defined (__ELF__)
# if defined (Q_OS_LINUX) || defined (Q_OS_SOLARIS) || defined (Q_OS_FREEBSD) || defined (Q_OS_OPENBSD) || defined (Q_OS_IRIX)
# define Q_OF_ELF
diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp
index 38e406b..35e7b68 100644
--- a/src/corelib/io/qbuffer.cpp
+++ b/src/corelib/io/qbuffer.cpp
@@ -333,23 +333,18 @@ bool QBuffer::open(OpenMode flags)
{
Q_D(QBuffer);
- if ((flags & Append) == Append)
+ if ((flags & (Append | Truncate)) != 0)
flags |= WriteOnly;
- setOpenMode(flags);
- if (!(isReadable() || isWritable())) {
- qWarning("QFile::open: File access not specified");
+ if ((flags & (ReadOnly | WriteOnly)) == 0) {
+ qWarning("QBuffer::open: Buffer access not specified");
return false;
}
- if ((flags & QIODevice::Truncate) == QIODevice::Truncate) {
+ if ((flags & Truncate) == Truncate)
d->buf->resize(0);
- }
- if ((flags & QIODevice::Append) == QIODevice::Append) // append to end of buffer
- seek(d->buf->size());
- else
- seek(0);
+ d->ioIndex = (flags & Append) == Append ? d->buf->size() : 0;
- return true;
+ return QIODevice::open(flags);
}
/*!
diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp
index f1e0758..b0ebfbd 100644
--- a/src/corelib/io/qfilesystemengine_unix.cpp
+++ b/src/corelib/io/qfilesystemengine_unix.cpp
@@ -180,7 +180,8 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
return QFileSystemEntry(slowCanonicalized(absoluteName(entry).filePath()));
#else
char *ret = 0;
-# if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES)
+# if defined(Q_OS_MAC)
+# if !defined(QT_NO_CORESERVICES)
// Mac OS X 10.5.x doesn't support the realpath(X,0) extension we use here.
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
ret = realpath(entry.nativeFilePath().constData(), (char*)0);
@@ -197,9 +198,13 @@ QFileSystemEntry QFileSystemEngine::canonicalName(const QFileSystemEntry &entry,
return QFileSystemEntry(ret);
}
}
-# else
+# else
+ ret = (char*)malloc(PATH_MAX);
+ realpath(entry.nativeFilePath().constData(), (char*)ret);
+# endif //!defined(QT_NO_CORESERVICES)
+# else
ret = realpath(entry.nativeFilePath().constData(), (char*)0);
-# endif
+# endif //defined(Q_OS_MAC)
if (ret) {
data.knownFlagsMask |= QFileSystemMetaData::ExistsAttribute;
data.entryFlags |= QFileSystemMetaData::ExistsAttribute;
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.cpp b/src/corelib/io/qfilesystemwatcher_fsevents.cpp
index 6ae6e38..4ae7cf8 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.cpp
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.cpp
@@ -57,13 +57,15 @@
#include <sys/types.h>
#include <CoreFoundation/CFRunLoop.h>
#include <CoreFoundation/CFUUID.h>
+#if !defined( QT_NO_CORESERVICES )
#include <CoreServices/CoreServices.h>
+#endif
#include <AvailabilityMacros.h>
#include <private/qcore_mac_p.h>
QT_BEGIN_NAMESPACE
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// Static operator overloading so for the sake of some convieniece.
// They only live in this compilation unit to avoid polluting Qt in general.
static bool operator==(const struct ::timespec &left, const struct ::timespec &right)
@@ -152,7 +154,7 @@ QFSEventsFileSystemWatcherEngine::QFSEventsFileSystemWatcherEngine()
QFSEventsFileSystemWatcherEngine::~QFSEventsFileSystemWatcherEngine()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// I assume that at this point, QFileSystemWatcher has already called stop
// on me, so I don't need to invalidate or stop my stream, simply
// release it.
@@ -171,7 +173,7 @@ QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
stop();
wait();
QMutexLocker locker(&mutex);
@@ -257,7 +259,7 @@ QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
void QFSEventsFileSystemWatcherEngine::warmUpFSEvents()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// This function assumes that the mutex has already been grabbed before calling it.
// It exits with the mutex still locked (Q_ASSERT(mutex.isLocked()) ;-).
start();
@@ -269,7 +271,7 @@ QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &pat
QStringList *files,
QStringList *directories)
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
stop();
wait();
QMutexLocker locker(&mutex);
@@ -336,7 +338,7 @@ QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &pat
#endif
}
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
void QFSEventsFileSystemWatcherEngine::updateList(PathInfoList &list, bool directory, bool emitSignals)
{
PathInfoList::iterator End = list.end();
@@ -396,7 +398,7 @@ void QFSEventsFileSystemWatcherEngine::fseventsCallback(ConstFSEventStreamRef ,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId [])
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
QFSEventsFileSystemWatcherEngine *watcher = static_cast<QFSEventsFileSystemWatcherEngine *>(clientCallBackInfo);
QMutexLocker locker(&watcher->mutex);
CFArrayRef paths = static_cast<CFArrayRef>(eventPaths);
@@ -431,7 +433,7 @@ void QFSEventsFileSystemWatcherEngine::fseventsCallback(ConstFSEventStreamRef ,
void QFSEventsFileSystemWatcherEngine::stop()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
QMutexLocker locker(&mutex);
stopFSStream(fsStream);
if (threadsRunLoop) {
@@ -443,13 +445,13 @@ void QFSEventsFileSystemWatcherEngine::stop()
void QFSEventsFileSystemWatcherEngine::updateFiles()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
QMutexLocker locker(&mutex);
updateHash(filePathInfoHash);
updateHash(dirPathInfoHash);
if (filePathInfoHash.isEmpty() && dirPathInfoHash.isEmpty()) {
// Everything disappeared before we got to start, don't bother.
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
// Code duplicated from stop(), with the exception that we
// don't wait on waitForStop here. Doing this will lead to
// a deadlock since this function is called from the worker
@@ -467,7 +469,7 @@ void QFSEventsFileSystemWatcherEngine::updateFiles()
void QFSEventsFileSystemWatcherEngine::run()
{
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
threadsRunLoop = CFRunLoopGetCurrent();
FSEventStreamScheduleWithRunLoop(fsStream, threadsRunLoop, kCFRunLoopDefaultMode);
bool startedOK = FSEventStreamStart(fsStream);
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
index 2466a6e..515c32e 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents_p.h
+++ b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
@@ -74,7 +74,7 @@ typedef uint64_t FSEventStreamEventId;
QT_BEGIN_NAMESPACE
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined(QT_NO_CORESERVICES)
// Yes, I use a stat64 element here. QFileInfo requires too much knowledge about implementation
// details to be used as a long-standing record. Since I'm going to have to store this information, I can
// do the stat myself too.
@@ -117,7 +117,7 @@ private:
QMutex mutex;
QWaitCondition waitCondition;
QWaitCondition waitForStop;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 && !defined( QT_NO_CORESERVICES )
PathHash filePathInfoHash;
PathHash dirPathInfoHash;
void updateHash(PathHash &pathHash);
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 70a70c2..4b689c5 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -751,12 +751,16 @@ QProcessPrivate::QProcessPrivate()
sequenceNumber = 0;
exitCode = 0;
exitStatus = QProcess::NormalExit;
+#ifndef Q_OS_QNX
startupSocketNotifier = 0;
+#endif
deathNotifier = 0;
notifier = 0;
pipeWriter = 0;
+#ifndef Q_OS_QNX
childStartedPipe[0] = INVALID_Q_PIPE;
childStartedPipe[1] = INVALID_Q_PIPE;
+#endif
deathPipe[0] = INVALID_Q_PIPE;
deathPipe[1] = INVALID_Q_PIPE;
exitCode = 0;
@@ -825,11 +829,13 @@ void QProcessPrivate::cleanup()
qDeleteInEventHandler(stdinChannel.notifier);
stdinChannel.notifier = 0;
}
+#ifndef Q_OS_QNX
if (startupSocketNotifier) {
startupSocketNotifier->setEnabled(false);
qDeleteInEventHandler(startupSocketNotifier);
startupSocketNotifier = 0;
}
+#endif
if (deathNotifier) {
deathNotifier->setEnabled(false);
qDeleteInEventHandler(deathNotifier);
@@ -842,7 +848,9 @@ void QProcessPrivate::cleanup()
destroyPipe(stdoutChannel.pipe);
destroyPipe(stderrChannel.pipe);
destroyPipe(stdinChannel.pipe);
+#ifndef Q_OS_QNX
destroyPipe(childStartedPipe);
+#endif
destroyPipe(deathPipe);
#ifdef Q_OS_UNIX
serial = 0;
@@ -1077,8 +1085,10 @@ bool QProcessPrivate::_q_startupNotification()
qDebug("QProcessPrivate::startupNotification()");
#endif
+#ifndef Q_OS_QNX
if (startupSocketNotifier)
startupSocketNotifier->setEnabled(false);
+#endif
if (processStarted()) {
q->setProcessState(QProcess::Running);
emit q->started();
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 9adb331..f24a7bc 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -288,11 +288,15 @@ public:
QRingBuffer errorReadBuffer;
QRingBuffer writeBuffer;
+#ifndef Q_OS_QNX
Q_PIPE childStartedPipe[2];
+#endif
Q_PIPE deathPipe[2];
void destroyPipe(Q_PIPE pipe[2]);
+#ifndef Q_OS_QNX
QSocketNotifier *startupSocketNotifier;
+#endif
QSocketNotifier *deathNotifier;
// the wonderful windows notifier
@@ -301,8 +305,10 @@ public:
QWinEventNotifier *processFinishedNotifier;
void startProcess();
-#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN)
+#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) && !defined(Q_OS_QNX)
void execChild(const char *workingDirectory, char **path, char **argv, char **envp);
+#elif defined(Q_OS_QNX)
+ pid_t spawnChild(const char *workingDirectory, char **argv, char **envp);
#endif
bool processStarted();
void terminateProcess();
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 07e3087..725e4c5 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -105,6 +105,10 @@ QT_END_NAMESPACE
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#ifdef Q_OS_QNX
+# include <spawn.h>
+#endif
+
QT_BEGIN_NAMESPACE
@@ -521,16 +525,6 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environm
return envp;
}
-// under QNX RTOS we have to use vfork() when multithreading
-inline pid_t qt_fork()
-{
-#if defined(Q_OS_QNX)
- return vfork();
-#else
- return fork();
-#endif
-}
-
#ifdef Q_OS_MAC
Q_GLOBAL_STATIC(QMutex, cfbundleMutex);
#endif
@@ -550,15 +544,18 @@ void QProcessPrivate::startProcess()
!createChannel(stdoutChannel) ||
!createChannel(stderrChannel))
return;
+#if !defined(Q_OS_QNX)
qt_create_pipe(childStartedPipe);
+#endif
qt_create_pipe(deathPipe);
if (threadData->eventDispatcher) {
+#if !defined(Q_OS_QNX)
startupSocketNotifier = new QSocketNotifier(childStartedPipe[0],
QSocketNotifier::Read, q);
QObject::connect(startupSocketNotifier, SIGNAL(activated(int)),
q, SLOT(_q_startupNotification()));
-
+#endif
deathNotifier = new QSocketNotifier(deathPipe[0],
QSocketNotifier::Read, q);
QObject::connect(deathNotifier, SIGNAL(activated(int)),
@@ -650,7 +647,11 @@ void QProcessPrivate::startProcess()
// Start the process manager, and fork off the child process.
processManager()->lock();
- pid_t childPid = qt_fork();
+#if defined(Q_OS_QNX)
+ pid_t childPid = spawnChild(workingDirPtr, argv, envp);
+#else
+ pid_t childPid = fork();
+#endif
int lastForkErrno = errno;
if (childPid != 0) {
// Clean up duplicated memory.
@@ -668,7 +669,7 @@ void QProcessPrivate::startProcess()
if (childPid < 0) {
// Cleanup, report error and return
#if defined (QPROCESS_DEBUG)
- qDebug("qt_fork failed: %s", qPrintable(qt_error_string(lastForkErrno)));
+ qDebug("fork() failed: %s", qPrintable(qt_error_string(lastForkErrno)));
#endif
processManager()->unlock();
q->setProcessState(QProcess::NotRunning);
@@ -679,11 +680,13 @@ void QProcessPrivate::startProcess()
return;
}
+#if !defined(Q_OS_QNX)
// Start the child.
if (childPid == 0) {
execChild(workingDirPtr, path, argv, envp);
::_exit(-1);
}
+#endif
// Register the child. In the mean time, we can get a SIGCHLD, so we need
// to keep the lock held to avoid a race to catch the child.
@@ -694,14 +697,15 @@ void QProcessPrivate::startProcess()
// parent
// close the ends we don't use and make all pipes non-blocking
::fcntl(deathPipe[0], F_SETFL, ::fcntl(deathPipe[0], F_GETFL) | O_NONBLOCK);
+#if !defined(Q_OS_QNX)
qt_safe_close(childStartedPipe[1]);
childStartedPipe[1] = -1;
+#endif
if (stdinChannel.pipe[0] != -1) {
qt_safe_close(stdinChannel.pipe[0]);
stdinChannel.pipe[0] = -1;
}
-
if (stdinChannel.pipe[1] != -1)
::fcntl(stdinChannel.pipe[1], F_SETFL, ::fcntl(stdinChannel.pipe[1], F_GETFL) | O_NONBLOCK);
@@ -709,7 +713,6 @@ void QProcessPrivate::startProcess()
qt_safe_close(stdoutChannel.pipe[1]);
stdoutChannel.pipe[1] = -1;
}
-
if (stdoutChannel.pipe[0] != -1)
::fcntl(stdoutChannel.pipe[0], F_SETFL, ::fcntl(stdoutChannel.pipe[0], F_GETFL) | O_NONBLOCK);
@@ -721,6 +724,7 @@ void QProcessPrivate::startProcess()
::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK);
}
+#if !defined(Q_OS_QNX)
void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv, char **envp)
{
::signal(SIGPIPE, SIG_DFL); // reset the signal that we ignored
@@ -728,17 +732,17 @@ void QProcessPrivate::execChild(const char *workingDir, char **path, char **argv
Q_Q(QProcess);
// copy the stdin socket (without closing on exec)
- qt_safe_dup2(stdinChannel.pipe[0], fileno(stdin), 0);
+ qt_safe_dup2(stdinChannel.pipe[0], QT_FILENO(stdin), 0);
// copy the stdout and stderr if asked to
if (processChannelMode != QProcess::ForwardedChannels) {
- qt_safe_dup2(stdoutChannel.pipe[1], fileno(stdout), 0);
+ qt_safe_dup2(stdoutChannel.pipe[1], QT_FILENO(stdout), 0);
// merge stdout and stderr if asked to
if (processChannelMode == QProcess::MergedChannels) {
- qt_safe_dup2(fileno(stdout), fileno(stderr), 0);
+ qt_safe_dup2(QT_FILENO(stdout), QT_FILENO(stderr), 0);
} else {
- qt_safe_dup2(stderrChannel.pipe[1], fileno(stderr), 0);
+ qt_safe_dup2(stderrChannel.pipe[1], QT_FILENO(stderr), 0);
}
}
@@ -807,6 +811,87 @@ bool QProcessPrivate::processStarted()
return i <= 0;
}
+#else // Q_OS_QNX
+
+static pid_t doSpawn(int fd_count, int fd_map[], char **argv, char **envp, bool spawn_detached)
+{
+ // A multi threaded QNX Process can't fork so we call spawn() instead.
+
+ struct inheritance inherit;
+ memset(&inherit, 0, sizeof(inherit));
+ inherit.flags |= SPAWN_SETSID;
+ inherit.flags |= SPAWN_CHECK_SCRIPT;
+ if (spawn_detached)
+ inherit.flags |= SPAWN_NOZOMBIE;
+ inherit.flags |= SPAWN_SETSIGDEF;
+ sigaddset(&inherit.sigdefault, SIGPIPE); // reset the signal that we ignored
+
+ pid_t childPid;
+ EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp));
+ if (childPid == -1) {
+ inherit.flags |= SPAWN_SEARCH_PATH;
+ EINTR_LOOP(childPid, ::spawn(argv[0], fd_count, fd_map, &inherit, argv, envp));
+ }
+
+ return childPid;
+}
+
+pid_t QProcessPrivate::spawnChild(const char *workingDir, char **argv, char **envp)
+{
+ Q_Q(QProcess);
+
+ const int fd_count = 3;
+ int fd_map[fd_count];
+ switch (processChannelMode) {
+ case QProcess::ForwardedChannels:
+ fd_map[0] = stdinChannel.pipe[0];
+ fd_map[1] = QT_FILENO(stdout);
+ fd_map[2] = QT_FILENO(stderr);
+ break;
+ case QProcess::MergedChannels:
+ fd_map[0] = stdinChannel.pipe[0];
+ fd_map[1] = stdoutChannel.pipe[1];
+ fd_map[2] = stdoutChannel.pipe[1];
+ break;
+ case QProcess::SeparateChannels:
+ fd_map[0] = stdinChannel.pipe[0];
+ fd_map[1] = stdoutChannel.pipe[1];
+ fd_map[2] = stderrChannel.pipe[1];
+ break;
+ }
+
+ // enter the working directory
+ char *oldWorkingDir = 0;
+ char buff[PATH_MAX + 1];
+ if (workingDir) {
+ oldWorkingDir = QT_GETCWD(buff, PATH_MAX + 1);
+ QT_CHDIR(workingDir);
+ }
+
+ pid_t childPid = doSpawn(fd_count, fd_map, argv, envp, false);
+
+ if (oldWorkingDir)
+ QT_CHDIR(oldWorkingDir);
+
+ if (childPid != -1) {
+ q->setProcessState(QProcess::Running);
+ QMetaObject::invokeMethod(q, "_q_startupNotification", Qt::QueuedConnection);
+ }
+
+ return childPid;
+}
+
+bool QProcessPrivate::processStarted()
+{
+ return processState == QProcess::Running;
+}
+
+bool QProcessPrivate::waitForStarted(int /*msecs*/)
+{
+ return processStarted();
+}
+#endif // Q_OS_QNX
+
qint64 QProcessPrivate::bytesAvailableFromStdout() const
{
int nbytes = 0;
@@ -924,6 +1009,7 @@ static int qt_timeout_value(int msecs, int elapsed)
return timeout < 0 ? 0 : timeout;
}
+#if !defined(Q_OS_QNX)
bool QProcessPrivate::waitForStarted(int msecs)
{
Q_Q(QProcess);
@@ -951,6 +1037,7 @@ bool QProcessPrivate::waitForStarted(int msecs)
#endif
return startedEmitted;
}
+#endif // Q_OS_QNX
bool QProcessPrivate::waitForReadyRead(int msecs)
{
@@ -972,8 +1059,10 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
int nfds = deathPipe[0];
FD_SET(deathPipe[0], &fdread);
+#if !defined(Q_OS_QNX)
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
+#endif
if (stdoutChannel.pipe[0] != -1)
add_fd(nfds, stdoutChannel.pipe[0], &fdread);
@@ -994,10 +1083,12 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
return false;
}
+#if !defined(Q_OS_QNX)
if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
}
+#endif
bool readyReadEmitted = false;
if (stdoutChannel.pipe[0] != -1 && FD_ISSET(stdoutChannel.pipe[0], &fdread)) {
@@ -1044,8 +1135,10 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
int nfds = deathPipe[0];
FD_SET(deathPipe[0], &fdread);
+#if !defined(Q_OS_QNX)
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
+#endif
if (stdoutChannel.pipe[0] != -1)
add_fd(nfds, stdoutChannel.pipe[0], &fdread);
@@ -1068,10 +1161,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
return false;
}
+#if !defined(Q_OS_QNX)
if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
}
+#endif
if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
return _q_canWrite();
@@ -1109,8 +1204,10 @@ bool QProcessPrivate::waitForFinished(int msecs)
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
+#if !defined(Q_OS_QNX)
if (processState == QProcess::Starting)
add_fd(nfds, childStartedPipe[0], &fdread);
+#endif
if (stdoutChannel.pipe[0] != -1)
add_fd(nfds, stdoutChannel.pipe[0], &fdread);
@@ -1134,10 +1231,12 @@ bool QProcessPrivate::waitForFinished(int msecs)
return false;
}
+#if !defined(Q_OS_QNX)
if (childStartedPipe[0] != -1 && FD_ISSET(childStartedPipe[0], &fdread)) {
if (!_q_startupNotification())
return false;
}
+#endif
if (stdinChannel.pipe[1] != -1 && FD_ISSET(stdinChannel.pipe[1], &fdwrite))
_q_canWrite();
@@ -1199,6 +1298,47 @@ void QProcessPrivate::_q_notified()
{
}
+#if defined(Q_OS_QNX)
+bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
+{
+ QByteArray encodedWorkingDirectory = QFile::encodeName(workingDirectory);
+
+ // enter the working directory
+ char *oldWorkingDir = 0;
+ char buff[PATH_MAX + 1];
+ if (!encodedWorkingDirectory.isEmpty()) {
+ oldWorkingDir = QT_GETCWD(buff, PATH_MAX + 1);
+ QT_CHDIR(encodedWorkingDirectory.constData());
+ }
+
+ const int fd_count = 3;
+ int fd_map[fd_count] = { QT_FILENO(stdin), QT_FILENO(stdout), QT_FILENO(stderr) };
+
+ QList<QByteArray> enc_args;
+ enc_args.append(QFile::encodeName(program));
+ for (int i = 0; i < arguments.size(); ++i)
+ enc_args.append(arguments.at(i).toLocal8Bit());
+
+ const int argc = enc_args.size();
+ QScopedArrayPointer<char*> raw_argv(new char*[argc + 1]);
+ for (int i = 0; i < argc; ++i)
+ raw_argv[i] = const_cast<char *>(enc_args.at(i).data());
+ raw_argv[argc] = 0;
+
+ char **envp = 0; // inherit environment
+
+ pid_t childPid = doSpawn(fd_count, fd_map, raw_argv.data(), envp, true);
+ if (pid && childPid != -1)
+ *pid = childPid;
+
+ if (oldWorkingDir)
+ QT_CHDIR(oldWorkingDir);
+
+ return childPid != -1;
+}
+
+#else
+
bool QProcessPrivate::startDetached(const QString &program, const QStringList &arguments, const QString &workingDirectory, qint64 *pid)
{
processManager()->start();
@@ -1212,7 +1352,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
int pidPipe[2];
qt_safe_pipe(pidPipe);
- pid_t childPid = qt_fork();
+ pid_t childPid = fork();
if (childPid == 0) {
struct sigaction noaction;
memset(&noaction, 0, sizeof(noaction));
@@ -1224,7 +1364,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
qt_safe_close(startedPipe[0]);
qt_safe_close(pidPipe[0]);
- pid_t doubleForkPid = qt_fork();
+ pid_t doubleForkPid = fork();
if (doubleForkPid == 0) {
qt_safe_close(pidPipe[1]);
@@ -1312,6 +1452,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
qt_safe_close(pidPipe[0]);
return success;
}
+#endif // Q_OS_QNX
void QProcessPrivate::initializeProcessManager()
{
diff --git a/src/corelib/kernel/qcore_mac.cpp b/src/corelib/kernel/qcore_mac.cpp
index 0814c1a..e705c31 100644
--- a/src/corelib/kernel/qcore_mac.cpp
+++ b/src/corelib/kernel/qcore_mac.cpp
@@ -41,22 +41,22 @@
#include <private/qcore_mac_p.h>
#include <new>
-#include "qvarlengtharray.h"
QT_BEGIN_NAMESPACE
QString QCFString::toQString(CFStringRef str)
{
- if(!str)
+ if (!str)
return QString();
+
CFIndex length = CFStringGetLength(str);
- const UniChar *chars = CFStringGetCharactersPtr(str);
- if (chars)
- return QString(reinterpret_cast<const QChar *>(chars), length);
+ if (length == 0)
+ return QString();
+
+ QString string(length, Qt::Uninitialized);
+ CFStringGetCharacters(str, CFRangeMake(0, length), reinterpret_cast<UniChar *>(const_cast<QChar *>(string.unicode())));
- QVarLengthArray<UniChar> buffer(length);
- CFStringGetCharacters(str, CFRangeMake(0, length), buffer.data());
- return QString(reinterpret_cast<const QChar *>(buffer.constData()), length);
+ return string;
}
QCFString::operator QString() const
@@ -74,9 +74,66 @@ CFStringRef QCFString::toCFStringRef(const QString &string)
QCFString::operator CFStringRef() const
{
- if (!type)
- const_cast<QCFString*>(this)->type = toCFStringRef(string);
+ if (!type) {
+ if (string.d->data != string.d->array)
+ const_cast<QCFString*>(this)->string.realloc(); // ### Qt5: do we really need this stupid user protection?
+ const_cast<QCFString*>(this)->type =
+ CFStringCreateWithCharactersNoCopy(0,
+ reinterpret_cast<const UniChar *>(string.unicode()),
+ string.length(),
+ kCFAllocatorNull);
+ }
return type;
}
+
+void qt_mac_to_pascal_string(const QString &s, Str255 str, TextEncoding encoding, int len)
+{
+ if(len == -1)
+ len = s.length();
+#if 0
+ UnicodeMapping mapping;
+ mapping.unicodeEncoding = CreateTextEncoding(kTextEncodingUnicodeDefault,
+ kTextEncodingDefaultVariant,
+ kUnicode16BitFormat);
+ mapping.otherEncoding = (encoding ? encoding : );
+ mapping.mappingVersion = kUnicodeUseLatestMapping;
+
+ UnicodeToTextInfo info;
+ OSStatus err = CreateUnicodeToTextInfo(&mapping, &info);
+ if(err != noErr) {
+ qDebug("Qt: internal: Unable to create pascal string '%s'::%d [%ld]",
+ s.left(len).latin1(), (int)encoding, err);
+ return;
+ }
+ const int unilen = len * 2;
+ const UniChar *unibuf = (UniChar *)s.unicode();
+ ConvertFromUnicodeToPString(info, unilen, unibuf, str);
+ DisposeUnicodeToTextInfo(&info);
+#else
+ Q_UNUSED(encoding);
+ CFStringGetPascalString(QCFString(s), str, 256, CFStringGetSystemEncoding());
+#endif
+}
+
+QString qt_mac_from_pascal_string(const Str255 pstr)
+{
+ return QCFString(CFStringCreateWithPascalString(0, pstr, CFStringGetSystemEncoding()));
+}
+
+OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref)
+{
+ return FSPathMakeRef(reinterpret_cast<const UInt8 *>(file.toUtf8().constData()), fsref, 0);
+}
+
+// Don't use this function, it won't work in 10.5 (Leopard) and up
+OSErr qt_mac_create_fsspec(const QString &file, FSSpec *spec)
+{
+ FSRef fsref;
+ OSErr ret = qt_mac_create_fsref(file, &fsref);
+ if (ret == noErr)
+ ret = FSGetCatalogInfo(&fsref, kFSCatInfoNone, 0, 0, spec, 0);
+ return ret;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcore_mac_p.h b/src/corelib/kernel/qcore_mac_p.h
index adbad83..4b8c16f 100644
--- a/src/corelib/kernel/qcore_mac_p.h
+++ b/src/corelib/kernel/qcore_mac_p.h
@@ -148,6 +148,13 @@ private:
QString string;
};
+Q_CORE_EXPORT void qt_mac_to_pascal_string(const QString &s, Str255 str, TextEncoding encoding = 0, int len = -1);
+Q_CORE_EXPORT QString qt_mac_from_pascal_string(const Str255 pstr);
+
+Q_CORE_EXPORT OSErr qt_mac_create_fsref(const QString &file, FSRef *fsref);
+// Don't use this function, it won't work in 10.5 (Leopard) and up
+Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &file, FSSpec *spec);
+
QT_END_NAMESPACE
#if (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5)
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 7694a0f..dd46bc5 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -98,6 +98,12 @@
# include <taskLib.h>
#endif
+#ifdef Q_OS_QNX
+# include <sys/neutrino.h>
+# include <pthread.h>
+# include <sched.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QMutexUnlocker
@@ -353,6 +359,22 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint
qt_application_thread_id = QThread::currentThreadId();
#endif
+#ifdef Q_OS_QNX
+ // make the kernel attempt to emulate an instruction with a misaligned access
+ // if the attempt fails, it faults with a SIGBUS
+ int tv = -1;
+ ThreadCtl(_NTO_TCTL_ALIGN_FAULT, &tv);
+
+ // without Round Robin drawn intensive apps will hog the cpu
+ // and make the system appear frozen
+ int sched_policy;
+ sched_param param;
+ if (pthread_getschedparam(0, &sched_policy, &param) == 0 && sched_policy != SCHED_RR) {
+ sched_policy = SCHED_RR;
+ pthread_setschedparam(0, sched_policy, &param);
+ }
+#endif
+
// note: this call to QThread::currentThread() may end up setting theMainThread!
if (QThread::currentThread() != theMainThread)
qWarning("WARNING: QApplication was not created in the main() thread.");
diff --git a/src/corelib/kernel/qsharedmemory.cpp b/src/corelib/kernel/qsharedmemory.cpp
index 2882279..371974c 100644
--- a/src/corelib/kernel/qsharedmemory.cpp
+++ b/src/corelib/kernel/qsharedmemory.cpp
@@ -80,6 +80,8 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
return result;
#elif defined(Q_OS_SYMBIAN)
return result.left(KMaxKernelName);
+#elif defined(QT_POSIX_IPC)
+ return QLatin1Char('/') + result;
#else
return QDir::tempPath() + QLatin1Char('/') + result;
#endif
@@ -117,6 +119,9 @@ QSharedMemoryPrivate::makePlatformSafeKey(const QString &key,
process crashes without running the QSharedMemory destructor, the
shared memory segment survives the crash.
+ \o QNX: Due to possible race conditions in the POSIX IPC implementation, create()
+ should be called prior to any attach() calls (even across multiple threads).
+
\o HP-UX: Only one attach to a shared memory segment is allowed per
process. This means that QSharedMemory should not be used across
multiple threads in the same process in HP-UX.
diff --git a/src/corelib/kernel/qsharedmemory_p.h b/src/corelib/kernel/qsharedmemory_p.h
index 21b8612..780e52e 100644
--- a/src/corelib/kernel/qsharedmemory_p.h
+++ b/src/corelib/kernel/qsharedmemory_p.h
@@ -135,6 +135,8 @@ public:
const QString &prefix = QLatin1String("qipc_sharedmemory_"));
#ifdef Q_OS_WIN
HANDLE handle();
+#elif defined(QT_POSIX_IPC)
+ int handle();
#else
key_t handle();
#endif
@@ -166,6 +168,8 @@ private:
HANDLE hand;
#elif defined(Q_OS_SYMBIAN)
RChunk chunk;
+#elif defined(QT_POSIX_IPC)
+ int hand;
#else
key_t unix_key;
#endif
diff --git a/src/corelib/kernel/qsharedmemory_unix.cpp b/src/corelib/kernel/qsharedmemory_unix.cpp
index e991ce9..a086acd 100644
--- a/src/corelib/kernel/qsharedmemory_unix.cpp
+++ b/src/corelib/kernel/qsharedmemory_unix.cpp
@@ -50,8 +50,12 @@
#ifndef QT_NO_SHAREDMEMORY
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/shm.h>
+#else
+#include <sys/mman.h>
#include <sys/stat.h>
+#endif
#include <fcntl.h>
#include <unistd.h>
#endif // QT_NO_SHAREDMEMORY
@@ -70,7 +74,11 @@ QSharedMemoryPrivate::QSharedMemoryPrivate()
#ifndef QT_NO_SYSTEMSEMAPHORE
systemSemaphore(QString()), lockedByMe(false),
#endif
+#ifndef QT_POSIX_IPC
unix_key(0)
+#else
+ hand(0)
+#endif
{
}
@@ -91,12 +99,18 @@ void QSharedMemoryPrivate::setErrorString(const QString &function)
errorString = QSharedMemory::tr("%1: doesn't exist").arg(function);
error = QSharedMemory::NotFound;
break;
+ case EAGAIN:
case EMFILE:
+ case ENFILE:
case ENOMEM:
case ENOSPC:
errorString = QSharedMemory::tr("%1: out of resources").arg(function);
error = QSharedMemory::OutOfResources;
break;
+ case EOVERFLOW:
+ errorString = QSharedMemory::tr("%1: invalid size").arg(function);
+ error = QSharedMemory::InvalidSize;
+ break;
default:
errorString = QSharedMemory::tr("%1: unknown error %2").arg(function).arg(errno);
error = QSharedMemory::UnknownError;
@@ -112,6 +126,7 @@ void QSharedMemoryPrivate::setErrorString(const QString &function)
If not already made create the handle used for accessing the shared memory.
*/
+#ifndef QT_POSIX_IPC
key_t QSharedMemoryPrivate::handle()
{
// already made
@@ -140,6 +155,20 @@ key_t QSharedMemoryPrivate::handle()
}
return unix_key;
}
+#else
+int QSharedMemoryPrivate::handle()
+{
+ // don't allow making handles on empty keys
+ QString safeKey = makePlatformSafeKey(key);
+ if (safeKey.isEmpty()) {
+ errorString = QSharedMemory::tr("%1: key is empty").arg(QLatin1String("QSharedMemory::handle"));
+ error = QSharedMemory::KeyError;
+ return 0;
+ }
+
+ return 1;
+}
+#endif // QT_POSIX_IPC
#endif // QT_NO_SHAREDMEMORY
@@ -155,6 +184,7 @@ key_t QSharedMemoryPrivate::handle()
*/
int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
{
+#ifndef QT_POSIX_IPC
if (QFile::exists(fileName))
return 0;
@@ -168,6 +198,11 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
qt_safe_close(fd);
}
return 1;
+#else
+ Q_UNUSED(fileName);
+ // nothing to do
+ return -1;
+#endif
}
#endif // QT_NO_SHAREDMEMORY && QT_NO_SYSTEMSEMAPHORE
@@ -175,11 +210,17 @@ int QSharedMemoryPrivate::createUnixKeyFile(const QString &fileName)
void QSharedMemoryPrivate::cleanHandle()
{
+#ifndef QT_POSIX_IPC
unix_key = 0;
+#else
+ qt_safe_close(hand);
+ hand = 0;
+#endif
}
bool QSharedMemoryPrivate::create(int size)
{
+#ifndef QT_POSIX_IPC
// build file if needed
int built = createUnixKeyFile(nativeKey);
if (built == -1) {
@@ -211,12 +252,46 @@ bool QSharedMemoryPrivate::create(int size)
QFile::remove(nativeKey);
return false;
}
+#else
+ if (!handle())
+ return false;
+
+ QByteArray shmName = QFile::encodeName(makePlatformSafeKey(key));
+
+ int fd;
+ EINTR_LOOP(fd, shm_open(shmName.constData(), O_RDWR | O_CREAT | O_EXCL, 0666));
+ if (fd == -1) {
+ QString function = QLatin1String("QSharedMemory::create");
+ switch (errno) {
+ case ENAMETOOLONG:
+ case EINVAL:
+ errorString = QSharedMemory::tr("%1: bad name").arg(function);
+ error = QSharedMemory::KeyError;
+ break;
+ default:
+ setErrorString(function);
+ }
+ return false;
+ }
+
+ // the size may only be set once; ignore errors
+ int ret;
+ EINTR_LOOP(ret, ftruncate(fd, size));
+ if (ret == -1) {
+ setErrorString(QLatin1String("QSharedMemory::create (ftruncate)"));
+ qt_safe_close(fd);
+ return false;
+ }
+
+ qt_safe_close(fd);
+#endif // QT_POSIX_IPC
return true;
}
bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
{
+#ifndef QT_POSIX_IPC
// grab the shared memory segment id
int id = shmget(unix_key, 0, (mode == QSharedMemory::ReadOnly ? 0444 : 0660));
if (-1 == id) {
@@ -240,12 +315,55 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode)
setErrorString(QLatin1String("QSharedMemory::attach (shmctl)"));
return false;
}
+#else
+ QByteArray shmName = QFile::encodeName(makePlatformSafeKey(key));
+
+ int oflag = (mode == QSharedMemory::ReadOnly ? O_RDONLY : O_RDWR);
+ mode_t omode = (mode == QSharedMemory::ReadOnly ? 0444 : 0660);
+
+ EINTR_LOOP(hand, shm_open(shmName.constData(), oflag, omode));
+ if (hand == -1) {
+ QString function = QLatin1String("QSharedMemory::attach (shm_open)");
+ switch (errno) {
+ case ENAMETOOLONG:
+ case EINVAL:
+ errorString = QSharedMemory::tr("%1: bad name").arg(function);
+ error = QSharedMemory::KeyError;
+ break;
+ default:
+ setErrorString(function);
+ }
+ hand = 0;
+ return false;
+ }
+
+ // grab the size
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) == -1) {
+ setErrorString(QLatin1String("QSharedMemory::attach (fstat)"));
+ cleanHandle();
+ return false;
+ }
+ size = st.st_size;
+
+ // grab the memory
+ int mprot = (mode == QSharedMemory::ReadOnly ? PROT_READ : PROT_READ | PROT_WRITE);
+ memory = mmap(0, size, mprot, MAP_SHARED, hand, 0);
+ if (memory == MAP_FAILED || !memory) {
+ setErrorString(QLatin1String("QSharedMemory::attach (mmap)"));
+ cleanHandle();
+ memory = 0;
+ size = 0;
+ return false;
+ }
+#endif // QT_POSIX_IPC
return true;
}
bool QSharedMemoryPrivate::detach()
{
+#ifndef QT_POSIX_IPC
// detach from the memory segment
if (-1 == shmdt(memory)) {
QString function = QLatin1String("QSharedMemory::detach");
@@ -292,6 +410,31 @@ bool QSharedMemoryPrivate::detach()
if (!QFile::remove(nativeKey))
return false;
}
+#else
+ // detach from the memory segment
+ if (munmap(memory, size) == -1) {
+ setErrorString(QLatin1String("QSharedMemory::detach (munmap)"));
+ return false;
+ }
+ memory = 0;
+ size = 0;
+
+ // get the number of current attachments
+ int shm_nattch = 0;
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) == 0) {
+ // subtract 2 from linkcount: one for our own open and one for the dir entry
+ shm_nattch = st.st_nlink - 2;
+ }
+ cleanHandle();
+ // if there are no attachments then unlink the shared memory
+ if (shm_nattch == 0) {
+ QByteArray shmName = QFile::encodeName(makePlatformSafeKey(key));
+ if (shm_unlink(shmName.constData()) == -1 && errno != ENOENT)
+ setErrorString(QLatin1String("QSharedMemory::detach (shm_unlink)"));
+ }
+#endif // QT_POSIX_IPC
+
return true;
}
diff --git a/src/corelib/kernel/qsystemsemaphore.cpp b/src/corelib/kernel/qsystemsemaphore.cpp
index 98ee6f4..ae30348 100644
--- a/src/corelib/kernel/qsystemsemaphore.cpp
+++ b/src/corelib/kernel/qsystemsemaphore.cpp
@@ -151,6 +151,11 @@ QT_BEGIN_NAMESPACE
creates a new semaphore for that key and sets its resource count to
\a initialValue.
+ In QNX, if the \a mode is \l {QSystemSemaphore::} {Create} and the
+ system already has a semaphore identified by \a key, that semaphore
+ will be deleted and the new one will be created for that key with
+ a resource count set to \a initialValue.
+
In Windows and in Symbian, \a mode is ignored, and the system always tries to
create a semaphore for the specified \a key. If the system does not
already have a semaphore identified as \a key, it creates the
@@ -234,7 +239,7 @@ void QSystemSemaphore::setKey(const QString &key, int initialValue, AccessMode m
return;
d->error = NoError;
d->errorString = QString();
-#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN)
+#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN) && !defined(QT_POSIX_IPC)
// optimization to not destroy/create the file & semaphore
if (key == d->key && mode == Create && d->createdSemaphore && d->createdFile) {
d->initialValue = initialValue;
diff --git a/src/corelib/kernel/qsystemsemaphore_p.h b/src/corelib/kernel/qsystemsemaphore_p.h
index 3e5f737..d84d416 100644
--- a/src/corelib/kernel/qsystemsemaphore_p.h
+++ b/src/corelib/kernel/qsystemsemaphore_p.h
@@ -61,6 +61,9 @@
#ifndef Q_OS_WINCE
# include <sys/types.h>
#endif
+#ifdef QT_POSIX_IPC
+# include <semaphore.h>
+#endif
#ifdef Q_OS_SYMBIAN
class RSemaphore;
@@ -84,6 +87,9 @@ public:
#elif defined(Q_OS_SYMBIAN)
int handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
void setErrorString(const QString &function,int err = 0);
+#elif defined(QT_POSIX_IPC)
+ bool handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
+ void setErrorString(const QString &function);
#else
key_t handle(QSystemSemaphore::AccessMode mode = QSystemSemaphore::Open);
void setErrorString(const QString &function);
@@ -99,6 +105,9 @@ public:
HANDLE semaphoreLock;
#elif defined(Q_OS_SYMBIAN)
RSemaphore semaphore;
+#elif defined(QT_POSIX_IPC)
+ sem_t *semaphore;
+ bool createdSemaphore;
#else
key_t unix_key;
int semaphore;
diff --git a/src/corelib/kernel/qsystemsemaphore_unix.cpp b/src/corelib/kernel/qsystemsemaphore_unix.cpp
index 704afaf..e060eb2 100644
--- a/src/corelib/kernel/qsystemsemaphore_unix.cpp
+++ b/src/corelib/kernel/qsystemsemaphore_unix.cpp
@@ -50,7 +50,9 @@
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/sem.h>
+#endif
#include <fcntl.h>
#include <errno.h>
@@ -67,7 +69,11 @@
QT_BEGIN_NAMESPACE
QSystemSemaphorePrivate::QSystemSemaphorePrivate() :
+#ifndef QT_POSIX_IPC
unix_key(-1), semaphore(-1), createdFile(false),
+#else
+ semaphore(SEM_FAILED),
+#endif
createdSemaphore(false), error(QSystemSemaphore::NoError)
{
}
@@ -90,10 +96,18 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function)
error = QSystemSemaphore::NotFound;
break;
case ERANGE:
+ case ENOMEM:
case ENOSPC:
+ case EMFILE:
+ case ENFILE:
+ case EOVERFLOW:
errorString = QCoreApplication::translate("QSystemSemaphore", "%1: out of resources").arg(function);
error = QSystemSemaphore::OutOfResources;
break;
+ case ENAMETOOLONG:
+ errorString = QCoreApplication::translate("QSystemSemaphore", "%1: name error").arg(function);
+ error = QSystemSemaphore::KeyError;
+ break;
default:
errorString = QCoreApplication::translate("QSystemSemaphore", "%1: unknown error %2").arg(function).arg(errno);
error = QSystemSemaphore::UnknownError;
@@ -109,6 +123,7 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function)
Initialise the semaphore
*/
+#ifndef QT_POSIX_IPC
key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
{
if (-1 != unix_key)
@@ -170,6 +185,54 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
return unix_key;
}
+#else
+bool QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
+{
+ if (semaphore != SEM_FAILED)
+ return true; // we already have a semaphore
+
+ if (fileName.isEmpty()) {
+ errorString = QCoreApplication::tr("%1: key is empty", "QSystemSemaphore").arg(QLatin1String("QSystemSemaphore::handle"));
+ error = QSystemSemaphore::KeyError;
+ return false;
+ }
+
+ QByteArray semName = QFile::encodeName(fileName);
+
+ // Always try with O_EXCL so we know whether we created the semaphore.
+ int oflag = O_CREAT | O_EXCL;
+ for (int tryNum = 0, maxTries = 1; tryNum < maxTries; ++tryNum) {
+ do {
+ semaphore = sem_open(semName.constData(), oflag, 0666, initialValue);
+ } while (semaphore == SEM_FAILED && errno == EINTR);
+ if (semaphore == SEM_FAILED && errno == EEXIST) {
+ if (mode == QSystemSemaphore::Create) {
+ if (sem_unlink(semName.constData()) == -1 && errno != ENOENT) {
+ setErrorString(QLatin1String("QSystemSemaphore::handle (sem_unlink)"));
+ return false;
+ }
+ // Race condition: the semaphore might be recreated before
+ // we call sem_open again, so we'll retry several times.
+ maxTries = 3;
+ } else {
+ // Race condition: if it no longer exists at the next sem_open
+ // call, we won't realize we created it, so we'll leak it later.
+ oflag &= ~O_EXCL;
+ maxTries = 2;
+ }
+ } else {
+ break;
+ }
+ }
+ if (semaphore == SEM_FAILED) {
+ setErrorString(QLatin1String("QSystemSemaphore::handle"));
+ return false;
+ }
+
+ createdSemaphore = (oflag & O_EXCL) != 0;
+ return true;
+}
+#endif // QT_POSIX_IPC
/*!
\internal
@@ -178,6 +241,7 @@ key_t QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode mode)
*/
void QSystemSemaphorePrivate::cleanHandle()
{
+#ifndef QT_POSIX_IPC
unix_key = -1;
// remove the file if we made it
@@ -198,6 +262,27 @@ void QSystemSemaphorePrivate::cleanHandle()
}
createdSemaphore = false;
}
+#else
+ if (semaphore != SEM_FAILED) {
+ if (sem_close(semaphore) == -1) {
+ setErrorString(QLatin1String("QSystemSemaphore::cleanHandle (sem_close)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::cleanHandle sem_close failed.");
+#endif
+ }
+ semaphore = SEM_FAILED;
+ }
+
+ if (createdSemaphore) {
+ if (sem_unlink(QFile::encodeName(fileName).constData()) == -1 && errno != ENOENT) {
+ setErrorString(QLatin1String("QSystemSemaphore::cleanHandle (sem_unlink)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::cleanHandle sem_unlink failed.");
+#endif
+ }
+ createdSemaphore = false;
+ }
+#endif // QT_POSIX_IPC
}
/*!
@@ -205,6 +290,7 @@ void QSystemSemaphorePrivate::cleanHandle()
*/
bool QSystemSemaphorePrivate::modifySemaphore(int count)
{
+#ifndef QT_POSIX_IPC
if (-1 == handle())
return false;
@@ -229,6 +315,44 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count)
#endif
return false;
}
+#else
+ if (!handle())
+ return false;
+
+ if (count > 0) {
+ int cnt = count;
+ do {
+ if (sem_post(semaphore) == -1) {
+ setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore (sem_post)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::modify sem_post failed") << count << errno;
+#endif
+ // rollback changes to preserve the SysV semaphore behavior
+ for ( ; cnt < count; ++cnt) {
+ register int res;
+ EINTR_LOOP(res, sem_wait(semaphore));
+ }
+ return false;
+ }
+ --cnt;
+ } while (cnt > 0);
+ } else {
+ register int res;
+ EINTR_LOOP(res, sem_wait(semaphore));
+ if (res == -1) {
+ // If the semaphore was removed be nice and create it and then modifySemaphore again
+ if (errno == EINVAL || errno == EIDRM) {
+ semaphore = SEM_FAILED;
+ return modifySemaphore(count);
+ }
+ setErrorString(QLatin1String("QSystemSemaphore::modifySemaphore (sem_wait)"));
+#ifdef QSYSTEMSEMAPHORE_DEBUG
+ qDebug() << QLatin1String("QSystemSemaphore::modify sem_wait failed") << count << errno;
+#endif
+ return false;
+ }
+ }
+#endif // QT_POSIX_IPC
return true;
}
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index 839a396..765969e 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -479,6 +479,11 @@ void QThread::usleep(unsigned long usecs)
// sched_priority is OUT only
static bool calculateUnixPriority(int priority, int *sched_policy, int *sched_priority)
{
+#ifdef Q_OS_QNX
+ // without Round Robin drawn intensive apps will hog the cpu
+ // and make the system appear frozen
+ *sched_policy = SCHED_RR;
+#endif
#ifdef SCHED_IDLE
if (priority == QThread::IdlePriority) {
*sched_policy = SCHED_IDLE;
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index f8f4bdc..ee45cfd 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -3580,6 +3580,28 @@ static inline __m128i mergeQuestionMarks(__m128i chunk)
{
const __m128i questionMark = _mm_set1_epi16('?');
+# ifdef __SSE4_2__
+ // compare the unsigned shorts for the range 0x0100-0xFFFF
+ // note on the use of _mm_cmpestrm:
+ // The MSDN documentation online (http://technet.microsoft.com/en-us/library/bb514080.aspx)
+ // says for range search the following:
+ // For each character c in a, determine whether b0 <= c <= b1 or b2 <= c <= b3
+ //
+ // However, all examples on the Internet, including from Intel
+ // (see http://software.intel.com/en-us/articles/xml-parsing-accelerator-with-intel-streaming-simd-extensions-4-intel-sse4/)
+ // put the range to be searched first
+ //
+ // Disassembly and instruction-level debugging with GCC and ICC show
+ // that they are doing the right thing. Inverting the arguments in the
+ // instruction does cause a bunch of test failures.
+
+ const int mode = _SIDD_UWORD_OPS | _SIDD_CMP_RANGES | _SIDD_UNIT_MASK;
+ const __m128i rangeMatch = _mm_cvtsi32_si128(0xffff0100);
+ const __m128i offLimitMask = _mm_cmpestrm(rangeMatch, 2, chunk, 8, mode);
+
+ // replace the non-Latin 1 characters in the chunk with question marks
+ chunk = _mm_blendv_epi8(chunk, questionMark, offLimitMask);
+# else
// SSE has no compare instruction for unsigned comparison.
// The variables must be shiffted + 0x8000 to be compared
const __m128i signedBitOffset = _mm_set1_epi16(0x8000);
@@ -3603,6 +3625,7 @@ static inline __m128i mergeQuestionMarks(__m128i chunk)
// merge offLimitQuestionMark and correctBytes to have the result
chunk = _mm_or_si128(correctBytes, offLimitQuestionMark);
# endif
+# endif
return chunk;
}
#endif
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index c61d09e..bf0a0ad 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -639,6 +639,7 @@ private:
static Data *fromAscii_helper(const char *str, int size = -1);
void replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen);
friend class QCharRef;
+ friend class QCFString;
friend class QTextCodec;
friend class QStringRef;
friend struct QAbstractConcatenable;
diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h
index 8b46e6a..a59c08a 100644
--- a/src/dbus/qdbus_symbols_p.h
+++ b/src/dbus/qdbus_symbols_p.h
@@ -301,6 +301,8 @@ DEFINEFUNC(void , dbus_get_version , (int *major_version_p,
int *minor_version_p,
int *micro_version_p),
(major_version_p, minor_version_p, micro_version_p), )
+DEFINEFUNC(char* , dbus_get_local_machine_id , (void), (), return)
+
/* dbus-pending-call.h */
DEFINEFUNC(dbus_bool_t , dbus_pending_call_set_notify, (DBusPendingCall *pending,
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 58c1caa..0b4133c 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -1124,6 +1124,27 @@ void QDBusConnectionPrivate::setBusService(const QDBusConnection &connection)
}
/*!
+ \since 4.8
+ Returns the local machine ID as known to the D-Bus system. Each
+ node or host that runs D-Bus has a unique identifier that can be
+ used to distinguish it from other hosts if they are sharing
+ resources like the filesystem.
+
+ Note that the local machine ID is not guaranteed to be persistent
+ across boots of the system, so this identifier should not be
+ stored in persistent storage (like the filesystem). It is
+ guaranteed to remain constant only during the lifetime of this
+ boot session.
+*/
+QByteArray QDBusConnection::localMachineId()
+{
+ char *dbus_machine_id = q_dbus_get_local_machine_id();
+ QByteArray result = dbus_machine_id;
+ q_dbus_free(dbus_machine_id);
+ return result;
+}
+
+/*!
\namespace QDBus
\inmodule QtDBus
diff --git a/src/dbus/qdbusconnection.h b/src/dbus/qdbusconnection.h
index 19418d6..4bdd055 100644
--- a/src/dbus/qdbusconnection.h
+++ b/src/dbus/qdbusconnection.h
@@ -176,6 +176,8 @@ public:
static void disconnectFromBus(const QString &name);
static void disconnectFromPeer(const QString &name);
+ static QByteArray localMachineId();
+
static QDBusConnection sessionBus();
static QDBusConnection systemBus();
diff --git a/src/declarative/debugger/qdeclarativeinspectorservice.cpp b/src/declarative/debugger/qdeclarativeinspectorservice.cpp
index 9fec006..15dbf58 100644
--- a/src/declarative/debugger/qdeclarativeinspectorservice.cpp
+++ b/src/declarative/debugger/qdeclarativeinspectorservice.cpp
@@ -67,11 +67,13 @@ QDeclarativeInspectorService *QDeclarativeInspectorService::instance()
void QDeclarativeInspectorService::addView(QDeclarativeView *view)
{
m_views.append(view);
+ updateStatus();
}
void QDeclarativeInspectorService::removeView(QDeclarativeView *view)
{
m_views.removeAll(view);
+ updateStatus();
}
void QDeclarativeInspectorService::sendMessage(const QByteArray &message)
@@ -84,10 +86,18 @@ void QDeclarativeInspectorService::sendMessage(const QByteArray &message)
void QDeclarativeInspectorService::statusChanged(Status status)
{
- if (m_views.isEmpty())
+ updateStatus();
+}
+
+void QDeclarativeInspectorService::updateStatus()
+{
+ if (m_views.isEmpty()) {
+ if (m_inspectorPlugin)
+ m_inspectorPlugin->deactivate();
return;
+ }
- if (status == Enabled) {
+ if (status() == Enabled) {
if (!m_inspectorPlugin)
m_inspectorPlugin = loadInspectorPlugin();
diff --git a/src/declarative/debugger/qdeclarativeinspectorservice_p.h b/src/declarative/debugger/qdeclarativeinspectorservice_p.h
index 9fe0d601f..9a14155 100644
--- a/src/declarative/debugger/qdeclarativeinspectorservice_p.h
+++ b/src/declarative/debugger/qdeclarativeinspectorservice_p.h
@@ -78,6 +78,8 @@ protected:
virtual void messageReceived(const QByteArray &);
private:
+ void updateStatus();
+
static QDeclarativeInspectorInterface *loadInspectorPlugin();
QList<QDeclarativeView*> m_views;
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index bc9b6fd..d2897eb 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -1941,12 +1941,12 @@ void QDeclarativeTextInput::selectionChanged()
void QDeclarativeTextInput::q_textChanged()
{
Q_D(QDeclarativeTextInput);
+ emit textChanged();
+ emit displayTextChanged();
updateSize();
d->determineHorizontalAlignment();
d->updateHorizontalScroll();
updateMicroFocus();
- emit textChanged();
- emit displayTextChanged();
if(hasAcceptableInput() != d->oldValidity){
d->oldValidity = hasAcceptableInput();
emit acceptableInputChanged();
diff --git a/src/declarative/qml/qdeclarativebinding.cpp b/src/declarative/qml/qdeclarativebinding.cpp
index ca3bc37..689cd00 100644
--- a/src/declarative/qml/qdeclarativebinding.cpp
+++ b/src/declarative/qml/qdeclarativebinding.cpp
@@ -243,12 +243,13 @@ QDeclarativeBinding::createBinding(Identifier id, QObject *obj, QDeclarativeCont
if (id < 0)
return 0;
+ Q_ASSERT(ctxt);
QDeclarativeContextData *ctxtdata = QDeclarativeContextData::get(ctxt);
- QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(qmlEngine(obj));
+ QDeclarativeEnginePrivate *engine = QDeclarativeEnginePrivate::get(ctxtdata->engine);
QDeclarativeCompiledData *cdata = 0;
QDeclarativeTypeData *typeData = 0;
- if (engine && ctxtdata && !ctxtdata->url.isEmpty()) {
+ if (!ctxtdata->url.isEmpty()) {
typeData = engine->typeLoader.get(ctxtdata->url);
cdata = typeData->compiledData();
}
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index 885ce77..fb52274 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -553,9 +553,6 @@ void QFileDialogPrivate::QNSOpenSavePanelDelegate_filterSelected(int menuIndex)
emit q_func()->filterSelected(nameFilters.at(menuIndex));
}
-extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
-extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); // qglobal.cpp
-
void QFileDialogPrivate::setDirectory_sys(const QString &directory)
{
#ifndef QT_MAC_USE_COCOA
diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h
index 9b0d82e..15e7cab 100644
--- a/src/gui/egl/qegl_p.h
+++ b/src/gui/egl/qegl_p.h
@@ -165,13 +165,21 @@ typedef int EGLImageKHR;
typedef void *EGLImageKHR;
#endif
+#if !defined(EGL_NO_IMAGE_KHR)
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
+#endif
+#if !defined(EGL_IMAGE_PRESERVED_KHR)
#define EGL_IMAGE_PRESERVED_KHR 0x30D2
+#endif
+#if !defined(EGL_KHR_image_base)
#define EGL_KHR_image_base
#endif
+#endif
-#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_pixmap)
+#if !defined(EGL_KHR_image)
#define EGL_NATIVE_PIXMAP_KHR 0x30B0
+#endif
+#if !defined(EGL_KHR_image_pixmap)
#define EGL_KHR_image_pixmap
#endif
diff --git a/src/gui/embedded/embedded.pri b/src/gui/embedded/embedded.pri
index 31f0bc6..836c116 100644
--- a/src/gui/embedded/embedded.pri
+++ b/src/gui/embedded/embedded.pri
@@ -117,7 +117,7 @@ embedded {
contains( gfx-drivers, qnx ) {
HEADERS += embedded/qscreenqnx_qws.h
SOURCES += embedded/qscreenqnx_qws.cpp
- LIBS += -lgf
+ LIBS_PRIVATE += -lgf
}
contains( gfx-drivers, integrityfb ) {
diff --git a/src/gui/embedded/qkbdqnx_qws.cpp b/src/gui/embedded/qkbdqnx_qws.cpp
index 5a8118d..ad76446 100644
--- a/src/gui/embedded/qkbdqnx_qws.cpp
+++ b/src/gui/embedded/qkbdqnx_qws.cpp
@@ -40,16 +40,16 @@
****************************************************************************/
#include "qkbdqnx_qws.h"
-#include "QtCore/qsocketnotifier.h"
+
+#include "qplatformdefs.h"
+#include "qsocketnotifier.h"
+#include "private/qcore_unix_p.h"
#include "QtCore/qdebug.h"
#include <sys/dcmd_input.h>
-#include <photon/keycodes.h>
-
-#include "qplatformdefs.h"
+#include <sys/keycodes.h>
#include <errno.h>
-
QT_BEGIN_NAMESPACE
/*!
@@ -72,7 +72,7 @@ QT_BEGIN_NAMESPACE
Example invocation from command line: \c{/usr/photon/bin/devi-hid -Pr kbd mouse}
Note that after running \c{devi-hid}, you will not be able to use the local
- shell anymore. It is suggested to run the command in a shell scrip, that launches
+ shell anymore. It is suggested to run the command in a shell script, that launches
a Qt application after invocation of \c{devi-hid}.
To make \l{Qt for Embedded Linux} explicitly choose the qnx keyboard
@@ -100,15 +100,13 @@ QWSQnxKeyboardHandler::QWSQnxKeyboardHandler(const QString &device)
QT_OPEN_RDONLY);
if (keyboardFD == -1) {
qErrnoWarning(errno, "QWSQnxKeyboardHandler: Unable to open device");
- return;
- }
-
- // create a socket notifier so we'll wake up whenever keyboard input is detected.
- QSocketNotifier *notifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), SLOT(socketActivated()));
-
- qDebug() << "QWSQnxKeyboardHandler: connected.";
+ } else {
+ // create a socket notifier so we'll wake up whenever keyboard input is detected.
+ QSocketNotifier *notifier = new QSocketNotifier(keyboardFD, QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), SLOT(socketActivated()));
+ qDebug("QWSQnxKeyboardHandler: connected.");
+ }
}
/*!
@@ -116,7 +114,16 @@ QWSQnxKeyboardHandler::QWSQnxKeyboardHandler(const QString &device)
*/
QWSQnxKeyboardHandler::~QWSQnxKeyboardHandler()
{
- QT_CLOSE(keyboardFD);
+ if (keyboardFD != -1)
+ QT_CLOSE(keyboardFD);
+}
+
+// similar to PhKeyToMb
+static inline bool key_sym_displayable(unsigned long sym)
+{
+ if (sym >= 0xF000)
+ return sym >= 0xF100 && (sizeof(wchar_t) > 2 || sym < 0x10000);
+ return (sym & ~0x9F) != 0; // exclude 0...0x1F and 0x80...0x9F
}
/*! \internal
@@ -136,6 +143,11 @@ void QWSQnxKeyboardHandler::socketActivated()
// the bytes read must be the size of a keyboard packet
Q_ASSERT(bytesRead == sizeof(_keyboard_packet));
+ if (packet.data.flags & KEY_SYM_VALID_EX)
+ packet.data.flags |= KEY_SYM_VALID;
+ else if (!(packet.data.flags & (KEY_SYM_VALID | KEY_CAP_VALID)))
+ return;
+
#if 0
qDebug() << "keyboard got scancode"
<< hex << packet.data.modifiers
@@ -145,86 +157,157 @@ void QWSQnxKeyboardHandler::socketActivated()
<< packet.data.key_scan;
#endif
- // QNX is nice enough to translate the raw keyboard data into a QNX data structure
+ // QNX is nice enough to translate the raw keyboard data into generic format for us.
// Now we just have to translate it into a format Qt understands.
- // figure out whether it's a press
- bool isPress = packet.data.key_cap & KEY_DOWN;
- // figure out whether the key is still pressed and the key event is repeated
- bool isRepeat = packet.data.key_cap & KEY_REPEAT;
-
- Qt::Key key = Qt::Key_unknown;
- int unicode = 0xffff;
-
- // TODO - this switch is not complete!
- switch (packet.data.key_scan) {
- case KEYCODE_SPACE: key = Qt::Key_Space; unicode = 0x20; break;
- case KEYCODE_F1: key = Qt::Key_F1; break;
- case KEYCODE_F2: key = Qt::Key_F2; break;
- case KEYCODE_F3: key = Qt::Key_F3; break;
- case KEYCODE_F4: key = Qt::Key_F4; break;
- case KEYCODE_F5: key = Qt::Key_F5; break;
- case KEYCODE_F6: key = Qt::Key_F6; break;
- case KEYCODE_F7: key = Qt::Key_F7; break;
- case KEYCODE_F8: key = Qt::Key_F8; break;
- case KEYCODE_F9: key = Qt::Key_F9; break;
- case KEYCODE_F10: key = Qt::Key_F10; break;
- case KEYCODE_F11: key = Qt::Key_F11; break;
- case KEYCODE_F12: key = Qt::Key_F12; break;
- case KEYCODE_BACKSPACE: key = Qt::Key_Backspace; break;
- case KEYCODE_TAB: key = Qt::Key_Tab; break;
- case KEYCODE_RETURN: key = Qt::Key_Return; break;
- case KEYCODE_KP_ENTER: key = Qt::Key_Enter; break;
- case KEYCODE_UP:
- case KEYCODE_KP_UP:
- key = Qt::Key_Up; break;
- case KEYCODE_DOWN:
- case KEYCODE_KP_DOWN:
- key = Qt::Key_Down; break;
- case KEYCODE_LEFT:
- case KEYCODE_KP_LEFT:
- key = Qt::Key_Left; break;
- case KEYCODE_RIGHT:
- case KEYCODE_KP_RIGHT:
- key = Qt::Key_Right; break;
- case KEYCODE_HOME:
- case KEYCODE_KP_HOME:
- key = Qt::Key_Home; break;
- case KEYCODE_END:
- case KEYCODE_KP_END:
- key = Qt::Key_End; break;
- case KEYCODE_PG_UP:
- case KEYCODE_KP_PG_UP:
- key = Qt::Key_PageUp; break;
- case KEYCODE_PG_DOWN:
- case KEYCODE_KP_PG_DOWN:
- key = Qt::Key_PageDown; break;
- case KEYCODE_INSERT:
- case KEYCODE_KP_INSERT:
- key = Qt::Key_Insert; break;
- case KEYCODE_DELETE:
- case KEYCODE_KP_DELETE:
- key = Qt::Key_Delete; break;
- case KEYCODE_ESCAPE:
- key = Qt::Key_Escape; break;
- default: // none of the above, try the key_scan directly
- unicode = packet.data.key_scan;
- break;
- }
-
// figure out the modifiers that are currently pressed
Qt::KeyboardModifiers modifiers = Qt::NoModifier;
- if (packet.data.flags & KEYMOD_SHIFT)
+ if (packet.data.modifiers & KEYMOD_SHIFT)
modifiers |= Qt::ShiftModifier;
- if (packet.data.flags & KEYMOD_CTRL)
+ if (packet.data.modifiers & KEYMOD_CTRL)
modifiers |= Qt::ControlModifier;
- if (packet.data.flags & KEYMOD_ALT)
+ if (packet.data.modifiers & KEYMOD_ALT)
modifiers |= Qt::AltModifier;
+ if (packet.data.modifiers & KEYMOD_NUM_LOCK)
+ modifiers |= Qt::KeypadModifier;
+#if 0
+ // special case for AltGr
+ if (packet.data.modifiers & KEYMOD_ALTGR)
+ key = Qt::Key_AltGr;
+#endif
+
+ // figure out whether it's a press
+ bool isPress = packet.data.flags & KEY_DOWN;
+ // figure out whether the key is still pressed and the key event is repeated
+ bool isRepeat = packet.data.flags & KEY_REPEAT;
+
+ int key = Qt::Key_unknown;
+ int unicode = 0;
+
+ if (((packet.data.flags & KEY_SYM_VALID) && key_sym_displayable(unicode = packet.data.key_sym))
+ || ((packet.data.flags & KEY_CAP_VALID) && key_sym_displayable(unicode = packet.data.key_cap))) {
+ if (unicode <= 0x0ff) {
+ if (unicode >= 'a' && unicode <= 'z')
+ key = Qt::Key_A + unicode - 'a';
+ else
+ key = unicode;
+ }
+ // Ctrl<something> or Alt<something> is not a displayable character
+ if (modifiers & (Qt::ControlModifier | Qt::AltModifier))
+ unicode = 0;
+ } else {
+ unicode = 0;
+
+ unsigned long sym = 0;
+ if (packet.data.flags & KEY_SYM_VALID)
+ sym = packet.data.key_sym;
+ else if (packet.data.flags & KEY_CAP_VALID)
+ sym = packet.data.key_cap;
- // if the unicode value is not ascii, we ignore it.
- // TODO - do a complete mapping between all QNX scan codes and Qt codes
- if (unicode != 0xffff && !isascii(unicode))
- return; // unprintable character
+ switch (sym) {
+ case KEYCODE_ESCAPE: key = Qt::Key_Escape; unicode = 27; break;
+ case KEYCODE_TAB: key = Qt::Key_Tab; unicode = 9; break;
+ case KEYCODE_BACK_TAB: key = Qt::Key_Backtab; break;
+ case KEYCODE_BACKSPACE: key = Qt::Key_Backspace; unicode = 127; break;
+ case KEYCODE_RETURN: key = Qt::Key_Return; break;
+ case KEYCODE_KP_ENTER: key = Qt::Key_Enter; break;
+ case KEYCODE_INSERT:
+ case KEYCODE_KP_INSERT:
+ key = Qt::Key_Insert; break;
+ case KEYCODE_KP_DELETE:
+ if (modifiers & Qt::KeypadModifier) {
+ key = Qt::Key_Comma;
+ break;
+ }
+ // fall through
+ case KEYCODE_DELETE:
+ key = Qt::Key_Delete; break;
+ case KEYCODE_PAUSE:
+ case KEYCODE_BREAK:
+ if (modifiers & (Qt::ControlModifier | Qt::AltModifier))
+ return; // sometimes occurs at the middle of a key sequence
+ key = Qt::Key_Pause; break;
+ case KEYCODE_PRINT:
+ if (modifiers & (Qt::ControlModifier | Qt::AltModifier))
+ return; // sometimes occurs at the middle of a key sequence
+ key = Qt::Key_Print; break;
+ case KEYCODE_SYSREQ:
+ key = Qt::Key_SysReq; break;
+ case KEYCODE_HOME:
+ case KEYCODE_KP_HOME:
+ key = Qt::Key_Home; break;
+ case KEYCODE_END:
+ case KEYCODE_KP_END:
+ key = Qt::Key_End; break;
+ case KEYCODE_LEFT:
+ case KEYCODE_KP_LEFT:
+ key = Qt::Key_Left; break;
+ case KEYCODE_UP:
+ case KEYCODE_KP_UP:
+ key = Qt::Key_Up; break;
+ case KEYCODE_RIGHT:
+ case KEYCODE_KP_RIGHT:
+ key = Qt::Key_Right; break;
+ case KEYCODE_DOWN:
+ case KEYCODE_KP_DOWN:
+ key = Qt::Key_Down; break;
+ case KEYCODE_PG_UP:
+ case KEYCODE_KP_PG_UP:
+ key = Qt::Key_PageUp; break;
+ case KEYCODE_PG_DOWN:
+ case KEYCODE_KP_PG_DOWN:
+ key = Qt::Key_PageDown; break;
+
+ case KEYCODE_LEFT_SHIFT:
+ case KEYCODE_RIGHT_SHIFT:
+ key = Qt::Key_Shift; break;
+ case KEYCODE_LEFT_CTRL:
+ case KEYCODE_RIGHT_CTRL:
+ key = Qt::Key_Control; break;
+ case KEYCODE_LEFT_ALT:
+ case KEYCODE_RIGHT_ALT:
+ key = Qt::Key_Alt; break;
+ case KEYCODE_CAPS_LOCK:
+ key = Qt::Key_CapsLock; break;
+ case KEYCODE_NUM_LOCK:
+ key = Qt::Key_NumLock; break;
+ case KEYCODE_SCROLL_LOCK:
+ key = Qt::Key_ScrollLock; break;
+
+ case KEYCODE_F1:
+ case KEYCODE_F2:
+ case KEYCODE_F3:
+ case KEYCODE_F4:
+ case KEYCODE_F5:
+ case KEYCODE_F6:
+ case KEYCODE_F7:
+ case KEYCODE_F8:
+ case KEYCODE_F9:
+ case KEYCODE_F10:
+ case KEYCODE_F11:
+ case KEYCODE_F12:
+ key = Qt::Key_F1 + sym - KEYCODE_F1; break;
+
+ case KEYCODE_MENU: key = Qt::Key_Menu; break;
+ case KEYCODE_LEFT_HYPER: key = Qt::Key_Hyper_L; break;
+ case KEYCODE_RIGHT_HYPER: key = Qt::Key_Hyper_R; break;
+
+ case KEYCODE_KP_PLUS: key = Qt::Key_Plus; break;
+ case KEYCODE_KP_MINUS: key = Qt::Key_Minus; break;
+ case KEYCODE_KP_MULTIPLY: key = Qt::Key_multiply; break;
+ case KEYCODE_KP_DIVIDE: key = Qt::Key_Slash; break;
+ case KEYCODE_KP_FIVE:
+ if (!(modifiers & Qt::KeypadModifier))
+ key = Qt::Key_5;
+ break;
+
+ default: // none of the above
+ break;
+ }
+ }
+
+ if (key == Qt::Key_unknown && unicode == 0)
+ return;
// call processKeyEvent. This is where all the magic happens to insert a
// key event into Qt's event loop.
diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp
index ac15431..eaad15c 100644
--- a/src/gui/embedded/qlock.cpp
+++ b/src/gui/embedded/qlock.cpp
@@ -41,7 +41,6 @@
#include "qlock_p.h"
-
#ifdef QT_NO_QWS_MULTIPROCESS
QT_BEGIN_NAMESPACE
@@ -83,7 +82,7 @@ QT_END_NAMESPACE
#else // QT_NO_QWS_MULTIPROCESS
#if defined(Q_OS_DARWIN)
-# define Q_NO_SEMAPHORE
+# define QT_NO_SEMAPHORE
#endif
#include "qwssignalhandler_p.h"
@@ -91,11 +90,13 @@ QT_END_NAMESPACE
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
-#if defined(Q_NO_SEMAPHORE)
+#if defined(QT_NO_SEMAPHORE)
# include <sys/stat.h>
# include <sys/file.h>
-#else
+#elif !defined(QT_POSIX_IPC)
# include <sys/sem.h>
+#else
+# include <semaphore.h>
#endif
#include <string.h>
#include <errno.h>
@@ -109,17 +110,24 @@ QT_BEGIN_NAMESPACE
class QLockData
{
public:
-#ifdef Q_NO_SEMAPHORE
+#if defined(QT_NO_SEMAPHORE) || defined(QT_POSIX_IPC)
QByteArray file;
-#endif // Q_NO_SEMAPHORE
+#endif
+#if !defined(QT_POSIX_IPC)
int id;
+#else
+ sem_t *id; // Read mode resource counter
+ sem_t *rsem; // Read mode lock
+ sem_t *wsem; // Write mode lock
+#endif
int count;
bool owned;
};
+
/*!
\class QLock
- \brief The QLock class is a wrapper for a System V shared semaphore.
+ \brief The QLock class is a wrapper for a system shared semaphore.
\ingroup qws
@@ -148,7 +156,7 @@ QLock::QLock(const QString &filename, char id, bool create)
{
data = new QLockData;
data->count = 0;
-#ifdef Q_NO_SEMAPHORE
+#if defined(QT_NO_SEMAPHORE)
data->file = filename.toLocal8Bit() + id;
for (int x = 0; x < 2; ++x) {
data->id = QT_OPEN(data->file.constData(), O_RDWR | (x ? O_CREAT : 0), S_IRWXU);
@@ -157,7 +165,7 @@ QLock::QLock(const QString &filename, char id, bool create)
break;
}
}
-#else
+#elif !defined(QT_POSIX_IPC)
key_t semkey = ftok(filename.toLocal8Bit().constData(), id);
data->id = semget(semkey, 0, 0);
data->owned = create;
@@ -170,6 +178,28 @@ QLock::QLock(const QString &filename, char id, bool create)
arg.val = MAX_LOCKS;
semctl(data->id, 0, SETVAL, arg);
}
+#else
+ data->file = filename.toLocal8Bit() + id;
+ data->owned = create;
+
+ char ids[3] = { 'c', 'r', 'w' };
+ sem_t **sems[3] = { &data->id, &data->rsem, &data->wsem };
+ unsigned short initialValues[3] = { MAX_LOCKS, 1, 1 };
+ for (int i = 0; i < 3; ++i) {
+ QByteArray file = data->file + ids[i];
+ do {
+ *sems[i] = sem_open(file.constData(), 0, 0666, 0);
+ } while (*sems[i] == SEM_FAILED && errno == EINTR);
+ if (create) {
+ if (*sems[i] != SEM_FAILED) {
+ sem_close(*sems[i]);
+ sem_unlink(file.constData());
+ }
+ do {
+ *sems[i] = sem_open(file.constData(), O_CREAT, 0666, initialValues[i]);
+ } while (*sems[i] == SEM_FAILED && errno == EINTR);
+ }
+ }
#endif
if (!isValid()) {
qWarning("QLock::QLock: Cannot %s semaphore %s '%c' (%d, %s)",
@@ -193,17 +223,32 @@ QLock::~QLock()
while (locked())
unlock();
-#ifdef Q_NO_SEMAPHORE
+
+#if defined(QT_NO_SEMAPHORE)
if (isValid())
QT_CLOSE(data->id);
+#elif defined(QT_POSIX_IPC)
+ if (data->id != SEM_FAILED)
+ sem_close(data->id);
+ if (data->rsem != SEM_FAILED)
+ sem_close(data->rsem);
+ if (data->wsem != SEM_FAILED)
+ sem_close(data->wsem);
#endif
+
if (data->owned) {
-#ifdef Q_NO_SEMAPHORE
+#if defined(QT_NO_SEMAPHORE)
unlink(data->file.constData());
-#else
+#elif !defined(QT_POSIX_IPC)
qt_semun semval;
semval.val = 0;
semctl(data->id, 0, IPC_RMID, semval);
+#else
+ char ids[3] = { 'c', 'r', 'w' };
+ for (int i = 0; i < 3; ++i) {
+ QByteArray file = data->file + ids[i];
+ sem_unlink(file.constData());
+ }
#endif
}
delete data;
@@ -216,7 +261,11 @@ QLock::~QLock()
*/
bool QLock::isValid() const
{
+#if !defined(QT_POSIX_IPC)
return data && data->id != -1;
+#else
+ return data && data->id != SEM_FAILED && data->rsem != SEM_FAILED && data->wsem != SEM_FAILED;
+#endif
}
/*!
@@ -232,21 +281,48 @@ bool QLock::isValid() const
*/
void QLock::lock(Type t)
{
+ if (!isValid())
+ return;
+
if (!data->count) {
type = t;
int rv;
-#ifdef Q_NO_SEMAPHORE
+#if defined(QT_NO_SEMAPHORE)
int op = type == Write ? LOCK_EX : LOCK_SH;
EINTR_LOOP(rv, flock(data->id, op));
-#else
+#elif !defined(QT_POSIX_IPC)
sembuf sops;
sops.sem_num = 0;
sops.sem_op = type == Write ? -MAX_LOCKS : -1;
sops.sem_flg = SEM_UNDO;
EINTR_LOOP(rv, semop(data->id, &sops, 1));
+#else
+ if (type == Write) {
+ EINTR_LOOP(rv, sem_wait(data->rsem));
+ if (rv != -1) {
+ EINTR_LOOP(rv, sem_wait(data->wsem));
+ if (rv == -1)
+ sem_post(data->rsem);
+ }
+ } else {
+ EINTR_LOOP(rv, sem_wait(data->wsem));
+ if (rv != -1) {
+ EINTR_LOOP(rv, sem_trywait(data->rsem));
+ if (rv != -1 || errno == EAGAIN) {
+ EINTR_LOOP(rv, sem_wait(data->id));
+ if (rv == -1) {
+ int semval;
+ sem_getvalue(data->id, &semval);
+ if (semval == MAX_LOCKS)
+ sem_post(data->rsem);
+ }
+ }
+ rv = sem_post(data->wsem);
+ }
+ }
#endif
if (rv == -1) {
qDebug("QLock::lock(): %s", strerror(errno));
@@ -265,19 +341,37 @@ void QLock::lock(Type t)
*/
void QLock::unlock()
{
- if (data->count) {
+ if (!isValid())
+ return;
+
+ if (data->count > 0) {
data->count--;
if (!data->count) {
int rv;
-#ifdef Q_NO_SEMAPHORE
+#if defined(QT_NO_SEMAPHORE)
EINTR_LOOP(rv, flock(data->id, LOCK_UN));
-#else
+#elif !defined(QT_POSIX_IPC)
sembuf sops;
sops.sem_num = 0;
sops.sem_op = type == Write ? MAX_LOCKS : 1;
sops.sem_flg = SEM_UNDO;
EINTR_LOOP(rv, semop(data->id, &sops, 1));
+#else
+ if (type == Write) {
+ sem_post(data->wsem);
+ rv = sem_post(data->rsem);
+ } else {
+ EINTR_LOOP(rv, sem_wait(data->wsem));
+ if (rv != -1) {
+ sem_post(data->id);
+ int semval;
+ sem_getvalue(data->id, &semval);
+ if (semval == MAX_LOCKS)
+ sem_post(data->rsem);
+ rv = sem_post(data->wsem);
+ }
+ }
#endif
if (rv == -1)
qDebug("QLock::unlock(): %s", strerror(errno));
diff --git a/src/gui/embedded/qmouselinuxinput_qws.cpp b/src/gui/embedded/qmouselinuxinput_qws.cpp
index efcf6d4..19a9a99 100644
--- a/src/gui/embedded/qmouselinuxinput_qws.cpp
+++ b/src/gui/embedded/qmouselinuxinput_qws.cpp
@@ -135,19 +135,21 @@ void QWSLinuxInputMousePrivate::readMouseData()
int n = 0;
forever {
- n = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
-
- if (n == 0) {
+ int bytesRead = QT_READ(m_fd, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
+ if (bytesRead == 0) {
qWarning("Got EOF from the input device.");
return;
- } else if (n < 0 && (errno != EINTR && errno != EAGAIN)) {
- qWarning("Could not read from input device: %s", strerror(errno));
- return;
- } else if (n % sizeof(buffer[0]) == 0) {
+ }
+ if (bytesRead == -1) {
+ if (errno != EAGAIN)
+ qWarning("Could not read from input device: %s", strerror(errno));
break;
}
- }
+ n += bytesRead;
+ if (n % sizeof(buffer[0]) == 0)
+ break;
+ }
n /= sizeof(buffer[0]);
for (int i = 0; i < n; ++i) {
diff --git a/src/gui/embedded/qmouseqnx_qws.cpp b/src/gui/embedded/qmouseqnx_qws.cpp
index a9647c0..d0b892e 100644
--- a/src/gui/embedded/qmouseqnx_qws.cpp
+++ b/src/gui/embedded/qmouseqnx_qws.cpp
@@ -39,14 +39,13 @@
**
****************************************************************************/
-#include "qplatformdefs.h"
#include "qmouseqnx_qws.h"
+#include "qplatformdefs.h"
#include "qsocketnotifier.h"
-#include "qdebug.h"
+#include "private/qcore_unix_p.h"
#include <sys/dcmd_input.h>
-
#include <errno.h>
QT_BEGIN_NAMESPACE
@@ -92,22 +91,28 @@ QT_BEGIN_NAMESPACE
\sa QMouseDriverFactory
*/
-QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &device)
+QQnxMouseHandler::QQnxMouseHandler(const QString & driver, const QString &device)
+ : QObject(), QWSMouseHandler(driver, device), mouseButtons(Qt::NoButton)
{
// open the mouse device with O_NONBLOCK so reading won't block when there's no data
mouseFD = QT_OPEN(device.isEmpty() ? "/dev/devi/mouse0" : device.toLatin1().constData(),
- QT_OPEN_RDONLY | O_NONBLOCK);
+ QT_OPEN_RDONLY | O_NONBLOCK);
if (mouseFD == -1) {
qErrnoWarning(errno, "QQnxMouseHandler: Unable to open mouse device");
- return;
+ } else {
+ struct _pointer_info data;
+ if (devctl(mouseFD, _POINTERGETINFO, &data, sizeof(data), NULL) == EOK)
+ absolutePositioning = (data.flags & _POINTER_FLAG_ABSOLUTE);
+ else
+ absolutePositioning = !device.isEmpty() && device.contains(QLatin1String("touch"));
+
+ // register a socket notifier on the file descriptor so we'll wake up whenever
+ // there's a mouse move waiting for us.
+ mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
+ connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated()));
+
+ qDebug("QQnxMouseHandler: connected.");
}
-
- // register a socket notifier on the file descriptor so we'll wake up whenever
- // there's a mouse move waiting for us.
- mouseNotifier = new QSocketNotifier(mouseFD, QSocketNotifier::Read, this);
- connect(mouseNotifier, SIGNAL(activated(int)), SLOT(socketActivated()));
-
- qDebug() << "QQnxMouseHandler: connected.";
}
/*!
@@ -115,7 +120,8 @@ QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &de
*/
QQnxMouseHandler::~QQnxMouseHandler()
{
- QT_CLOSE(mouseFD);
+ if (mouseFD != -1)
+ QT_CLOSE(mouseFD);
}
/*! \reimp */
@@ -140,39 +146,45 @@ void QQnxMouseHandler::suspend()
*/
void QQnxMouseHandler::socketActivated()
{
+ QPoint queuedPos = mousePos;
+
// _mouse_packet is a QNX structure. devi-hid is nice enough to translate
// the raw byte data from mouse devices into generic format for us.
- _mouse_packet packet;
+ struct _mouse_packet buffer[32];
+ int n = 0;
- int iteration = 0;
-
- // read mouse events in batches of 10. Since we're getting quite a lot
- // of mouse events, it's better to do them in batches than to return to the
- // event loop every time.
- do {
- int bytesRead = QT_READ(mouseFD, &packet, sizeof(packet));
+ forever {
+ int bytesRead = QT_READ(mouseFD, reinterpret_cast<char *>(buffer) + n, sizeof(buffer) - n);
if (bytesRead == -1) {
// EAGAIN means that there are no more mouse events to read
if (errno != EAGAIN)
- qErrnoWarning(errno, "QQnxMouseHandler: Unable to read from socket");
- return;
+ qErrnoWarning(errno, "QQnxMouseHandler: Could not read from input device");
+ break;
}
- // bytes read should always be equal to the size of a packet.
- Q_ASSERT(bytesRead == sizeof(packet));
+ n += bytesRead;
+ if (n % sizeof(buffer[0]) == 0)
+ break;
+ }
+ n /= sizeof(buffer[0]);
- // translate the coordinates from the QNX data structure to Qt coordinates
- // note the swapped y axis
- QPoint pos = mousePos;
- pos += QPoint(packet.dx, -packet.dy);
+ for (int i = 0; i < n; ++i) {
+ const struct _mouse_packet &packet = buffer[i];
- // QNX only tells us relative mouse movements, not absolute ones, so limit the
- // cursor position manually to the screen
- limitToScreen(pos);
+ // translate the coordinates from the QNX data structure to the Qt coordinates
+ if (absolutePositioning) {
+ queuedPos = QPoint(packet.dx, packet.dy);
+ } else {
+ // note the swapped y axis
+ queuedPos += QPoint(packet.dx, -packet.dy);
+
+ // QNX only tells us relative mouse movements, not absolute ones, so
+ // limit the cursor position manually to the screen
+ limitToScreen(queuedPos);
+ }
// translate the QNX mouse button bitmask to Qt buttons
int buttons = Qt::NoButton;
-
if (packet.hdr.buttons & _POINTER_BUTTON_LEFT)
buttons |= Qt::LeftButton;
if (packet.hdr.buttons & _POINTER_BUTTON_MIDDLE)
@@ -180,11 +192,17 @@ void QQnxMouseHandler::socketActivated()
if (packet.hdr.buttons & _POINTER_BUTTON_RIGHT)
buttons |= Qt::RightButton;
- // call mouseChanged() - this does all the magic to actually move the on-screen
- // mouse cursor.
- mouseChanged(pos, buttons, 0);
- } while (++iteration < 11);
+ if (buttons != mouseButtons) {
+ // send the MouseEvent to avoid missing any clicks
+ mouseChanged(queuedPos, buttons, 0);
+ // mousePos updated by the mouseChanged()
+ queuedPos = mousePos;
+ mouseButtons = buttons;
+ }
+ }
+
+ if (queuedPos != mousePos)
+ mouseChanged(queuedPos, mouseButtons, 0);
}
QT_END_NAMESPACE
-
diff --git a/src/gui/embedded/qmouseqnx_qws.h b/src/gui/embedded/qmouseqnx_qws.h
index 2a5eef2..54deaf3 100644
--- a/src/gui/embedded/qmouseqnx_qws.h
+++ b/src/gui/embedded/qmouseqnx_qws.h
@@ -70,6 +70,8 @@ private Q_SLOTS:
private:
QSocketNotifier *mouseNotifier;
int mouseFD;
+ int mouseButtons;
+ bool absolutePositioning;
};
QT_END_NAMESPACE
diff --git a/src/gui/embedded/qscreen_qws.h b/src/gui/embedded/qscreen_qws.h
index 2ecc6e7..5ff90f9 100644
--- a/src/gui/embedded/qscreen_qws.h
+++ b/src/gui/embedded/qscreen_qws.h
@@ -44,7 +44,7 @@
#include <QtCore/qnamespace.h>
#include <QtCore/qpoint.h>
-#include <QtCore/qlist.h>
+#include <QtCore/qstringlist.h>
#include <QtGui/qrgb.h>
#include <QtCore/qrect.h>
#include <QtGui/qimage.h>
@@ -357,6 +357,7 @@ private:
friend class QVNCScreen;
friend class QLinuxFbScreen;
friend class QVFbScreen;
+ friend class QQnxScreen;
friend class QProxyScreen;
friend class QIntfbScreen;
#endif
diff --git a/src/gui/embedded/qscreenqnx_qws.cpp b/src/gui/embedded/qscreenqnx_qws.cpp
index 4afe087..d34e732 100644
--- a/src/gui/embedded/qscreenqnx_qws.cpp
+++ b/src/gui/embedded/qscreenqnx_qws.cpp
@@ -40,7 +40,9 @@
****************************************************************************/
#include "qscreenqnx_qws.h"
-#include "qdebug.h"
+
+#include <qapplication.h>
+#include <qregexp.h>
#include <gf/gf.h>
@@ -52,6 +54,10 @@ struct QQnxScreenContext
inline QQnxScreenContext()
: device(0), display(0), layer(0), hwSurface(0), memSurface(0), context(0)
{}
+ inline ~QQnxScreenContext()
+ { cleanup(); }
+
+ void cleanup();
gf_dev_t device;
gf_dev_info_t deviceInfo;
@@ -64,6 +70,35 @@ struct QQnxScreenContext
gf_context_t context;
};
+void QQnxScreenContext::cleanup()
+{
+ if (context) {
+ gf_context_free(context);
+ context = 0;
+ }
+ if (memSurface) {
+ gf_surface_free(memSurface);
+ memSurface = 0;
+ }
+ if (hwSurface) {
+ gf_surface_free(hwSurface);
+ hwSurface = 0;
+ }
+ if (layer) {
+ gf_layer_detach(layer);
+ layer = 0;
+ }
+ if (display) {
+ gf_display_detach(display);
+ display = 0;
+ }
+ if (device) {
+ gf_dev_detach(device);
+ device = 0;
+ }
+}
+
+
/*!
\class QQnxScreen
\preliminary
@@ -117,19 +152,23 @@ QQnxScreen::~QQnxScreen()
delete d;
}
-/*! \reimp
+/*!
+ \reimp
*/
bool QQnxScreen::initDevice()
{
- // implement this if you have multiple processes that want to access the display
- // (not required if QT_NO_QWS_MULTIPROCESS is set)
+#ifndef QT_NO_QWS_CURSOR
+ QScreenCursor::initSoftwareCursor();
+#endif
+
return true;
}
-/*! \internal
- Attaches to the named device \a name.
+/*!
+ \internal
+ Attaches to the named device \a name.
*/
-static bool attachDevice(QQnxScreenContext * const d, const char *name)
+static inline bool attachDevice(QQnxScreenContext * const d, const char *name)
{
int ret = gf_dev_attach(&d->device, name, &d->deviceInfo);
if (ret != GF_ERR_OK) {
@@ -139,193 +178,231 @@ static bool attachDevice(QQnxScreenContext * const d, const char *name)
return true;
}
-/*! \internal
- Attaches to the display at index \a displayIndex.
- */
-static bool attachDisplay(QQnxScreenContext * const d, int displayIndex)
+/*!
+ \internal
+ Attaches to the display at index \a displayIndex.
+*/
+static inline bool attachDisplay(QQnxScreenContext * const d, int displayIndex)
{
int ret = gf_display_attach(&d->display, d->device, displayIndex, &d->displayInfo);
if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_display_attach(%d) failed with error code %d",
- displayIndex, ret);
+ qWarning("QQnxScreen: gf_display_attach(%d) failed with error code %d", displayIndex, ret);
return false;
}
return true;
}
-/*! \internal
- Attaches to the layer \a layerIndex.
- */
-static bool attachLayer(QQnxScreenContext * const d, int layerIndex)
+/*!
+ \internal
+ Attaches to the layer \a layerIndex.
+*/
+static inline bool attachLayer(QQnxScreenContext * const d, int layerIndex)
{
- int ret = gf_layer_attach(&d->layer, d->display, layerIndex, 0);
+ unsigned flags = QApplication::type() != QApplication::GuiServer ? GF_LAYER_ATTACH_PASSIVE : 0;
+ int ret = gf_layer_attach(&d->layer, d->display, layerIndex, flags);
if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_layer_attach(%d) failed with error code %d", layerIndex,
- ret);
+ qWarning("QQnxScreen: gf_layer_attach(%d) failed with error code %d", layerIndex, ret);
return false;
}
- gf_layer_enable(d->layer);
return true;
}
-/*! \internal
- Creates a new hardware surface (usually on the Gfx card memory) with the dimensions \a w * \a h.
- */
-static bool createHwSurface(QQnxScreenContext * const d, int w, int h)
+/*!
+ \internal
+ Creates a new hardware surface (usually on the Gfx card memory) with the dimensions \a w * \a h.
+*/
+static inline bool createHwSurface(QQnxScreenContext * const d, int w, int h)
{
int ret = gf_surface_create_layer(&d->hwSurface, &d->layer, 1, 0,
- w, h, GF_FORMAT_ARGB8888, 0, 0);
+ w, h, d->displayInfo.format, 0, 0);
if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_surface_create_layer(%dx%d) failed with error code %d",
- w, h, ret);
+ qWarning("QQnxScreen: gf_surface_create_layer(%dx%d) failed with error code %d", w, h, ret);
return false;
}
gf_layer_set_surfaces(d->layer, &d->hwSurface, 1);
+ gf_layer_enable(d->layer);
+
ret = gf_layer_update(d->layer, 0);
if (ret != GF_ERR_OK) {
qWarning("QQnxScreen: gf_layer_update() failed with error code %d\n", ret);
return false;
}
- return true;
-}
-
-/*! \internal
- Creates an in-memory, linear accessible surface of dimensions \a w * \a h.
- This is the main surface that QWS blits to.
- */
-static bool createMemSurface(QQnxScreenContext * const d, int w, int h)
-{
- // Note: gf_surface_attach() could also be used, so we'll create the buffer
- // and let the surface point to it. Here, we use surface_create instead.
-
- int ret = gf_surface_create(&d->memSurface, d->device, w, h,
- GF_FORMAT_ARGB8888, 0,
- GF_SURFACE_CREATE_CPU_FAST_ACCESS | GF_SURFACE_CREATE_CPU_LINEAR_ACCESSIBLE
- | GF_SURFACE_PHYS_CONTIG | GF_SURFACE_CREATE_SHAREABLE);
+ ret = gf_context_create(&d->context);
if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_surface_create(%dx%d) failed with error code %d",
- w, h, ret);
+ qWarning("QQnxScreen: gf_context_create() failed with error code %d", ret);
return false;
}
- gf_surface_get_info(d->memSurface, &d->memSurfaceInfo);
-
- if (d->memSurfaceInfo.sid == unsigned(GF_SID_INVALID)) {
- qWarning("QQnxScreen: gf_surface_get_info() failed.");
+ ret = gf_context_set_surface(d->context, d->hwSurface);
+ if (ret != GF_ERR_OK) {
+ qWarning("QQnxScreen: gf_context_set_surface() failed with error code %d", ret);
return false;
}
return true;
}
-/* \internal
- Creates a QNX gf context and sets our memory surface on it.
- */
-static bool createContext(QQnxScreenContext * const d)
+/*!
+ \internal
+ Creates an in-memory, linear accessible surface of dimensions \a w * \a h.
+ This is the main surface that QWS blits to.
+*/
+static inline bool createMemSurface(QQnxScreenContext * const d, int w, int h)
{
- int ret = gf_context_create(&d->context);
+#ifndef QT_NO_QWS_MULTIPROCESS
+ if (QApplication::type() != QApplication::GuiServer) {
+ unsigned sidlist[64];
+ int n = gf_surface_sidlist(d->device, sidlist); // undocumented API
+ for (int i = 0; i < n; ++i) {
+ int ret = gf_surface_attach_by_sid(&d->memSurface, d->device, sidlist[i]);
+ if (ret == GF_ERR_OK) {
+ gf_surface_get_info(d->memSurface, &d->memSurfaceInfo);
+ if (d->memSurfaceInfo.sid != unsigned(GF_SID_INVALID)) {
+ // can we use the surface's vaddr?
+ unsigned flags = GF_SURFACE_CPU_LINEAR_READABLE | GF_SURFACE_CPU_LINEAR_WRITEABLE;
+ if ((d->memSurfaceInfo.flags & flags) == flags)
+ return true;
+ }
+
+ gf_surface_free(d->memSurface);
+ d->memSurface = 0;
+ }
+ }
+ qWarning("QQnxScreen: cannot attach to an usable surface; create a new one.");
+ }
+#endif
+ int ret = gf_surface_create(&d->memSurface, d->device, w, h, d->displayInfo.format, 0,
+ GF_SURFACE_CREATE_CPU_FAST_ACCESS | GF_SURFACE_CREATE_CPU_LINEAR_ACCESSIBLE
+ | GF_SURFACE_CREATE_PHYS_CONTIG | GF_SURFACE_CREATE_SHAREABLE);
if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_context_create() failed with error code %d", ret);
+ qWarning("QQnxScreen: gf_surface_create(%dx%d) failed with error code %d",
+ w, h, ret);
return false;
}
- ret = gf_context_set_surface(d->context, d->memSurface);
- if (ret != GF_ERR_OK) {
- qWarning("QQnxScreen: gf_context_set_surface() failed with error code %d", ret);
+ gf_surface_get_info(d->memSurface, &d->memSurfaceInfo);
+
+ if (d->memSurfaceInfo.sid == unsigned(GF_SID_INVALID)) {
+ qWarning("QQnxScreen: gf_surface_get_info() failed.");
return false;
}
return true;
}
-/*! \reimp
- Connects to QNX's io-display based device based on the \a displaySpec parameters
- from the \c{QWS_DISPLAY} environment variable. See the QQnxScreen class documentation
- for possible parameters.
+/*!
+ \reimp
+ Connects to QNX's io-display based device based on the \a displaySpec parameters
+ from the \c{QWS_DISPLAY} environment variable. See the QQnxScreen class documentation
+ for possible parameters.
- \sa QQnxScreen
- */
+ \sa QQnxScreen
+*/
bool QQnxScreen::connect(const QString &displaySpec)
{
const QStringList params = displaySpec.split(QLatin1Char(':'), QString::SkipEmptyParts);
- bool isOk = false;
- QRegExp deviceRegExp(QLatin1String("^device=(.+)$"));
- if (params.indexOf(deviceRegExp) != -1) {
- isOk = attachDevice(d, deviceRegExp.cap(1).toLocal8Bit().constData());
- } else {
- // no device specified - attach to device 0 (the default)
- isOk = attachDevice(d, GF_DEVICE_INDEX(0));
+ // default to device 0
+ int deviceIndex = 0;
+ if (!params.isEmpty()) {
+ QRegExp deviceRegExp(QLatin1String("^device=(.+)$"));
+ if (params.indexOf(deviceRegExp) != -1)
+ deviceIndex = deviceRegExp.cap(1).toInt();
}
- if (!isOk)
+ if (!attachDevice(d, GF_DEVICE_INDEX(deviceIndex)))
return false;
qDebug("QQnxScreen: Attached to Device, number of displays: %d", d->deviceInfo.ndisplays);
- // default to display 0
- int displayIndex = 0;
- QRegExp displayRegexp(QLatin1String("^display=(\\d+)$"));
- if (params.indexOf(displayRegexp) != -1) {
- displayIndex = displayRegexp.cap(1).toInt();
+ // default to display id passed to constructor
+ int displayIndex = displayId;
+ if (!params.isEmpty()) {
+ QRegExp displayRegexp(QLatin1String("^display=(\\d+)$"));
+ if (params.indexOf(displayRegexp) != -1)
+ displayIndex = displayRegexp.cap(1).toInt();
}
if (!attachDisplay(d, displayIndex))
return false;
qDebug("QQnxScreen: Attached to Display %d, resolution %dx%d, refresh %d Hz",
- displayIndex, d->displayInfo.xres, d->displayInfo.yres,
- d->displayInfo.refresh);
-
+ displayIndex, d->displayInfo.xres, d->displayInfo.yres, d->displayInfo.refresh);
// default to main_layer_index from the displayInfo struct
- int layerIndex = 0;
- QRegExp layerRegexp(QLatin1String("^layer=(\\d+)$"));
- if (params.indexOf(layerRegexp) != -1) {
- layerIndex = layerRegexp.cap(1).toInt();
- } else {
- layerIndex = d->displayInfo.main_layer_index;
+ int layerIndex = d->displayInfo.main_layer_index;
+ if (!params.isEmpty()) {
+ QRegExp layerRegexp(QLatin1String("^layer=(\\d+)$"));
+ if (params.indexOf(layerRegexp) != -1)
+ layerIndex = layerRegexp.cap(1).toInt();
}
if (!attachLayer(d, layerIndex))
return false;
+ // determine the pixel format and the pixel type
+ switch (d->displayInfo.format) {
+#if defined(QT_QWS_DEPTH_32) || defined(QT_QWS_DEPTH_GENERIC)
+ case GF_FORMAT_ARGB8888:
+ pixeltype = QScreen::BGRPixel;
+ // fall through
+ case GF_FORMAT_BGRA8888:
+ setPixelFormat(QImage::Format_ARGB32);
+ break;
+#endif
+#if defined(QT_QWS_DEPTH_24)
+ case GF_FORMAT_BGR888:
+ pixeltype = QScreen::BGRPixel;
+ setPixelFormat(QImage::Format_RGB888);
+ break;
+#endif
+#if defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_GENERIC)
+ case GF_FORMAT_PACK_RGB565:
+ case GF_FORMAT_PKLE_RGB565:
+ case GF_FORMAT_PKBE_RGB565:
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ setFrameBufferLittleEndian((d->displayInfo.format & GF_FORMAT_PKLE) == GF_FORMAT_PKLE);
+#endif
+ setPixelFormat(QImage::Format_RGB16);
+ break;
+#endif
+ default:
+ return false;
+ }
+
// tell QWSDisplay the width and height of the display
w = dw = d->displayInfo.xres;
h = dh = d->displayInfo.yres;
-
- // we only support 32 bit displays for now.
- QScreen::d = 32;
+ QScreen::d = (d->displayInfo.format & GF_FORMAT_BPP); // colour depth
// assume 72 dpi as default, to calculate the physical dimensions if not specified
const int defaultDpi = 72;
-
- // Handle display physical size spec.
- QRegExp mmWidthRegexp(QLatin1String("^mmWidth=(\\d+)$"));
- if (params.indexOf(mmWidthRegexp) == -1) {
- physWidth = qRound(dw * 25.4 / defaultDpi);
- } else {
- physWidth = mmWidthRegexp.cap(1).toInt();
+ // Handle display physical size
+ physWidth = qRound(dw * 25.4 / defaultDpi);
+ physHeight = qRound(dh * 25.4 / defaultDpi);
+ if (!params.isEmpty()) {
+ QRegExp mmWidthRegexp(QLatin1String("^mmWidth=(\\d+)$"));
+ if (params.indexOf(mmWidthRegexp) != -1)
+ physWidth = mmWidthRegexp.cap(1).toInt();
+
+ QRegExp mmHeightRegexp(QLatin1String("^mmHeight=(\\d+)$"));
+ if (params.indexOf(mmHeightRegexp) != -1)
+ physHeight = mmHeightRegexp.cap(1).toInt();
}
- QRegExp mmHeightRegexp(QLatin1String("^mmHeight=(\\d+)$"));
- if (params.indexOf(mmHeightRegexp) == -1) {
- physHeight = qRound(dh * 25.4 / defaultDpi);
- } else {
- physHeight = mmHeightRegexp.cap(1).toInt();
+ if (QApplication::type() == QApplication::GuiServer) {
+ // create a hardware surface with our dimensions. In the old days, it was possible
+ // to get a pointer directly to the hw surface, so we could blit directly. Now, we
+ // have to use one indirection more, because it's not guaranteed that the hw surface
+ // is mappable into our process.
+ if (!createHwSurface(d, w, h))
+ return false;
}
- // create a hardware surface with our dimensions. In the old days, it was possible
- // to get a pointer directly to the hw surface, so we could blit directly. Now, we
- // have to use one indirection more, because it's not guaranteed that the hw surface
- // is mappable into our process.
- if (!createHwSurface(d, w, h))
- return false;
-
// create an in-memory linear surface that is used by QWS. QWS will blit directly in here.
if (!createMemSurface(d, w, h))
return false;
@@ -338,72 +415,84 @@ bool QQnxScreen::connect(const QString &displaySpec)
// the overall size of the in-memory buffer is linestep * height
size = mapsize = lstep * h;
- // create a QNX drawing context
- if (!createContext(d))
- return false;
-
- // we're always using a software cursor for now. Initialize it here.
- QScreenCursor::initSoftwareCursor();
-
// done, the driver should be connected to the display now.
return true;
}
-/*! \reimp
- */
+/*!
+ \reimp
+*/
void QQnxScreen::disconnect()
{
- if (d->context)
- gf_context_free(d->context);
-
- if (d->memSurface)
- gf_surface_free(d->memSurface);
-
- if (d->hwSurface)
- gf_surface_free(d->hwSurface);
-
- if (d->layer)
- gf_layer_detach(d->layer);
-
- if (d->display)
- gf_display_detach(d->display);
-
- if (d->device)
- gf_dev_detach(d->device);
-
- d->memSurface = 0;
- d->hwSurface = 0;
- d->context = 0;
- d->layer = 0;
- d->display = 0;
- d->device = 0;
+ d->cleanup();
}
-/*! \reimp
- */
+/*!
+ \reimp
+*/
void QQnxScreen::shutdownDevice()
{
}
-
-/*! \reimp
- QQnxScreen doesn't support setting the mode, use io-display instead.
- */
+/*!
+ \reimp
+ QQnxScreen doesn't support setting the mode, use io-display instead.
+*/
void QQnxScreen::setMode(int,int,int)
{
qWarning("QQnxScreen: Unable to change mode, use io-display instead.");
}
-/*! \reimp
- */
+/*!
+ \reimp
+*/
bool QQnxScreen::supportsDepth(int depth) const
{
- // only 32-bit for the moment
- return depth == 32;
+ gf_modeinfo_t displayMode;
+ for (int i = 0; gf_display_query_mode(d->display, i, &displayMode) == GF_ERR_OK; ++i) {
+ switch (displayMode.primary_format) {
+#if defined(QT_QWS_DEPTH_32) || defined(QT_QWS_DEPTH_GENERIC)
+ case GF_FORMAT_ARGB8888:
+ case GF_FORMAT_BGRA8888:
+ if (depth == 32)
+ return true;
+ break;
+#endif
+#if defined(QT_QWS_DEPTH_24)
+ case GF_FORMAT_BGR888:
+ if (depth == 24)
+ return true;
+ break;
+#endif
+#if defined(QT_QWS_DEPTH_16) || defined(QT_QWS_DEPTH_GENERIC)
+ case GF_FORMAT_PACK_RGB565:
+ case GF_FORMAT_PKLE_RGB565:
+ case GF_FORMAT_PKBE_RGB565:
+ if (depth == 16)
+ return true;
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+
+ return false;
}
-/*! \reimp
- */
+/*!
+ \reimp
+*/
+void QQnxScreen::blank(bool on)
+{
+ int ret = gf_display_set_dpms(d->display, on ? GF_DPMS_OFF : GF_DPMS_ON);
+ if (ret != GF_ERR_OK)
+ qWarning("QQnxScreen: gf_display_set_dpms() failed with error code %d", ret);
+}
+
+/*!
+ \reimp
+*/
void QQnxScreen::exposeRegion(QRegion r, int changing)
{
// here is where the actual magic happens. QWS will call exposeRegion whenever
@@ -414,6 +503,10 @@ void QQnxScreen::exposeRegion(QRegion r, int changing)
QScreen::exposeRegion(r, changing);
// now our in-memory surface should be up to date with the latest changes.
+
+ if (!d->hwSurface)
+ return;
+
// the code below copies the region from the in-memory surface to the hardware.
// just get the bounding rectangle of the region. Most screen updates are rectangular
@@ -432,16 +525,14 @@ void QQnxScreen::exposeRegion(QRegion r, int changing)
// blit the changed region from the memory surface to the hardware surface
ret = gf_draw_blit2(d->context, d->memSurface, d->hwSurface,
- br.x(), br.y(), br.right(), br.bottom(), br.x(), br.y());
- if (ret != GF_ERR_OK) {
+ br.x(), br.y(), br.right(), br.bottom(), br.x(), br.y());
+ if (ret != GF_ERR_OK)
qWarning("QQnxScreen: gf_draw_blit2() failed with error code %d", ret);
- }
// flush all drawing commands (in our case, a single blit)
ret = gf_draw_flush(d->context);
- if (ret != GF_ERR_OK) {
+ if (ret != GF_ERR_OK)
qWarning("QQnxScreen: gf_draw_flush() failed with error code %d", ret);
- }
// tell QNX that we're done drawing.
gf_draw_end(d->context);
diff --git a/src/gui/embedded/qscreenqnx_qws.h b/src/gui/embedded/qscreenqnx_qws.h
index 38c0ac9..6f6d18a 100644
--- a/src/gui/embedded/qscreenqnx_qws.h
+++ b/src/gui/embedded/qscreenqnx_qws.h
@@ -66,6 +66,7 @@ public:
void shutdownDevice();
void setMode(int,int,int);
bool supportsDepth(int) const;
+ void blank(bool on);
void exposeRegion(QRegion r, int changing);
diff --git a/src/gui/embedded/qwslock.cpp b/src/gui/embedded/qwslock.cpp
index c14f50b..f9ea000 100644
--- a/src/gui/embedded/qwslock.cpp
+++ b/src/gui/embedded/qwslock.cpp
@@ -45,12 +45,15 @@
#include "qwssignalhandler_p.h"
+#include <stdint.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/sem.h>
+#endif
#include <sys/time.h>
#include <time.h>
#ifdef Q_OS_LINUX
@@ -66,6 +69,12 @@ QT_BEGIN_NAMESPACE
#error QWSLock currently requires semaphores
#endif
+#ifdef QT_POSIX_IPC
+#include <QtCore/QAtomicInt>
+
+static QBasicAtomicInt localUniqueId = Q_BASIC_ATOMIC_INITIALIZER(1);
+#endif
+
QWSLock::QWSLock(int id) : semId(id)
{
static unsigned short initialValues[3] = { 1, 1, 0 };
@@ -74,6 +83,7 @@ QWSLock::QWSLock(int id) : semId(id)
QWSSignalHandler::instance()->addWSLock(this);
#endif
+#ifndef QT_POSIX_IPC
if (semId == -1) {
semId = semget(IPC_PRIVATE, 3, IPC_CREAT | 0666);
if (semId == -1) {
@@ -88,6 +98,30 @@ QWSLock::QWSLock(int id) : semId(id)
qFatal("Unable to initialize semaphores");
}
}
+#else
+ sems[0] = sems[1] = sems[2] = SEM_FAILED;
+ owned = false;
+
+ if (semId == -1) {
+ // ### generate really unique IDs
+ semId = (getpid() << 16) + (localUniqueId.fetchAndAddRelaxed(1) % ushort(-1));
+ owned = true;
+ }
+
+ QByteArray pfx = "/qwslock_" + QByteArray::number(semId, 16) + '_';
+ QByteArray keys[3] = { pfx + "BackingStore", pfx + "Communication", pfx + "RegionEvent" };
+ for (int i = 0; i < 3; ++i) {
+ if (owned)
+ sem_unlink(keys[i].constData());
+ do {
+ sems[i] = sem_open(keys[i].constData(), (owned ? O_CREAT : 0), 0666, initialValues[i]);
+ } while (sems[i] == SEM_FAILED && errno == EINTR);
+ if (sems[i] == SEM_FAILED) {
+ perror("QWSLock::QWSLock");
+ qFatal("Unable to %s semaphore", (owned ? "create" : "open"));
+ }
+ }
+#endif
lockCount[0] = lockCount[1] = 0;
}
@@ -99,10 +133,27 @@ QWSLock::~QWSLock()
#endif
if (semId != -1) {
+#ifndef QT_POSIX_IPC
qt_semun semval;
semval.val = 0;
semctl(semId, 0, IPC_RMID, semval);
semId = -1;
+#else
+ // emulate the SEM_UNDO behavior for the BackingStore lock
+ while (hasLock(BackingStore))
+ unlock(BackingStore);
+
+ QByteArray pfx = "/qwslock_" + QByteArray::number(semId, 16) + '_';
+ QByteArray keys[3] = { pfx + "BackingStore", pfx + "Communication", pfx + "RegionEvent" };
+ for (int i = 0; i < 3; ++i) {
+ if (sems[i] != SEM_FAILED) {
+ sem_close(sems[i]);
+ sems[i] = SEM_FAILED;
+ }
+ if (owned)
+ sem_unlink(keys[i].constData());
+ }
+#endif
}
}
@@ -110,6 +161,7 @@ bool QWSLock::up(unsigned short semNum)
{
int ret;
+#ifndef QT_POSIX_IPC
sembuf sops = { semNum, 1, 0 };
// As the BackingStore lock is a mutex, and only one process may own
// the lock, it's safe to use SEM_UNDO. On the other hand, the
@@ -119,6 +171,9 @@ bool QWSLock::up(unsigned short semNum)
sops.sem_flg |= SEM_UNDO;
EINTR_LOOP(ret, semop(semId, &sops, 1));
+#else
+ ret = sem_post(sems[semNum]);
+#endif
if (ret == -1) {
qDebug("QWSLock::up(): %s", strerror(errno));
return false;
@@ -131,6 +186,7 @@ bool QWSLock::down(unsigned short semNum, int)
{
int ret;
+#ifndef QT_POSIX_IPC
sembuf sops = { semNum, -1, 0 };
// As the BackingStore lock is a mutex, and only one process may own
// the lock, it's safe to use SEM_UNDO. On the other hand, the
@@ -140,6 +196,9 @@ bool QWSLock::down(unsigned short semNum, int)
sops.sem_flg |= SEM_UNDO;
EINTR_LOOP(ret, semop(semId, &sops, 1));
+#else
+ EINTR_LOOP(ret, sem_wait(sems[semNum]));
+#endif
if (ret == -1) {
qDebug("QWSLock::down(): %s", strerror(errno));
return false;
@@ -150,7 +209,13 @@ bool QWSLock::down(unsigned short semNum, int)
int QWSLock::getValue(unsigned short semNum) const
{
- int ret = semctl(semId, semNum, GETVAL, 0);
+ int ret;
+#ifndef QT_POSIX_IPC
+ ret = semctl(semId, semNum, GETVAL, 0);
+#else
+ if (sem_getvalue(sems[semNum], &ret) == -1)
+ ret = -1;
+#endif
if (ret == -1)
qDebug("QWSLock::getValue(): %s", strerror(errno));
return ret;
diff --git a/src/gui/embedded/qwslock_p.h b/src/gui/embedded/qwslock_p.h
index d020b22..71a4cca 100644
--- a/src/gui/embedded/qwslock_p.h
+++ b/src/gui/embedded/qwslock_p.h
@@ -57,6 +57,10 @@
#ifndef QT_NO_QWS_MULTIPROCESS
+#ifdef QT_POSIX_IPC
+# include <semaphore.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QWSLock
@@ -80,6 +84,10 @@ private:
int semId;
int lockCount[2];
+#ifdef QT_POSIX_IPC
+ sem_t *sems[3];
+ bool owned;
+#endif
};
QT_END_NAMESPACE
diff --git a/src/gui/embedded/qwssharedmemory.cpp b/src/gui/embedded/qwssharedmemory.cpp
index a677626..853de61 100644
--- a/src/gui/embedded/qwssharedmemory.cpp
+++ b/src/gui/embedded/qwssharedmemory.cpp
@@ -45,14 +45,37 @@
#include <sys/types.h>
#include <sys/ipc.h>
+#ifndef QT_POSIX_IPC
#include <sys/shm.h>
+#else
+#include <sys/mman.h>
+#include <sys/stat.h>
+#endif
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <private/qcore_unix_p.h>
//#define QT_SHM_DEBUG
QT_BEGIN_NAMESPACE
+#ifdef QT_POSIX_IPC
+#include <QtCore/QAtomicInt>
+
+static QBasicAtomicInt localUniqueId = Q_BASIC_ATOMIC_INITIALIZER(1);
+
+static inline QByteArray makeKey(int id)
+{
+ return "/qwsshm_" + QByteArray::number(id, 16);
+}
+#endif
+
QWSSharedMemory::QWSSharedMemory()
: shmId(-1), shmBase(0), shmSize(0)
+#ifdef QT_POSIX_IPC
+ , hand(-1)
+#endif
{
}
@@ -66,19 +89,47 @@ bool QWSSharedMemory::create(int size)
if (shmId != -1)
detach();
+#ifndef QT_POSIX_IPC
shmId = shmget(IPC_PRIVATE, size, IPC_CREAT | 0600);
+#else
+ // ### generate really unique IDs
+ shmId = (getpid() << 16) + (localUniqueId.fetchAndAddRelaxed(1) % ushort(-1));
+ QByteArray shmName = makeKey(shmId);
+ EINTR_LOOP(hand, shm_open(shmName.constData(), O_RDWR | O_CREAT, 0660));
+ if (hand != -1) {
+ // the size may only be set once; ignore errors
+ int ret;
+ EINTR_LOOP(ret, ftruncate(hand, size));
+ if (ret == -1)
+ shmId = -1;
+ } else {
+ shmId = -1;
+ }
+#endif
if (shmId == -1) {
#ifdef QT_SHM_DEBUG
perror("QWSSharedMemory::create():");
qWarning("Error allocating shared memory of size %d", size);
#endif
+ detach();
return false;
}
+
+#ifndef QT_POSIX_IPC
shmBase = shmat(shmId, 0, 0);
// On Linux, it is possible to attach a shared memory segment even if it
// is already marked to be deleted. However, POSIX.1-2001 does not specify
// this behaviour and many other implementations do not support it.
shmctl(shmId, IPC_RMID, 0);
+#else
+ // grab the size
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) != -1) {
+ shmSize = st.st_size;
+ // grab the memory
+ shmBase = mmap(0, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, hand, 0);
+ }
+#endif
if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
perror("QWSSharedMemory::create():");
@@ -102,7 +153,21 @@ bool QWSSharedMemory::attach(int id)
return false;
shmId = id;
+#ifndef QT_POSIX_IPC
shmBase = shmat(shmId, 0, 0);
+#else
+ QByteArray shmName = makeKey(shmId);
+ EINTR_LOOP(hand, shm_open(shmName.constData(), O_RDWR, 0660));
+ if (hand != -1) {
+ // grab the size
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) != -1) {
+ shmSize = st.st_size;
+ // grab the memory
+ shmBase = mmap(0, shmSize, PROT_READ | PROT_WRITE, MAP_SHARED, hand, 0);
+ }
+ }
+#endif
if (shmBase == (void*)-1 || !shmBase) {
#ifdef QT_SHM_DEBUG
perror("QWSSharedMemory::attach():");
@@ -117,8 +182,28 @@ bool QWSSharedMemory::attach(int id)
void QWSSharedMemory::detach()
{
+#ifndef QT_POSIX_IPC
if (shmBase && shmBase != (void*)-1)
shmdt(shmBase);
+#else
+ if (shmBase && shmBase != (void*)-1)
+ munmap(shmBase, shmSize);
+ if (hand > 0) {
+ // get the number of current attachments
+ int shm_nattch = 0;
+ QT_STATBUF st;
+ if (QT_FSTAT(hand, &st) == 0) {
+ // subtract 2 from linkcount: one for our own open and one for the dir entry
+ shm_nattch = st.st_nlink - 2;
+ }
+ qt_safe_close(hand);
+ // if there are no attachments then unlink the shared memory
+ if (shm_nattch == 0) {
+ QByteArray shmName = makeKey(shmId);
+ shm_unlink(shmName.constData());
+ }
+ }
+#endif
shmBase = 0;
shmSize = 0;
shmId = -1;
@@ -129,11 +214,13 @@ int QWSSharedMemory::size() const
if (shmId == -1)
return 0;
+#ifndef QT_POSIX_IPC
if (!shmSize) {
struct shmid_ds shm;
shmctl(shmId, IPC_STAT, &shm);
- const_cast<QWSSharedMemory *>(this)->shmSize = shm.shm_segsz;
+ shmSize = shm.shm_segsz;
}
+#endif
return shmSize;
}
diff --git a/src/gui/embedded/qwssharedmemory_p.h b/src/gui/embedded/qwssharedmemory_p.h
index f3ce241..42ef6c8 100644
--- a/src/gui/embedded/qwssharedmemory_p.h
+++ b/src/gui/embedded/qwssharedmemory_p.h
@@ -77,7 +77,10 @@ public:
private:
int shmId;
void *shmBase;
- int shmSize;
+ mutable int shmSize;
+#ifdef QT_POSIX_IPC
+ int hand;
+#endif
};
#endif // QT_NO_QWS_MULTIPROCESS
diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp
index 76d2d04..6fbe849 100644
--- a/src/gui/graphicsview/qgraphicslayout.cpp
+++ b/src/gui/graphicsview/qgraphicslayout.cpp
@@ -269,18 +269,8 @@ void QGraphicsLayout::activate()
return;
Q_ASSERT(!parentItem->isLayout());
- if (QGraphicsLayout::instantInvalidatePropagation()) {
- QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem);
- if (!parentWidget->parentLayoutItem()) {
- // we've reached the topmost widget, resize it
- bool wasResized = parentWidget->testAttribute(Qt::WA_Resized);
- parentWidget->resize(parentWidget->size());
- parentWidget->setAttribute(Qt::WA_Resized, wasResized);
- }
-
- setGeometry(parentItem->contentsRect()); // relayout children
- } else {
- setGeometry(parentItem->contentsRect()); // relayout children
+ setGeometry(parentItem->contentsRect()); // relayout children
+ if (!QGraphicsLayout::instantInvalidatePropagation()) {
parentLayoutItem()->updateGeometry();
}
}
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index 804394a..965b1b34 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -347,11 +347,10 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
{
QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func();
QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data();
- QRectF newGeom;
+ QRectF newGeom = rect;
QPointF oldPos = d->geom.topLeft();
if (!wd->inSetPos) {
setAttribute(Qt::WA_Resized);
- newGeom = rect;
newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize))
.boundedTo(effectiveSizeHint(Qt::MaximumSize)));
@@ -405,14 +404,7 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
emit widthChanged();
if (oldSize.height() != newGeom.size().height())
emit heightChanged();
- QGraphicsLayout *lay = wd->layout;
- if (QGraphicsLayout::instantInvalidatePropagation()) {
- if (!lay || lay->isActivated()) {
- QApplication::sendEvent(this, &re);
- }
- } else {
- QApplication::sendEvent(this, &re);
- }
+ QApplication::sendEvent(this, &re);
}
}
@@ -1091,8 +1083,11 @@ void QGraphicsWidget::updateGeometry()
* When the event is received, it will start flowing all the way down to the leaf
* widgets in one go. This will make a relayout flicker-free.
*/
- if (QGraphicsLayout::instantInvalidatePropagation())
- QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest));
+ if (QGraphicsLayout::instantInvalidatePropagation()) {
+ Q_D(QGraphicsWidget);
+ ++d->refCountInvokeRelayout;
+ QMetaObject::invokeMethod(this, "_q_relayout", Qt::QueuedConnection);
+ }
}
if (!QGraphicsLayout::instantInvalidatePropagation()) {
bool wasResized = testAttribute(Qt::WA_Resized);
diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h
index 063be2d..5085817 100644
--- a/src/gui/graphicsview/qgraphicswidget.h
+++ b/src/gui/graphicsview/qgraphicswidget.h
@@ -234,6 +234,8 @@ protected:
private:
Q_DISABLE_COPY(QGraphicsWidget)
Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsWidget)
+ Q_PRIVATE_SLOT(d_func(), void _q_relayout())
+
friend class QGraphicsScene;
friend class QGraphicsScenePrivate;
friend class QGraphicsView;
diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp
index 8649dec..ca6713b 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.cpp
+++ b/src/gui/graphicsview/qgraphicswidget_p.cpp
@@ -233,6 +233,18 @@ void QGraphicsWidgetPrivate::resolveLayoutDirection()
}
}
+/* private slot */
+void QGraphicsWidgetPrivate::_q_relayout()
+{
+ --refCountInvokeRelayout;
+ if (refCountInvokeRelayout == 0) {
+ Q_Q(QGraphicsWidget);
+ bool wasResized = q->testAttribute(Qt::WA_Resized);
+ q->resize(q->size()); // this will restrict the size
+ q->setAttribute(Qt::WA_Resized, wasResized);
+ }
+}
+
QPalette QGraphicsWidgetPrivate::naturalWidgetPalette() const
{
Q_Q(const QGraphicsWidget);
@@ -903,4 +915,6 @@ void QGraphicsWidgetPrivate::setGeometryFromSetPos()
QT_END_NAMESPACE
+#include "moc_qgraphicswidget.cpp"
+
#endif //QT_NO_GRAPHICSVIEW
diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h
index 398abc3..6ea2586 100644
--- a/src/gui/graphicsview/qgraphicswidget_p.h
+++ b/src/gui/graphicsview/qgraphicswidget_p.h
@@ -81,6 +81,7 @@ public:
polished(0),
inSetPos(0),
autoFillBackground(0),
+ refCountInvokeRelayout(0),
focusPolicy(Qt::NoFocus),
focusNext(0),
focusPrev(0),
@@ -106,6 +107,7 @@ public:
QGraphicsLayout *layout;
void setLayoutDirection_helper(Qt::LayoutDirection direction);
void resolveLayoutDirection();
+ void _q_relayout();
// Style
QPalette palette;
@@ -179,11 +181,14 @@ public:
return false;
return (attributes & (1 << bit)) != 0;
}
+ // 32 bits
+ quint32 refCountInvokeRelayout : 16;
quint32 attributes : 10;
quint32 inSetGeometry : 1;
quint32 polished: 1;
quint32 inSetPos : 1;
quint32 autoFillBackground : 1;
+ quint32 padding : 2; // feel free to use
// Focus
Qt::FocusPolicy focusPolicy;
diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h
index 5b75aa1..f07843d 100644
--- a/src/gui/image/qpixmapdata_p.h
+++ b/src/gui/image/qpixmapdata_p.h
@@ -56,6 +56,10 @@
#include <QtGui/qpixmap.h>
#include <QtCore/qatomic.h>
+#ifdef Q_OS_SYMBIAN
+#include <QtGui/private/qvolatileimage_p.h>
+#endif
+
QT_BEGIN_NAMESPACE
class QImageReader;
@@ -135,6 +139,7 @@ public:
}
#if defined(Q_OS_SYMBIAN)
+ virtual QVolatileImage toVolatileImage() const { return QVolatileImage(); }
virtual void* toNativeType(NativeType type);
virtual void fromNativeType(void* pixmap, NativeType type);
#endif
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index ebf0ff8..d603540 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -646,6 +646,7 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints)
{
using namespace Qt;
+ reset();
commitTemporaryPreeditString();
const bool anynumbermodes = hints & (ImhDigitsOnly | ImhFormattedNumbersOnly | ImhDialableCharactersOnly);
diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm
index 343b68f..c5ff799 100644
--- a/src/gui/kernel/qapplication_mac.mm
+++ b/src/gui/kernel/qapplication_mac.mm
@@ -218,7 +218,6 @@ extern OSWindowRef qt_mac_window_for(const QWidget*); //qwidget_mac.cpp
extern QWidget *qt_mac_find_window(OSWindowRef); //qwidget_mac.cpp
extern void qt_mac_set_cursor(const QCursor *); //qcursor_mac.cpp
extern bool qt_mac_is_macsheet(const QWidget *); //qwidget_mac.cpp
-extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
extern void qt_mac_command_set_enabled(MenuRef, UInt32, bool); //qmenu_mac.cpp
extern bool qt_sendSpontaneousEvent(QObject *obj, QEvent *event); // qapplication.cpp
extern void qt_mac_update_cursor(); // qcursor_mac.mm
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index 1197c77..3b6a075 100644
--- a/src/gui/kernel/qapplication_qws.cpp
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -209,7 +209,7 @@ QString qws_dataDir()
if (!S_ISDIR(buf.st_mode))
qFatal("%s is not a directory", dataDir.constData());
-#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS)
+#if !defined(Q_OS_INTEGRITY) && !defined(Q_OS_VXWORKS) && !defined(Q_OS_QNX)
if (buf.st_uid != getuid())
qFatal("Qt for Embedded Linux data directory is not owned by user %d", getuid());
@@ -2184,6 +2184,11 @@ void qt_init(QApplicationPrivate *priv, int type)
qws_screen_is_interlaced = read_bool_env_var("QWS_INTERLACE",false);
const char *display = ::getenv("QWS_DISPLAY");
+
+#ifdef QT_QWS_DEFAULT_DRIVER_NAME
+ if (!display) display = QT_QWS_DEFAULT_DRIVER_NAME;
+#endif
+
if (display)
qws_display_spec = display; // since we setenv later!
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 31d02d4..086cfec 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -1531,6 +1531,11 @@ void QSymbianControl::HandleResourceChange(int resourceType)
QResizeEvent e(qt_desktopWidget->size(), qt_desktopWidget->size());
QApplication::sendEvent(qt_desktopWidget, &e);
}
+ // Send resize event to dialogs so they can adjust their position if necessary.
+ if (qwidget->windowType() & Qt::Dialog) {
+ QResizeEvent e(qwidget->size(), qwidget->size());
+ QApplication::sendEvent(qwidget, &e);
+ }
break;
}
#endif
diff --git a/src/gui/kernel/qmime_mac.cpp b/src/gui/kernel/qmime_mac.cpp
index a1df34e..8b47d8e 100644
--- a/src/gui/kernel/qmime_mac.cpp
+++ b/src/gui/kernel/qmime_mac.cpp
@@ -119,10 +119,6 @@ const QStringList& qEnabledDraggedTypes()
*****************************************************************************/
//#define DEBUG_MIME_MAPS
-//functions
-extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
-extern void qt_mac_from_pascal_string(QString, Str255, TextEncoding encoding=0, int len=-1); //qglobal.cpp
-
ScrapFlavorType qt_mac_mime_type = 'CUTE';
CFStringRef qt_mac_mime_typeUTI = CFSTR("com.pasteboard.trolltech.marker");
diff --git a/src/gui/kernel/qt_mac.cpp b/src/gui/kernel/qt_mac.cpp
index 339bc82..69f0034 100644
--- a/src/gui/kernel/qt_mac.cpp
+++ b/src/gui/kernel/qt_mac.cpp
@@ -61,7 +61,6 @@ QFont qfontForThemeFont(ThemeFontID themeID)
SInt16 f_size;
Style f_style;
GetThemeFont(themeID, Script, f_name, &f_size, &f_style);
- extern QString qt_mac_from_pascal_string(const Str255); //qglobal.cpp
return QFont(qt_mac_from_pascal_string(f_name), f_size,
(f_style & ::bold) ? QFont::Bold : QFont::Normal,
(bool)(f_style & ::italic));
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 778f1f1..b3bf365 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -4551,6 +4551,11 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM
QPoint oldp = q->pos();
QSize olds = q->size();
+ // Apply size restrictions, applicable for Windows & Widgets.
+ if (QWExtra *extra = extraData()) {
+ w = qBound(extra->minw, w, extra->maxw);
+ h = qBound(extra->minh, h, extra->maxh);
+ }
const bool isResize = (olds != QSize(w, h));
if (!realWindow && !isResize && QPoint(x, y) == oldp)
@@ -4560,13 +4565,6 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM
data.window_state = data.window_state & ~Qt::WindowMaximized;
const bool visible = q->isVisible();
- // Apply size restrictions, applicable for Windows & Widgets.
- if (QWExtra *extra = extraData()) {
- w = qMin(w, extra->maxw);
- h = qMin(h, extra->maxh);
- w = qMax(w, extra->minw);
- h = qMax(h, extra->minh);
- }
data.crect = QRect(x, y, w, h);
if (realWindow) {
diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp
index 661120c..56c3010 100644
--- a/src/gui/kernel/qwidget_qpa.cpp
+++ b/src/gui/kernel/qwidget_qpa.cpp
@@ -129,6 +129,11 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
{
Q_D(QWidget);
+ d->aboutToDestroy();
+ if (!isWindow() && parentWidget())
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
+ d->deactivateWidgetCleanup();
+
if ((windowType() == Qt::Popup))
qApp->d_func()->closePopup(this);
@@ -136,6 +141,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
if (this == QApplicationPrivate::active_window)
QApplication::setActiveWindow(0);
+ setAttribute(Qt::WA_WState_Created, false);
+
if (windowType() != Qt::Desktop) {
if (destroySubWindows) {
QObjectList childList(children());
@@ -155,6 +162,8 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
d->hide_sys();
}
}
+
+ d->setWinId(0);
}
}
@@ -412,6 +421,7 @@ void QWidgetPrivate::hide_sys()
{
Q_Q(QWidget);
q->setAttribute(Qt::WA_Mapped, false);
+ deactivateWidgetCleanup();
if (!q->isWindow()) {
QWidget *p = q->parentWidget();
if (p &&p->isVisible()) {
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 8510416..5105d9a 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -1084,7 +1084,7 @@ void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem)
changedHints = true;
}
- fill(qtVectorPathForPath(path), staticTextItem->color);
+ fill(qtVectorPathForPath(path), s->pen.color());
if (changedHints) {
s->renderHints = oldHints;
diff --git a/src/gui/painting/qwindowsurface_qws.cpp b/src/gui/painting/qwindowsurface_qws.cpp
index 7e8cf9b..3789a33 100644
--- a/src/gui/painting/qwindowsurface_qws.cpp
+++ b/src/gui/painting/qwindowsurface_qws.cpp
@@ -1065,10 +1065,12 @@ bool QWSSharedMemSurface::setMemory(int memId)
return true;
mem.detach();
- if (!mem.attach(memId)) {
+
+ if (memId != -1 && !mem.attach(memId)) {
+#ifndef QT_NO_DEBUG
perror("QWSSharedMemSurface: attaching to shared memory");
- qCritical("QWSSharedMemSurface: Error attaching to"
- " shared memory 0x%x", memId);
+ qCritical("QWSSharedMemSurface: Error attaching to shared memory 0x%x", memId);
+#endif
return false;
}
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index e5171d8..ad0e151 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -5292,7 +5292,7 @@ QPixmap QCommonStyle::standardPixmap(StandardPixmap sp, const QStyleOption *opti
pixmap = QIcon::fromTheme(QLatin1String("media-seek-backward")).pixmap(16);
break;
case SP_MediaSkipForward:
- pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16);
+ pixmap = QIcon::fromTheme(QLatin1String("media-skip-forward")).pixmap(16);
break;
case SP_MediaSkipBackward:
pixmap = QIcon::fromTheme(QLatin1String("media-skip-backward")).pixmap(16);
diff --git a/src/gui/text/qfontdatabase_mac.cpp b/src/gui/text/qfontdatabase_mac.cpp
index 724dbf6..60cf586 100644
--- a/src/gui/text/qfontdatabase_mac.cpp
+++ b/src/gui/text/qfontdatabase_mac.cpp
@@ -388,7 +388,6 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
if(fnt->data.isEmpty()) {
#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
- extern OSErr qt_mac_create_fsref(const QString &, FSRef *); // qglobal.cpp
FSRef ref;
if(qt_mac_create_fsref(fnt->fileName, &ref) != noErr)
return;
@@ -398,7 +397,6 @@ static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt)
#endif
{
#ifndef Q_WS_MAC64
- extern Q_CORE_EXPORT OSErr qt_mac_create_fsspec(const QString &, FSSpec *); // global.cpp
FSSpec spec;
if(qt_mac_create_fsspec(fnt->fileName, &spec) != noErr)
return;
diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp
index c83e929..313000f 100644
--- a/src/gui/text/qfontdatabase_qws.cpp
+++ b/src/gui/text/qfontdatabase_qws.cpp
@@ -75,6 +75,11 @@
#include <qresource.h>
#endif
+#ifdef Q_OS_QNX
+// ### using QFontEngineQPF leads to artifacts on QNX
+# define QT_NO_QWS_SHARE_FONTS
+#endif
+
QT_BEGIN_NAMESPACE
#ifndef QT_NO_LIBRARY
diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp
index 754334c..958daa2 100644
--- a/src/gui/text/qfontdatabase_x11.cpp
+++ b/src/gui/text/qfontdatabase_x11.cpp
@@ -1566,9 +1566,8 @@ static FcPattern *getFcPattern(const QFontPrivate *fp, int script, const QFontDe
qt_addPatternProps(pattern, fp->screen, script, request);
- FcDefaultSubstitute(pattern);
FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcConfigSubstitute(0, pattern, FcMatchFont);
+ FcDefaultSubstitute(pattern);
// these should only get added to the pattern _after_ substitution
// append the default fallback font for the specified script
@@ -1606,35 +1605,20 @@ static void FcFontSetRemove(FcFontSet *fs, int at)
memmove(fs->fonts + at, fs->fonts + at + 1, len);
}
-static QFontEngine *tryPatternLoad(FcPattern *p, int screen,
- const QFontDef &request, int script, FcPattern **matchedPattern = 0)
+static QFontEngine *tryPatternLoad(FcPattern *match, int screen,
+ const QFontDef &request, int script)
{
#ifdef FONT_MATCH_DEBUG
FcChar8 *fam;
- FcPatternGetString(p, FC_FAMILY, 0, &fam);
+ FcPatternGetString(match, FC_FAMILY, 0, &fam);
FM_DEBUG("==== trying %s\n", fam);
#endif
FM_DEBUG("passes charset test\n");
- FcPattern *pattern = FcPatternDuplicate(p);
- // add properties back in as the font selected from the
- // list doesn't contain them.
- qt_addPatternProps(pattern, screen, script, request);
-
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
- FcResult res;
- FcPattern *match = FcFontMatch(0, pattern, &res);
-
- if (matchedPattern)
- *matchedPattern = 0;
QFontEngineX11FT *engine = 0;
if (!match) // probably no fonts available.
goto done;
- if (matchedPattern)
- *matchedPattern = FcPatternDuplicate(match);
-
if (script != QUnicodeTables::Common) {
// skip font if it doesn't support the language we want
if (specialChars[script]) {
@@ -1673,11 +1657,6 @@ static QFontEngine *tryPatternLoad(FcPattern *p, int screen,
}
}
done:
- FcPatternDestroy(pattern);
- if (!engine && matchedPattern && *matchedPattern) {
- FcPatternDestroy(*matchedPattern);
- *matchedPattern = 0;
- }
return engine;
}
@@ -1726,14 +1705,26 @@ static QFontEngine *loadFc(const QFontPrivate *fp, int script, const QFontDef &r
#endif
QFontEngine *fe = 0;
- FcPattern *matchedPattern = 0;
- fe = tryPatternLoad(pattern, fp->screen, request, script, &matchedPattern);
+ FcResult res;
+ FcPattern *match = FcFontMatch(0, pattern, &res);
+ fe = tryPatternLoad(match, fp->screen, request, script);
if (!fe) {
FcFontSet *fs = qt_fontSetForPattern(pattern, request);
+ if (match) {
+ FcPatternDestroy(match);
+ match = 0;
+ }
+
if (fs) {
- for (int i = 0; !fe && i < fs->nfont; ++i)
- fe = tryPatternLoad(fs->fonts[i], fp->screen, request, script, &matchedPattern);
+ for (int i = 0; !fe && i < fs->nfont; ++i) {
+ match = FcFontRenderPrepare(NULL, pattern, fs->fonts[i]);
+ fe = tryPatternLoad(match, fp->screen, request, script);
+ if (fe)
+ break;
+ FcPatternDestroy(match);
+ match = 0;
+ }
FcFontSetDestroy(fs);
}
FM_DEBUG("engine for script %d is %s\n", script, fe ? fe->fontDef.family.toLatin1().data(): "(null)");
@@ -1741,11 +1732,11 @@ static QFontEngine *loadFc(const QFontPrivate *fp, int script, const QFontDef &r
if (fe
&& script == QUnicodeTables::Common
&& !(request.styleStrategy & QFont::NoFontMerging) && !fe->symbol) {
- fe = new QFontEngineMultiFT(fe, matchedPattern, pattern, fp->screen, request);
+ fe = new QFontEngineMultiFT(fe, match, pattern, fp->screen, request);
} else {
FcPatternDestroy(pattern);
- if (matchedPattern)
- FcPatternDestroy(matchedPattern);
+ if (match)
+ FcPatternDestroy(match);
}
return fe;
}
diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp
index e3bfa5d..490866c 100644
--- a/src/gui/text/qfontengine_x11.cpp
+++ b/src/gui/text/qfontengine_x11.cpp
@@ -863,11 +863,8 @@ glyph_t QFontEngineXLFD::glyphIndexToFreetypeGlyphIndex(glyph_t g) const
// Multi FT engine
// ------------------------------------------------------------------
-static QFontEngine *engineForPattern(FcPattern *pattern, const QFontDef &request,
- int screen)
+static QFontEngine *engineForPattern(FcPattern *match, const QFontDef &request, int screen)
{
- FcResult res;
- FcPattern *match = FcFontMatch(0, pattern, &res);
QFontEngineX11FT *engine = new QFontEngineX11FT(match, request, screen);
if (!engine->invalid())
return engine;
@@ -879,9 +876,9 @@ static QFontEngine *engineForPattern(FcPattern *pattern, const QFontDef &request
}
QFontEngineMultiFT::QFontEngineMultiFT(QFontEngine *fe, FcPattern *matchedPattern, FcPattern *p, int s, const QFontDef &req)
- : QFontEngineMulti(2), request(req), pattern(p), firstEnginePattern(matchedPattern), fontSet(0), screen(s)
+ : QFontEngineMulti(2), request(req), pattern(p), fontSet(0), screen(s)
{
-
+ firstEnginePattern = FcPatternDuplicate(matchedPattern);
engines[0] = fe;
engines.at(0)->ref.ref();
fontDef = engines[0]->fontDef;
@@ -907,8 +904,6 @@ void QFontEngineMultiFT::loadEngine(int at)
extern QMutex *qt_fontdatabase_mutex();
QMutexLocker locker(qt_fontdatabase_mutex());
- extern void qt_addPatternProps(FcPattern *pattern, int screen, int script,
- const QFontDef &request);
extern QFontDef qt_FcPatternToQFontDef(FcPattern *pattern, const QFontDef &);
extern FcFontSet *qt_fontSetForPattern(FcPattern *pattern, const QFontDef &request);
@@ -940,22 +935,18 @@ void QFontEngineMultiFT::loadEngine(int at)
Q_ASSERT(at < engines.size());
Q_ASSERT(engines.at(at) == 0);
- FcPattern *pattern = FcPatternDuplicate(fontSet->fonts[at + firstFontIndex - 1]);
- qt_addPatternProps(pattern, screen, QUnicodeTables::Common, request);
-
- QFontDef fontDef = qt_FcPatternToQFontDef(pattern, this->request);
+ FcPattern *match = FcFontRenderPrepare(NULL, pattern, fontSet->fonts[at + firstFontIndex - 1]);
+ QFontDef fontDef = qt_FcPatternToQFontDef(match, this->request);
// note: we use -1 for the script to make sure that we keep real
// FT engines separate from Multi engines in the font cache
QFontCache::Key key(fontDef, -1, screen);
QFontEngine *fontEngine = QFontCache::instance()->findEngine(key);
if (!fontEngine) {
- FcConfigSubstitute(0, pattern, FcMatchPattern);
- FcDefaultSubstitute(pattern);
- fontEngine = engineForPattern(pattern, request, screen);
+ fontEngine = engineForPattern(match, request, screen);
QFontCache::instance()->insertEngine(key, fontEngine);
}
- FcPatternDestroy(pattern);
+ FcPatternDestroy(match);
fontEngine->ref.ref();
engines[at] = fontEngine;
}
@@ -1123,17 +1114,14 @@ QFontEngineX11FT::QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int s
}
#endif
- if (!init(face_id, antialias, defaultFormat)) {
- FcPatternDestroy(pattern);
+ if (!init(face_id, antialias, defaultFormat))
return;
- }
if (!freetype->charset) {
FcCharSet *cs;
FcPatternGetCharSet (pattern, FC_CHARSET, 0, &cs);
freetype->charset = FcCharSetCopy(cs);
}
- FcPatternDestroy(pattern);
}
QFontEngineX11FT::~QFontEngineX11FT()
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 41b6fe2..0abafb8 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2553,7 +2553,7 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block)
const bool emptyBlock = block.begin().atEnd();
if (emptyBlock) {
- html += QLatin1String("-qt-paragraph-type:empty; height:1em;");
+ html += QLatin1String("-qt-paragraph-type:empty;");
}
emitMargins(QString::number(format.topMargin()),
@@ -2709,6 +2709,8 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
emitBlockAttributes(block);
html += QLatin1Char('>');
+ if (block.begin().atEnd())
+ html += "<br />";
QTextBlock::Iterator it = block.begin();
if (fragmentMarkers && !it.atEnd() && block == doc->begin())
diff --git a/src/gui/text/qtextdocumentfragment.cpp b/src/gui/text/qtextdocumentfragment.cpp
index 042b1d0..0c8860e 100644
--- a/src/gui/text/qtextdocumentfragment.cpp
+++ b/src/gui/text/qtextdocumentfragment.cpp
@@ -545,8 +545,13 @@ void QTextHtmlImporter::import()
}
if (currentNode->isBlock()) {
- if (processBlockNode() == ContinueWithNextNode)
+ QTextHtmlImporter::ProcessNodeResult result = processBlockNode();
+ if (result == ContinueWithNextNode) {
continue;
+ } else if (result == ContinueWithNextSibling) {
+ currentNodeIdx += currentNode->children.size();
+ continue;
+ }
}
if (currentNode->charFormat.isAnchor() && !currentNode->charFormat.anchorName().isEmpty()) {
@@ -1157,7 +1162,7 @@ QTextHtmlImporter::ProcessNodeResult QTextHtmlImporter::processBlockNode()
if (currentNode->isEmptyParagraph) {
hasBlock = false;
- return ContinueWithNextNode;
+ return ContinueWithNextSibling;
}
hasBlock = true;
diff --git a/src/gui/text/qtextdocumentfragment_p.h b/src/gui/text/qtextdocumentfragment_p.h
index bfbec30..227123e 100644
--- a/src/gui/text/qtextdocumentfragment_p.h
+++ b/src/gui/text/qtextdocumentfragment_p.h
@@ -135,7 +135,7 @@ private:
Table scanTable(int tableNodeIdx);
- enum ProcessNodeResult { ContinueWithNextNode, ContinueWithCurrentNode };
+ enum ProcessNodeResult { ContinueWithNextNode, ContinueWithCurrentNode, ContinueWithNextSibling };
void appendBlock(const QTextBlockFormat &format, QTextCharFormat charFmt = QTextCharFormat());
bool appendNodeText();
diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp
index e8e6c98..8ddf3eb 100644
--- a/src/gui/text/qtextengine.cpp
+++ b/src/gui/text/qtextengine.cpp
@@ -319,6 +319,26 @@ static void appendItems(QScriptAnalysis *analysis, int &start, int &stop, const
start = stop;
}
+static QChar::Direction skipBoundryNeutrals(QScriptAnalysis *analysis,
+ const ushort *unicode, int length,
+ int &sor, int &eor, QBidiControl &control)
+{
+ QChar::Direction dir;
+ int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level;
+ while (sor < length) {
+ dir = QChar::direction(unicode[sor]);
+ // Keep skipping DirBN as if it doesn't exist
+ if (dir != QChar::DirBN)
+ break;
+ analysis[sor++].bidiLevel = level;
+ }
+
+ eor = sor;
+ if (eor == length)
+ dir = control.basicDirection();
+
+ return dir;
+}
// creates the next QScript items.
static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiControl &control)
@@ -430,8 +450,7 @@ static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiCon
case QChar::DirAN:
if (eor >= 0) {
appendItems(analysis, sor, eor, control, dir);
- dir = eor < length ? QChar::direction(unicode[eor]) : control.basicDirection();
- status.eor = dir;
+ status.eor = dir = skipBoundryNeutrals(analysis, unicode, length, sor, eor, control);
} else {
eor = current; status.eor = dir;
}
@@ -455,8 +474,7 @@ static bool bidiItemize(QTextEngine *engine, QScriptAnalysis *analysis, QBidiCon
}
eor = current - 1;
appendItems(analysis, sor, eor, control, dir);
- dir = eor < length ? QChar::direction(unicode[eor]) : control.basicDirection();
- status.eor = dir;
+ status.eor = dir = skipBoundryNeutrals(analysis, unicode, length, sor, eor, control);
} else {
if(status.eor != QChar::DirL) {
appendItems(analysis, sor, eor, control, dir);
diff --git a/src/network/access/qnetworkcookiejar.cpp b/src/network/access/qnetworkcookiejar.cpp
index a2fa689..1a5f73b 100644
--- a/src/network/access/qnetworkcookiejar.cpp
+++ b/src/network/access/qnetworkcookiejar.cpp
@@ -220,20 +220,33 @@ bool QNetworkCookieJar::setCookiesFromUrl(const QList<QNetworkCookie> &cookieLis
continue; // not accepted
}
- QList<QNetworkCookie>::Iterator it = d->allCookies.begin(),
- end = d->allCookies.end();
- for ( ; it != end; ++it)
+ for (int i = 0; i < d->allCookies.size(); ++i) {
// does this cookie already exist?
- if (cookie.name() == it->name() &&
- cookie.domain() == it->domain() &&
- cookie.path() == it->path()) {
+ const QNetworkCookie &current = d->allCookies.at(i);
+ if (cookie.name() == current.name() &&
+ cookie.domain() == current.domain() &&
+ cookie.path() == current.path()) {
// found a match
- d->allCookies.erase(it);
+ d->allCookies.removeAt(i);
break;
}
+ }
// did not find a match
if (!isDeletion) {
+ int countForDomain = 0;
+ for (int i = d->allCookies.size() - 1; i >= 0; --i) {
+ // Start from the end and delete the oldest cookies to keep a maximum count of 50.
+ const QNetworkCookie &current = d->allCookies.at(i);
+ if (isParentDomain(cookie.domain(), current.domain())
+ || isParentDomain(current.domain(), cookie.domain())) {
+ if (countForDomain >= 49)
+ d->allCookies.removeAt(i);
+ else
+ ++countForDomain;
+ }
+ }
+
d->allCookies += cookie;
++added;
}
diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri
index bb98305..e5d33bb 100644
--- a/src/network/kernel/kernel.pri
+++ b/src/network/kernel/kernel.pri
@@ -26,7 +26,7 @@ win32:SOURCES += kernel/qhostinfo_win.cpp kernel/qnetworkinterface_win.cpp
integrity:SOURCES += kernel/qhostinfo_unix.cpp kernel/qnetworkinterface_unix.cpp
mac:LIBS_PRIVATE += -framework SystemConfiguration -framework CoreFoundation
-mac:SOURCES += kernel/qnetworkproxy_mac.cpp
+mac:contains(QT_CONFIG, coreservices) SOURCES += kernel/qnetworkproxy_mac.cpp
else:win32:SOURCES += kernel/qnetworkproxy_win.cpp
else:symbian:SOURCES += kernel/qnetworkproxy_symbian.cpp
else:SOURCES += kernel/qnetworkproxy_generic.cpp
diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp
index 818aab7..4f7f4ed 100644
--- a/src/network/kernel/qauthenticator.cpp
+++ b/src/network/kernel/qauthenticator.cpp
@@ -223,7 +223,7 @@ void QAuthenticator::setUser(const QString &user)
} else if((separatorPosn = user.indexOf(QLatin1String("@"))) != -1) {
//domain name is present
d->realm.clear();
- d->userDomain = user.left(separatorPosn);
+ d->userDomain = user.mid(separatorPosn + 1);
d->extractedUser = user.left(separatorPosn);
d->user = user;
} else {
diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp
index 15635ff..edd5d6e 100644
--- a/src/network/socket/qsymbiansocketengine.cpp
+++ b/src/network/socket/qsymbiansocketengine.cpp
@@ -196,8 +196,14 @@ bool QSymbianSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType so
#ifdef QNATIVESOCKETENGINE_DEBUG
qDebug() << "QSymbianSocketEnginePrivate::createNewSocket - _q_networksession was set" << err;
#endif
- } else
- err = nativeSocket.Open(socketServer, family, type, protocol); //TODO: FIXME - deprecated API, make sure we always have a connection instead
+ } else {
+#ifdef QNATIVESOCKETENGINE_DEBUG
+ qDebug() << "QSymbianSocketEnginePrivate::createNewSocket - _q_networksession was not set, using implicit connection";
+#endif
+ // using implicit connection allows localhost connections without starting any RConnection, see QTBUG-16155 and QTBUG-16843
+ // when a remote address is used, socket server will start the system default connection if there is no route.
+ err = nativeSocket.Open(socketServer, family, type, protocol);
+ }
if (err != KErrNone) {
switch (err) {
@@ -564,12 +570,12 @@ bool QSymbianSocketEngine::connectToHostByName(const QString &name, quint16 port
If there's a connection activity on the socket, process it. Then
notify our parent if there really was activity.
*/
-void QSymbianSocketEngine::connectionNotification()
+void QSymbianSocketEngine::connectionComplete()
{
- // FIXME check if we really need to do it like that in Symbian
Q_D(QSymbianSocketEngine);
Q_ASSERT(state() == QAbstractSocket::ConnectingState);
+ // as it was a non blocking connect, call again to find the result.
connectToHost(d->peerAddress, d->peerPort);
if (state() != QAbstractSocket::ConnectingState) {
// we changed states
@@ -906,7 +912,6 @@ qint64 QSymbianSocketEngine::writeDatagram(const char *data, qint64 len,
return sentBytes();
}
-// FIXME check where the native socket engine called that..
bool QSymbianSocketEnginePrivate::fetchConnectionParameters()
{
localPort = 0;
@@ -990,9 +995,15 @@ void QSymbianSocketEngine::close()
d->asyncSelect = 0;
}
- //TODO: call nativeSocket.Shutdown(EImmediate) in some cases?
+ //RSocket::Shutdown(EImmediate) performs a fast disconnect. For TCP,
+ //this would mean sending RST rather than FIN so we don't do that.
+ //Qt's disconnectFromHost() API doesn't expose this choice.
+ //RSocket::Close will internally do a normal shutdown of the socket.
if (d->socketType == QAbstractSocket::UdpSocket) {
- //TODO: Close hangs without this, but only for UDP - why?
+ //RSocket::Close has been observed to block for a long time with
+ //UDP sockets. Doing an immediate shutdown first works around this
+ //problem. Since UDP is connectionless, there should be no difference
+ //at the network interface.
TRequestStatus stat;
d->nativeSocket.Shutdown(RSocket::EImmediate, stat);
User::WaitForRequest(stat);
@@ -1189,7 +1200,6 @@ int QSymbianSocketEnginePrivate::nativeSelect(int timeout, bool checkRead, bool
#endif
}
if (err) {
- //TODO: avoidable cast?
//set the error here, because read won't always return the same error again as select.
const_cast<QSymbianSocketEnginePrivate*>(this)->setError(err);
//restart asynchronous notifier (only one IOCTL allowed at a time)
@@ -1265,7 +1275,7 @@ bool QSymbianSocketEnginePrivate::multicastGroupMembershipHelper(const QHostAddr
QNetworkInterface QSymbianSocketEngine::multicastInterface() const
{
- //TODO
+ //### symbian 3 has no API equivalent to this
const Q_D(QSymbianSocketEngine);
Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::multicastInterface(), QNetworkInterface());
Q_CHECK_TYPE(QSymbianSocketEngine::multicastInterface(), QAbstractSocket::UdpSocket, QNetworkInterface());
@@ -1274,7 +1284,8 @@ QNetworkInterface QSymbianSocketEngine::multicastInterface() const
bool QSymbianSocketEngine::setMulticastInterface(const QNetworkInterface &iface)
{
- //TODO - this is possibly a unix'ism as the RConnection on which the socket was created is probably controlling this
+ //### symbian 3 has no API equivalent to this
+ //this is possibly a unix'ism as the RConnection on which the socket was created is probably controlling this
Q_D(QSymbianSocketEngine);
Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setMulticastInterface(), false);
Q_CHECK_TYPE(QSymbianSocketEngine::setMulticastInterface(), QAbstractSocket::UdpSocket, false);
@@ -1711,7 +1722,7 @@ void QAsyncSelect::run()
if (engine && engine->isWriteNotificationEnabled()
&& ((m_selectBuf() & KSockSelectWrite) || iStatus != KErrNone)) {
if (engine->state() == QAbstractSocket::ConnectingState)
- engine->connectionNotification();
+ engine->connectionComplete();
else
engine->writeNotification();
}
diff --git a/src/network/socket/qsymbiansocketengine_p.h b/src/network/socket/qsymbiansocketengine_p.h
index 81156fc..3b39096 100644
--- a/src/network/socket/qsymbiansocketengine_p.h
+++ b/src/network/socket/qsymbiansocketengine_p.h
@@ -136,10 +136,7 @@ public:
Q_INVOKABLE void startNotifications();
-public Q_SLOTS:
- // TODO: Why do we do this? This is private Qt implementation stuff anyway, no need for it
- // non-virtual override;
- void connectionNotification();
+ void connectionComplete();
private:
Q_DECLARE_PRIVATE(QSymbianSocketEngine)
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 599c3f6..9a137a6 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -68,7 +68,7 @@
#endif
QT_BEGIN_NAMESPACE
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES)
#define kSecTrustSettingsDomainSystem 2 // so we do not need to include the header file
PtrSecCertificateGetData QSslSocketPrivate::ptrSecCertificateGetData = 0;
PtrSecTrustSettingsCopyCertificates QSslSocketPrivate::ptrSecTrustSettingsCopyCertificates = 0;
@@ -532,7 +532,7 @@ void QSslSocketPrivate::ensureCiphersAndCertsLoaded()
resetDefaultCiphers();
//load symbols needed to receive certificates from system store
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES)
QLibrary securityLib("/System/Library/Frameworks/Security.framework/Versions/Current/Security");
if (securityLib.load()) {
ptrSecCertificateGetData = (PtrSecCertificateGetData) securityLib.resolve("SecCertificateGetData");
@@ -813,7 +813,7 @@ QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
timer.start();
#endif
QList<QSslCertificate> systemCerts;
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES)
CFArrayRef cfCerts;
OSStatus status = 1;
@@ -1338,9 +1338,9 @@ bool QSslSocketBackendPrivate::startHandshake()
sslErrors.clear();
}
- // if we have a max read buffer size, reset the plain socket's to 16k
+ // if we have a max read buffer size, reset the plain socket's to 32k
if (readBufferMaxSize)
- plainSocket->setReadBufferSize(16384);
+ plainSocket->setReadBufferSize(32768);
connectionEncrypted = true;
emit q->encrypted();
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 86ecba0..ee6361f 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -69,9 +69,11 @@ QT_BEGIN_NAMESPACE
#if defined(Q_OS_MAC)
#include <Security/SecCertificate.h>
#include <CoreFoundation/CFArray.h>
+#ifndef QT_NO_CORESERVICES
typedef OSStatus (*PtrSecCertificateGetData)(SecCertificateRef, CSSM_DATA_PTR);
typedef OSStatus (*PtrSecTrustSettingsCopyCertificates)(int, CFArrayRef*);
typedef OSStatus (*PtrSecTrustCopyAnchorCertificates)(CFArrayRef*);
+#endif
#elif defined(Q_OS_WIN)
#include <windows.h>
#include <wincrypt.h>
@@ -132,7 +134,7 @@ public:
static void addDefaultCaCertificate(const QSslCertificate &cert);
static void addDefaultCaCertificates(const QList<QSslCertificate> &certs);
-#if defined(Q_OS_MAC)
+#if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES)
static PtrSecCertificateGetData ptrSecCertificateGetData;
static PtrSecTrustSettingsCopyCertificates ptrSecTrustSettingsCopyCertificates;
static PtrSecTrustCopyAnchorCertificates ptrSecTrustCopyAnchorCertificates;
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 3ac759c..52450b6 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -90,6 +90,12 @@
QT_BEGIN_NAMESPACE
+inline static bool isPowerOfTwo(int x)
+{
+ // Assumption: x >= 1
+ return x == (x & -x);
+}
+
#if defined(Q_WS_WIN)
extern Q_GUI_EXPORT bool qt_cleartype_enabled;
#endif
@@ -201,6 +207,15 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
ctx->d_func()->bindTexture(texImage, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
+#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2)
+ QGLFunctions funcs(QGLContext::currentContext());
+ bool npotSupported = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures);
+ bool isNpot = !isPowerOfTwo(texImage.size().width())
+ || !isPowerOfTwo(texImage.size().height());
+ if (isNpot && !npotSupported) {
+ qWarning("GL2 Paint Engine: This system does not support the REPEAT wrap mode for non-power-of-two textures.");
+ }
+#endif
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
@@ -233,6 +248,15 @@ void QGL2PaintEngineExPrivate::updateBrushTexture()
QGLTexture *tex = ctx->d_func()->bindTexture(currentBrushPixmap, GL_TEXTURE_2D, GL_RGBA,
QGLContext::InternalBindOption |
QGLContext::CanFlipNativePixmapBindOption);
+#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2)
+ QGLFunctions funcs(QGLContext::currentContext());
+ bool npotSupported = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures);
+ bool isNpot = !isPowerOfTwo(currentBrushPixmap.size().width())
+ || !isPowerOfTwo(currentBrushPixmap.size().height());
+ if (isNpot && !npotSupported) {
+ qWarning("GL2 Paint Engine: This system does not support the REPEAT wrap mode for non-power-of-two textures.");
+ }
+#endif
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
textureInvertedY = tex->options & QGLContext::InvertedYBindOption ? -1 : 1;
}
@@ -1362,14 +1386,11 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
ensureActive();
d->transferMode(ImageDrawingMode);
- QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption|QGLContext::CanFlipNativePixmapBindOption;
-#ifdef QGL_USE_TEXTURE_POOL
- bindOptions |= QGLContext::TemporarilyCachedBindOption;
-#endif
-
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
QGLTexture *texture =
- ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA, bindOptions);
+ ctx->d_func()->bindTexture(pixmap, GL_TEXTURE_2D, GL_RGBA,
+ QGLContext::InternalBindOption
+ | QGLContext::CanFlipNativePixmapBindOption);
GLfloat top = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.top()) : src.top();
GLfloat bottom = texture->options & QGLContext::InvertedYBindOption ? (pixmap.height() - src.bottom()) : src.bottom();
@@ -1381,12 +1402,6 @@ void QGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixmap, c
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, texture->id);
d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);
-
- if (texture->options&QGLContext::TemporarilyCachedBindOption) {
- // pixmap was temporarily cached as a QImage texture by pooling system
- // and should be destroyed immediately
- QGLTextureCache::instance()->remove(ctx, texture->id);
- }
}
void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const QRectF& src,
@@ -1411,23 +1426,12 @@ void QGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, const
glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
- QGLContext::BindOptions bindOptions = QGLContext::InternalBindOption;
-#ifdef QGL_USE_TEXTURE_POOL
- bindOptions |= QGLContext::TemporarilyCachedBindOption;
-#endif
-
- QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, bindOptions);
+ QGLTexture *texture = ctx->d_func()->bindTexture(image, GL_TEXTURE_2D, GL_RGBA, QGLContext::InternalBindOption);
GLuint id = texture->id;
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
-
- if (texture->options&QGLContext::TemporarilyCachedBindOption) {
- // image was temporarily cached by texture pooling system
- // and should be destroyed immediately
- QGLTextureCache::instance()->remove(ctx, texture->id);
- }
}
void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
@@ -1782,6 +1786,15 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp
glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
glBindTexture(GL_TEXTURE_2D, cache->texture());
+#if !defined(QT_NO_DEBUG) && defined(QT_OPENGL_ES_2)
+ QGLFunctions funcs(QGLContext::currentContext());
+ bool npotSupported = funcs.hasOpenGLFeature(QGLFunctions::NPOTTextures);
+ bool isNpot = !isPowerOfTwo(cache->width())
+ || !isPowerOfTwo(cache->height());
+ if (isNpot && !npotSupported) {
+ qWarning("GL2 Paint Engine: This system does not support the REPEAT wrap mode for non-power-of-two textures.");
+ }
+#endif
updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
diff --git a/src/opengl/gl2paintengineex/qtriangulator.cpp b/src/opengl/gl2paintengineex/qtriangulator.cpp
index 7c3be2b..5293eff 100644
--- a/src/opengl/gl2paintengineex/qtriangulator.cpp
+++ b/src/opengl/gl2paintengineex/qtriangulator.cpp
@@ -1309,6 +1309,9 @@ inline void QRingBuffer<T>::enqueue(const T &x)
//============================================================================//
// QTriangulator //
//============================================================================//
+
+typedef QRBTree<int>::Node *QRBTreeIntNodePointer;
+
template<typename T>
class QTriangulator
{
@@ -1775,7 +1778,7 @@ bool QTriangulator<T>::ComplexToSimple::edgeIsLeftOfEdge(int leftEdgeIndex, int
}
template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
+QRBTreeIntNodePointer QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex) const
{
QRBTree<int>::Node *current = m_edgeList.root;
QRBTree<int>::Node *result = 0;
@@ -1791,7 +1794,7 @@ QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edge
}
template <typename T>
-QRBTree<int>::Node *QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
+QRBTreeIntNodePointer QTriangulator<T>::ComplexToSimple::searchEdgeLeftOf(int edgeIndex, QRBTree<int>::Node *after) const
{
if (!m_edgeList.root)
return after;
diff --git a/src/opengl/opengl.pro b/src/opengl/opengl.pro
index e7c1c44..ce1a5d2 100644
--- a/src/opengl/opengl.pro
+++ b/src/opengl/opengl.pro
@@ -157,10 +157,10 @@ embedded {
}
symbian {
- DEFINES += QGL_USE_TEXTURE_POOL QGL_NO_PRESERVED_SWAP
+ DEFINES += QGL_NO_PRESERVED_SWAP
SOURCES -= qpixmapdata_gl.cpp
SOURCES += qgl_symbian.cpp \
- qpixmapdata_poolgl.cpp \
+ qpixmapdata_symbiangl.cpp \
qglpixelbuffer_egl.cpp \
qgl_egl.cpp \
qgltexturepool.cpp
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index 5f5864d..9520b2b 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -100,7 +100,8 @@
#if defined(QT_OPENGL_ES) && !defined(QT_NO_EGL)
#include <EGL/egl.h>
#endif
-#ifdef QGL_USE_TEXTURE_POOL
+
+#ifdef Q_OS_SYMBIAN
#include <private/qgltexturepool_p.h>
#endif
@@ -2042,10 +2043,6 @@ struct DDSFormat {
the pixmap/image that it stems from, e.g. installing destruction
hooks in them.
- \omitvalue TemporarilyCachedBindOption Used by paint engines on some
- platforms to indicate that the pixmap or image texture is possibly
- cached only temporarily and must be destroyed immediately after the use.
-
\omitvalue InternalBindOption
*/
@@ -2550,7 +2547,8 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
#endif
const QImage &constRef = img; // to avoid detach in bits()...
-#ifdef QGL_USE_TEXTURE_POOL
+#ifdef Q_OS_SYMBIAN
+ // On Symbian we always use texture pool to reserve the texture
QGLTexturePool::instance()->createPermanentTexture(tx_id,
target,
0, internalFormat,
@@ -2562,6 +2560,7 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
glTexImage2D(target, 0, internalFormat, img.width(), img.height(), 0, externalFormat,
pixel_type, constRef.bits());
#endif
+
#if defined(QT_OPENGL_ES_2)
if (genMipmap)
glGenerateMipmap(target);
@@ -2585,6 +2584,13 @@ QGLTexture* QGLContextPrivate::bindTexture(const QImage &image, GLenum target, G
QGLTexture *texture = new QGLTexture(q, tx_id, target, options);
QGLTextureCache::instance()->insert(q, key, texture, cost);
+#ifdef Q_OS_SYMBIAN
+ // Store the key so that QGLTexturePool
+ // is able to release this texture when needed.
+ texture->boundKey = key;
+ // And append to LRU list
+ QGLTexturePool::instance()->useTexture(texture);
+#endif
return texture;
}
@@ -2665,6 +2671,20 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
#endif
if (!texture) {
+#ifdef Q_OS_SYMBIAN
+ // On Symbian pixmaps are backed up by native CFbsBitmap
+ // which can be shared across processes. QVolatileImage wraps
+ // it and provides locking mechanism to pixel access.
+ QVolatileImage volatileImage = pd->toVolatileImage();
+ if (volatileImage.isNull()) { // TODO: raster graphics system don't provide volatile image (yet)
+ // NOTE! On Symbian raster graphics system QPixmap::toImage() makes deep copy
+ texture = bindTexture(pixmap.toImage(), target, format, key, options);
+ } else {
+ volatileImage.beginDataAccess();
+ texture = bindTexture(volatileImage.imageRef(), target, format, key, options);
+ volatileImage.endDataAccess(true);
+ }
+#else
QImage image = pixmap.toImage();
// If the system depth is 16 and the pixmap doesn't have an alpha channel
// then we convert it to RGB16 in the hope that it gets uploaded as a 16
@@ -2672,6 +2692,7 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target,
if (pixmap.depth() == 16 && !image.hasAlphaChannel() )
image = image.convertToFormat(QImage::Format_RGB16);
texture = bindTexture(image, target, format, key, options);
+#endif
}
// NOTE: bindTexture(const QImage&, GLenum, GLint, const qint64, bool) should never return null
Q_ASSERT(texture);
@@ -6063,4 +6084,26 @@ QSize QGLTexture::bindCompressedTexturePVR(const char *buf, int len)
#undef ctx
+#ifdef Q_OS_SYMBIAN
+void QGLTexture::freeTexture()
+{
+ if (!id)
+ return;
+
+ if (inTexturePool)
+ QGLTexturePool::instance()->detachTexture(this);
+
+ if (boundPixmap)
+ boundPixmap->releaseNativeImageHandle();
+
+ if (options & QGLContext::MemoryManagedBindOption) {
+ Q_ASSERT(context);
+ context->d_ptr->texture_destroyer->emitFreeTexture(context, 0, id);
+ }
+
+ id = 0;
+ boundKey = 0;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h
index 1f4eda3..3d31242 100644
--- a/src/opengl/qgl.h
+++ b/src/opengl/qgl.h
@@ -341,7 +341,6 @@ public:
MemoryManagedBindOption = 0x0010, // internal flag
CanFlipNativePixmapBindOption = 0x0020, // internal flag
- TemporarilyCachedBindOption = 0x0040, // internal flag
DefaultBindOption = LinearFilteringBindOption
| InvertedYBindOption
diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm
index d4b2a40..c3dac87 100644
--- a/src/opengl/qgl_mac.mm
+++ b/src/opengl/qgl_mac.mm
@@ -114,7 +114,6 @@ extern int qt_mac_pixmap_get_bytes_per_line(const QPixmap *);
extern RgnHandle qt_mac_get_rgn(); //qregion_mac.cpp
extern void qt_mac_dispose_rgn(RgnHandle); //qregion_mac.cpp
extern QRegion qt_mac_convert_mac_region(RgnHandle); //qregion_mac.cpp
-extern void qt_mac_to_pascal_string(QString s, Str255 str, TextEncoding encoding=0, int len=-1); //qglobal.cpp
/*
QGLTemporaryContext implementation
diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h
index 4748521..de349a7 100644
--- a/src/opengl/qgl_p.h
+++ b/src/opengl/qgl_p.h
@@ -64,6 +64,12 @@
#include "qcache.h"
#include "qglpaintdevice_p.h"
+#ifdef Q_OS_SYMBIAN
+#include "qgltexturepool_p.h"
+
+class QGLPixmapData;
+#endif
+
#ifndef QT_NO_EGL
#include <QtGui/private/qegl_p.h>
#endif
@@ -562,10 +568,21 @@ public:
options(opt)
#if defined(Q_WS_X11)
, boundPixmap(0)
+#elif defined(Q_OS_SYMBIAN)
+ , boundPixmap(0)
+ , boundKey(0)
+ , nextLRU(0)
+ , prevLRU(0)
+ , inLRU(false)
+ , failedToAlloc(false)
+ , inTexturePool(false)
#endif
{}
~QGLTexture() {
+#ifdef Q_OS_SYMBIAN
+ freeTexture();
+#else
if (options & QGLContext::MemoryManagedBindOption) {
Q_ASSERT(context);
#if !defined(Q_WS_X11)
@@ -573,7 +590,8 @@ public:
#endif
context->d_ptr->texture_destroyer->emitFreeTexture(context, boundPixmap, id);
}
- }
+#endif
+ }
QGLContext *context;
GLuint id;
@@ -593,6 +611,19 @@ public:
(const char *buf, int len, const char *format = 0);
QSize bindCompressedTextureDDS(const char *buf, int len);
QSize bindCompressedTexturePVR(const char *buf, int len);
+
+#ifdef Q_OS_SYMBIAN
+ void freeTexture();
+
+ QGLPixmapData* boundPixmap;
+ qint64 boundKey;
+
+ QGLTexture *nextLRU;
+ QGLTexture *prevLRU;
+ mutable bool inLRU;
+ mutable bool failedToAlloc;
+ mutable bool inTexturePool;
+#endif
};
struct QGLTextureCacheKey {
diff --git a/src/opengl/qgltexturepool.cpp b/src/opengl/qgltexturepool.cpp
index d809328..9ad66f2 100644
--- a/src/opengl/qgltexturepool.cpp
+++ b/src/opengl/qgltexturepool.cpp
@@ -41,6 +41,7 @@
#include "qgltexturepool_p.h"
#include "qpixmapdata_gl_p.h"
+#include "qgl_p.h"
QT_BEGIN_NAMESPACE
@@ -53,8 +54,8 @@ class QGLTexturePoolPrivate
public:
QGLTexturePoolPrivate() : lruFirst(0), lruLast(0) {}
- QGLPixmapData *lruFirst;
- QGLPixmapData *lruLast;
+ QGLTexture *lruFirst;
+ QGLTexture *lruLast;
};
QGLTexturePool::QGLTexturePool()
@@ -73,36 +74,36 @@ QGLTexturePool *QGLTexturePool::instance()
return qt_gl_texture_pool;
}
-GLuint QGLTexturePool::createTextureForPixmap(GLenum target,
+GLuint QGLTexturePool::createTexture(GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data)
+ QGLTexture *texture)
{
- GLuint texture;
- glGenTextures(1, &texture);
- glBindTexture(target, texture);
+ GLuint tex;
+ glGenTextures(1, &tex);
+ glBindTexture(target, tex);
do {
glTexImage2D(target, level, internalformat, width, height, 0, format, type, 0);
GLenum error = glGetError();
if (error == GL_NO_ERROR) {
- if (data)
- moveToHeadOfLRU(data);
- return texture;
+ if (texture)
+ moveToHeadOfLRU(texture);
+ return tex;
} else if (error != GL_OUT_OF_MEMORY) {
qWarning("QGLTexturePool: cannot create temporary texture because of invalid params");
return 0;
}
- } while (reclaimSpace(internalformat, width, height, format, type, data));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
+ } while (reclaimSpace(internalformat, width, height, format, type, texture));
+ qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d texture",
width, height);
return 0;
}
-bool QGLTexturePool::createPermanentTexture(GLuint texture,
+bool QGLTexturePool::createPermanentTexture(GLuint tex,
GLenum target,
GLint level,
GLint internalformat,
@@ -112,7 +113,7 @@ bool QGLTexturePool::createPermanentTexture(GLuint texture,
GLenum type,
const GLvoid *data)
{
- glBindTexture(target, texture);
+ glBindTexture(target, tex);
do {
glTexImage2D(target, level, internalformat, width, height, 0, format, type, data);
@@ -124,32 +125,21 @@ bool QGLTexturePool::createPermanentTexture(GLuint texture,
return false;
}
} while (reclaimSpace(internalformat, width, height, format, type, 0));
- qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d pixmap",
+ qWarning("QGLTexturePool: cannot reclaim sufficient space for a %dx%d texture",
width, height);
return 0;
}
-void QGLTexturePool::releaseTexture(QGLPixmapData *data, GLuint texture)
+void QGLTexturePool::useTexture(QGLTexture *texture)
{
- // Very simple strategy at the moment: just destroy the texture.
- if (data)
- removeFromLRU(data);
-
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &texture);
- }
-}
-
-void QGLTexturePool::useTexture(QGLPixmapData *data)
-{
- moveToHeadOfLRU(data);
+ moveToHeadOfLRU(texture);
+ texture->inTexturePool = true;
}
-void QGLTexturePool::detachTexture(QGLPixmapData *data)
+void QGLTexturePool::detachTexture(QGLTexture *texture)
{
- removeFromLRU(data);
+ removeFromLRU(texture);
+ texture->inTexturePool = false;
}
bool QGLTexturePool::reclaimSpace(GLint internalformat,
@@ -157,7 +147,7 @@ bool QGLTexturePool::reclaimSpace(GLint internalformat,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data)
+ QGLTexture *texture)
{
Q_UNUSED(internalformat); // For future use in picking the best texture to eject.
Q_UNUSED(width);
@@ -167,19 +157,22 @@ bool QGLTexturePool::reclaimSpace(GLint internalformat,
bool succeeded = false;
bool wasInLRU = false;
- if (data) {
- wasInLRU = data->inLRU;
- moveToHeadOfLRU(data);
+ if (texture) {
+ wasInLRU = texture->inLRU;
+ moveToHeadOfLRU(texture);
}
- QGLPixmapData *lrudata = pixmapLRU();
- if (lrudata && lrudata != data) {
- lrudata->reclaimTexture();
+ QGLTexture *lrutexture = textureLRU();
+ if (lrutexture && lrutexture != texture) {
+ if (lrutexture->boundPixmap)
+ lrutexture->boundPixmap->reclaimTexture();
+ else
+ QGLTextureCache::instance()->remove(lrutexture->boundKey);
succeeded = true;
}
- if (data && !wasInLRU)
- removeFromLRU(data);
+ if (texture && !wasInLRU)
+ removeFromLRU(texture);
return succeeded;
}
@@ -187,55 +180,58 @@ bool QGLTexturePool::reclaimSpace(GLint internalformat,
void QGLTexturePool::hibernate()
{
Q_D(QGLTexturePool);
- QGLPixmapData *pd = d->lruLast;
- while (pd) {
- QGLPixmapData *prevLRU = pd->prevLRU;
- pd->inTexturePool = false;
- pd->inLRU = false;
- pd->nextLRU = 0;
- pd->prevLRU = 0;
- pd->hibernate();
- pd = prevLRU;
+ QGLTexture *texture = d->lruLast;
+ while (texture) {
+ QGLTexture *prevLRU = texture->prevLRU;
+ texture->inTexturePool = false;
+ texture->inLRU = false;
+ texture->nextLRU = 0;
+ texture->prevLRU = 0;
+ if (texture->boundPixmap)
+ texture->boundPixmap->hibernate();
+ else
+ QGLTextureCache::instance()->remove(texture->boundKey);
+ texture = prevLRU;
}
d->lruFirst = 0;
d->lruLast = 0;
}
-void QGLTexturePool::moveToHeadOfLRU(QGLPixmapData *data)
+void QGLTexturePool::moveToHeadOfLRU(QGLTexture *texture)
{
Q_D(QGLTexturePool);
- if (data->inLRU) {
- if (!data->prevLRU)
+ if (texture->inLRU) {
+ if (!texture->prevLRU)
return; // Already at the head of the list.
- removeFromLRU(data);
+ removeFromLRU(texture);
}
- data->inLRU = true;
- data->nextLRU = d->lruFirst;
- data->prevLRU = 0;
+ texture->inLRU = true;
+ texture->nextLRU = d->lruFirst;
+ texture->prevLRU = 0;
if (d->lruFirst)
- d->lruFirst->prevLRU = data;
+ d->lruFirst->prevLRU = texture;
else
- d->lruLast = data;
- d->lruFirst = data;
+ d->lruLast = texture;
+ d->lruFirst = texture;
}
-void QGLTexturePool::removeFromLRU(QGLPixmapData *data)
+void QGLTexturePool::removeFromLRU(QGLTexture *texture)
{
Q_D(QGLTexturePool);
- if (!data->inLRU)
+ if (!texture->inLRU)
return;
- if (data->nextLRU)
- data->nextLRU->prevLRU = data->prevLRU;
+ if (texture->nextLRU)
+ texture->nextLRU->prevLRU = texture->prevLRU;
else
- d->lruLast = data->prevLRU;
- if (data->prevLRU)
- data->prevLRU->nextLRU = data->nextLRU;
+ d->lruLast = texture->prevLRU;
+ if (texture->prevLRU)
+ texture->prevLRU->nextLRU = texture->nextLRU;
else
- d->lruFirst = data->nextLRU;
- data->inLRU = false;
+ d->lruFirst = texture->nextLRU;
+ texture->inLRU = false;
}
-QGLPixmapData *QGLTexturePool::pixmapLRU()
+QGLTexture *QGLTexturePool::textureLRU()
{
Q_D(QGLTexturePool);
return d->lruLast;
diff --git a/src/opengl/qgltexturepool_p.h b/src/opengl/qgltexturepool_p.h
index 27b730c..07f9700 100644
--- a/src/opengl/qgltexturepool_p.h
+++ b/src/opengl/qgltexturepool_p.h
@@ -58,7 +58,7 @@
QT_BEGIN_NAMESPACE
-class QGLPixmapData;
+class QGLTexture;
class QGLTexturePoolPrivate;
class QGLTexturePool
@@ -70,18 +70,18 @@ public:
static QGLTexturePool *instance();
// Create a new texture with the specified parameters and associate
- // it with "data". The QGLPixmapData will be notified when the
+ // it with "texture". The QGLTexture will be notified when the
// texture needs to be reclaimed by the pool.
//
// This function will call reclaimSpace() when texture creation fails.
- GLuint createTextureForPixmap(GLenum target,
+ GLuint createTexture(GLenum target,
GLint level,
GLint internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data);
+ QGLTexture *texture);
// Create a permanent texture with the specified parameters.
// If there is insufficient space for the texture,
@@ -100,40 +100,37 @@ public:
GLenum type,
const GLvoid *data);
- // Release a texture that is no longer required.
- void releaseTexture(QGLPixmapData *data, GLuint texture);
-
- // Notify the pool that a QGLPixmapData object is using
+ // Notify the pool that a QGLTexture object is using
// an texture again. This allows the pool to move the texture
- // within a least-recently-used list of QGLPixmapData objects.
- void useTexture(QGLPixmapData *data);
+ // within a least-recently-used list of QGLTexture objects.
+ void useTexture(QGLTexture *texture);
// Notify the pool that the texture associated with a
- // QGLPixmapData is being detached from the pool. The caller
+ // QGLTexture is being detached from the pool. The caller
// will become responsible for calling glDeleteTextures().
- void detachTexture(QGLPixmapData *data);
+ void detachTexture(QGLTexture *texture);
// Reclaim space for an image allocation with the specified parameters.
// Returns true if space was reclaimed, or false if there is no
- // further space that can be reclaimed. The "data" parameter
- // indicates the pixmap that is trying to obtain space which should
+ // further space that can be reclaimed. The "texture" parameter
+ // indicates the texture that is trying to obtain space which should
// not itself be reclaimed.
bool reclaimSpace(GLint internalformat,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
- QGLPixmapData *data);
+ QGLTexture *data);
- // Hibernate the image pool because the context is about to be
+ // Hibernate the texture pool because the context is about to be
// destroyed. All textures left in the pool should be released.
void hibernate();
protected:
- // Helper functions for managing the LRU list of QGLPixmapData objects.
- void moveToHeadOfLRU(QGLPixmapData *data);
- void removeFromLRU(QGLPixmapData *data);
- QGLPixmapData *pixmapLRU();
+ // Helper functions for managing the LRU list of QGLTexture objects.
+ void moveToHeadOfLRU(QGLTexture *texture);
+ void removeFromLRU(QGLTexture *texture);
+ QGLTexture *textureLRU();
private:
QScopedPointer<QGLTexturePoolPrivate> d_ptr;
diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp
index 8530b52..265bf22 100644
--- a/src/opengl/qgraphicssystem_gl.cpp
+++ b/src/opengl/qgraphicssystem_gl.cpp
@@ -55,9 +55,6 @@
#if defined(Q_OS_SYMBIAN)
#include <QtGui/private/qapplication_p.h>
-#endif
-
-#ifdef QGL_USE_TEXTURE_POOL
#include "private/qgltexturepool_p.h"
#endif
diff --git a/src/opengl/qpixmapdata_gl_p.h b/src/opengl/qpixmapdata_gl_p.h
index 909f264..bf1a303 100644
--- a/src/opengl/qpixmapdata_gl_p.h
+++ b/src/opengl/qpixmapdata_gl_p.h
@@ -70,12 +70,6 @@ class QGLFramebufferObject;
class QGLFramebufferObjectFormat;
class QGLPixmapData;
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd);
-void qt_gl_unregister_pixmap(QGLPixmapData *pd);
-void qt_gl_hibernate_pixmaps();
-#endif
-
#ifdef Q_OS_SYMBIAN
class QNativeImageHandleProvider;
#endif
@@ -143,7 +137,7 @@ public:
GLuint bind(bool copyBack = true) const;
QGLTexture *texture() const;
-#ifdef QGL_USE_TEXTURE_POOL
+#ifdef Q_OS_SYMBIAN
void destroyTexture();
// Detach this image from the image pool.
void detachTextureFromPool();
@@ -158,9 +152,8 @@ public:
// texture objects to reuse storage.
void reclaimTexture();
void forceToImage();
-#endif
-#ifdef Q_OS_SYMBIAN
+ QVolatileImage toVolatileImage() const { return m_source; }
QImage::Format idealFormat(QImage &image, Qt::ImageConversionFlags flags);
void* toNativeType(NativeType type);
void fromNativeType(void* pixmap, NativeType type);
@@ -218,23 +211,6 @@ private:
mutable QGLPixmapGLPaintDevice m_glDevice;
-#ifdef QGL_USE_TEXTURE_POOL
- QGLPixmapData *nextLRU;
- QGLPixmapData *prevLRU;
- mutable bool inLRU;
- mutable bool failedToAlloc;
- mutable bool inTexturePool;
-
- QGLPixmapData *next;
- QGLPixmapData *prev;
-
- friend class QGLTexturePool;
-
- friend void qt_gl_register_pixmap(QGLPixmapData *pd);
- friend void qt_gl_unregister_pixmap(QGLPixmapData *pd);
- friend void qt_gl_hibernate_pixmaps();
-#endif
-
friend class QGLPixmapGLPaintDevice;
friend class QMeeGoPixmapData;
friend class QMeeGoLivePixmapData;
diff --git a/src/opengl/qpixmapdata_poolgl.cpp b/src/opengl/qpixmapdata_symbiangl.cpp
index 5dd7b09..ab8a9e8 100644
--- a/src/opengl/qpixmapdata_poolgl.cpp
+++ b/src/opengl/qpixmapdata_symbiangl.cpp
@@ -248,43 +248,14 @@ QGLPixmapData::QGLPixmapData(PixelType type)
, m_dirty(false)
, m_hasFillColor(false)
, m_hasAlpha(false)
- , inLRU(false)
- , failedToAlloc(false)
- , inTexturePool(false)
{
setSerialNumber(++qt_gl_pixmap_serial);
m_glDevice.setPixmapData(this);
-
- qt_gl_register_pixmap(this);
}
QGLPixmapData::~QGLPixmapData()
{
delete m_engine;
-
- destroyTexture();
- qt_gl_unregister_pixmap(this);
-}
-
-void QGLPixmapData::destroyTexture()
-{
- if (inTexturePool) {
- QGLTexturePool *pool = QGLTexturePool::instance();
- if (m_texture.id)
- pool->releaseTexture(this, m_texture.id);
- } else {
- if (m_texture.id) {
- QGLWidget *shareWidget = qt_gl_share_widget();
- if (shareWidget) {
- QGLShareContextScope ctx(shareWidget->context());
- glDeleteTextures(1, &m_texture.id);
- }
- }
- }
- m_texture.id = 0;
- inTexturePool = false;
-
- releaseNativeImageHandle();
}
QPixmapData *QGLPixmapData::createCompatiblePixmapData() const
@@ -299,11 +270,13 @@ bool QGLPixmapData::isValid() const
bool QGLPixmapData::isValidContext(const QGLContext *ctx) const
{
- if (ctx == m_ctx)
- return true;
-
- const QGLContext *share_ctx = qt_gl_share_widget()->context();
- return ctx == share_ctx || QGLContext::areSharing(ctx, share_ctx);
+ // On Symbian, we usually want to treat QGLPixmapData as
+ // raster pixmap data because that's well known and tested
+ // execution path which is used on other platforms as well.
+ // That's why if source pixels are valid we return false
+ // to simulate raster pixmaps. Only QPixmaps created from
+ // SgImage will enable usage of QGLPixmapData.
+ return false;
}
void QGLPixmapData::resize(int width, int height)
@@ -354,27 +327,25 @@ void QGLPixmapData::ensureCreated() const
if (!m_source.isNull() && m_source.format() == QImage::Format_RGB16)
type = GL_UNSIGNED_SHORT_5_6_5;
- m_texture.options &= ~QGLContext::MemoryManagedBindOption;
-
if (!m_texture.id) {
- m_texture.id = QGLTexturePool::instance()->createTextureForPixmap(
+ m_texture.id = QGLTexturePool::instance()->createTexture(
target,
0, internal_format,
w, h,
external_format,
type,
- const_cast<QGLPixmapData*>(this));
+ &m_texture);
if (!m_texture.id) {
- failedToAlloc = true;
+ m_texture.failedToAlloc = true;
return;
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- inTexturePool = true;
- } else if (inTexturePool) {
+ m_texture.inTexturePool = true;
+ } else if (m_texture.inTexturePool) {
glBindTexture(target, m_texture.id);
- QGLTexturePool::instance()->useTexture(const_cast<QGLPixmapData*>(this));
+ QGLTexturePool::instance()->useTexture(&m_texture);
}
if (!m_source.isNull() && m_texture.id) {
@@ -754,15 +725,8 @@ void QGLPixmapData::copyBackFromRenderFbo(bool keepCurrentFboBound) const
bool QGLPixmapData::useFramebufferObjects() const
{
-#ifdef Q_OS_SYMBIAN
- // We don't want to use FBOs on Symbian
+ // We don't use FBOs on Symbian for now
return false;
-#else
- return QGLFramebufferObject::hasOpenGLFramebufferObjects()
- && QGLFramebufferObject::hasOpenGLFramebufferBlit()
- && qt_gl_preferGL2Engine()
- && (w * h > 32*32); // avoid overhead of FBOs for small pixmaps
-#endif
}
QPaintEngine* QGLPixmapData::paintEngine() const
@@ -846,39 +810,8 @@ QGLTexture* QGLPixmapData::texture() const
return &m_texture;
}
-void QGLPixmapData::detachTextureFromPool()
-{
- if (inTexturePool) {
- QGLTexturePool::instance()->detachTexture(this);
- inTexturePool = false;
- }
-}
-
-void QGLPixmapData::hibernate()
-{
- // If the image was imported (e.g, from an SgImage under Symbian), then
- // skip the hibernation, there is no sense in copying it back to main
- // memory because the data is most likely shared between several processes.
- bool skipHibernate = (m_texture.id && m_source.isNull());
-#if defined(Q_OS_SYMBIAN)
- // However we have to proceed normally if the image was retrieved via
- // a handle provider.
- skipHibernate &= !nativeImageHandleProvider;
-#endif
- if (skipHibernate)
- return;
-
- forceToImage();
- destroyTexture();
-}
-
-void QGLPixmapData::reclaimTexture()
-{
- if (!inTexturePool)
- return;
- forceToImage();
- destroyTexture();
-}
+Q_GUI_EXPORT int qt_defaultDpiX();
+Q_GUI_EXPORT int qt_defaultDpiY();
int QGLPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
{
@@ -926,6 +859,31 @@ void QGLPixmapData::forceToImage()
m_dirty = true;
}
+void QGLPixmapData::destroyTexture()
+{
+ // Destroy SgImage texture
+}
+
+void QGLPixmapData::detachTextureFromPool()
+{
+ QGLTexturePool::instance()->detachTexture(&m_texture);
+}
+
+void QGLPixmapData::hibernate()
+{
+ destroyTexture();
+}
+
+void QGLPixmapData::reclaimTexture()
+{
+ if (!m_texture.inTexturePool)
+ return;
+
+ forceToImage();
+
+ destroyTexture();
+}
+
QGLPaintDevice *QGLPixmapData::glDevice() const
{
return &m_glDevice;
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index ff55142..9ad7f6a 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -184,7 +184,7 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
class QGLGlobalShareWidget
{
public:
- QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {
+ QGLGlobalShareWidget() : refCount(0), widget(0), initializing(false) {
created = true;
}
@@ -227,8 +227,7 @@ public:
static bool cleanedUp;
static bool created;
- QGLPixmapData *firstPixmap;
- int widgetRefCount;
+ int refCount;
private:
QGLWidget *widget;
@@ -271,43 +270,6 @@ const QGLContext *qt_gl_share_context()
return 0;
}
-#ifdef QGL_USE_TEXTURE_POOL
-void qt_gl_register_pixmap(QGLPixmapData *pd)
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- pd->next = shared->firstPixmap;
- pd->prev = 0;
- if (shared->firstPixmap)
- shared->firstPixmap->prev = pd;
- shared->firstPixmap = pd;
-}
-
-void qt_gl_unregister_pixmap(QGLPixmapData *pd)
-{
- if (pd->next)
- pd->next->prev = pd->prev;
- if (pd->prev) {
- pd->prev->next = pd->next;
- } else {
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
- if (shared)
- shared->firstPixmap = pd->next;
- }
-}
-
-void qt_gl_hibernate_pixmaps()
-{
- QGLGlobalShareWidget *shared = _qt_gl_share_widget();
-
- // Scan all QGLPixmapData objects in the system and hibernate them.
- QGLPixmapData *pd = shared->firstPixmap;
- while (pd != 0) {
- pd->hibernate();
- pd = pd->next;
- }
-}
-#endif
-
struct QGLWindowSurfacePrivate
{
QGLFramebufferObject *fbo;
@@ -407,18 +369,10 @@ QGLWindowSurface::~QGLWindowSurface()
if (QGLGlobalShareWidget::cleanedUp)
return;
- --(_qt_gl_share_widget()->widgetRefCount);
-
-#ifdef QGL_USE_TEXTURE_POOL
- if (_qt_gl_share_widget()->widgetRefCount <= 0) {
- // All of the widget window surfaces have been destroyed
- // but we still have GL pixmaps active. Ask them to hibernate
- // to free up GPU resources until a widget is shown again.
- // This may eventually cause the EGLContext to be destroyed
- // because nothing in the system needs a context, which will
- // free up even more GPU resources.
- qt_gl_hibernate_pixmaps();
+ --(_qt_gl_share_widget()->refCount);
+#ifdef Q_OS_SYMBIAN
+ if (_qt_gl_share_widget()->refCount <= 0) {
// Destroy the context if necessary.
if (!qt_gl_share_widget()->context()->isSharing())
qt_destroy_gl_share_widget();
@@ -474,7 +428,7 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
ctx->create(qt_gl_share_context());
if (widget != qt_gl_share_widget())
- ++(_qt_gl_share_widget()->widgetRefCount);
+ ++(_qt_gl_share_widget()->refCount);
#ifndef QT_NO_EGL
static bool checkedForNOKSwapRegion = false;
@@ -508,6 +462,7 @@ void QGLWindowSurface::hijackWindow(QWidget *widget)
voidPtrPtr = &widgetPrivate->extraData()->glContext;
d_ptr->contexts << ctxPtrPtr;
+
#ifndef Q_OS_SYMBIAN
qDebug() << "hijackWindow() context created for" << widget << d_ptr->contexts.size();
#endif
@@ -902,7 +857,7 @@ void QGLWindowSurface::updateGeometry() {
#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes
if (d_ptr->size != geometry().size()) {
if (window() != qt_gl_share_widget())
- --(_qt_gl_share_widget()->widgetRefCount);
+ --(_qt_gl_share_widget()->refCount);
delete wd->extraData()->glContext;
wd->extraData()->glContext = 0;
diff --git a/src/openvg/qpixmapdata_vg_p.h b/src/openvg/qpixmapdata_vg_p.h
index 901bad9..18846f3 100644
--- a/src/openvg/qpixmapdata_vg_p.h
+++ b/src/openvg/qpixmapdata_vg_p.h
@@ -138,6 +138,7 @@ public:
QSize size() const { return QSize(w, h); }
#if defined(Q_OS_SYMBIAN)
+ QVolatileImage toVolatileImage() const { return source; }
void* toNativeType(NativeType type);
void fromNativeType(void* pixmap, NativeType type);
bool initFromNativeImageHandle(void *handle, const QString &type);
diff --git a/src/qt3support/dialogs/q3filedialog_mac.cpp b/src/qt3support/dialogs/q3filedialog_mac.cpp
index f82a8ac..c5db944 100644
--- a/src/qt3support/dialogs/q3filedialog_mac.cpp
+++ b/src/qt3support/dialogs/q3filedialog_mac.cpp
@@ -248,8 +248,6 @@ static const NavEventUPP make_navProcUPP()
}
-extern OSErr qt_mac_create_fsref(const QString &, FSRef *); //qglobal.cpp
-
QStringList Q3FileDialog::macGetOpenFileNames(const QString &filter, QString *pwd,
QWidget *parent, const char* /*name*/,
const QString& caption, QString *selectedFilter,
diff --git a/src/qt3support/other/q3process_unix.cpp b/src/qt3support/other/q3process_unix.cpp
index af024bc..426d10f 100644
--- a/src/qt3support/other/q3process_unix.cpp
+++ b/src/qt3support/other/q3process_unix.cpp
@@ -213,7 +213,7 @@ static void q3process_cleanup()
Q3ProcessPrivate::procManager = 0;
}
-#ifdef Q_OS_QNX6
+#ifdef Q_OS_QNX
#define BAILOUT qt_safe_close(tmpSocket);qt_safe_close(socketFD[1]);return -1;
int qnx6SocketPairReplacement (int socketFD[2]) {
int tmpSocket;
@@ -270,7 +270,7 @@ Q3ProcessManager::Q3ProcessManager() : sn(0)
// The SIGCHLD handler writes to a socket to tell the manager that
// something happened. This is done to get the processing in sync with the
// event reporting.
-#ifndef Q_OS_QNX6
+#ifndef Q_OS_QNX
if ( ::socketpair( AF_UNIX, SOCK_STREAM, 0, sigchldFd ) ) {
#else
if ( qnx6SocketPairReplacement (sigchldFd) ) {
@@ -670,14 +670,14 @@ bool Q3Process::start( QStringList *env )
int sStderr[2];
// open sockets for piping
-#ifndef Q_OS_QNX6
+#ifndef Q_OS_QNX
if ( (comms & Stdin) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdin ) == -1 ) {
#else
if ( (comms & Stdin) && qnx6SocketPairReplacement(sStdin) == -1 ) {
#endif
return false;
}
-#ifndef Q_OS_QNX6
+#ifndef Q_OS_QNX
if ( (comms & Stderr) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStderr ) == -1 ) {
#else
if ( (comms & Stderr) && qnx6SocketPairReplacement(sStderr) == -1 ) {
@@ -688,7 +688,7 @@ bool Q3Process::start( QStringList *env )
}
return false;
}
-#ifndef Q_OS_QNX6
+#ifndef Q_OS_QNX
if ( (comms & Stdout) && ::socketpair( AF_UNIX, SOCK_STREAM, 0, sStdout ) == -1 ) {
#else
if ( (comms & Stdout) && qnx6SocketPairReplacement(sStdout) == -1 ) {
@@ -782,11 +782,7 @@ bool Q3Process::start( QStringList *env )
::fcntl( fd[1], F_SETFD, FD_CLOEXEC ); // close on exec shows success
if ( env == 0 ) { // inherit environment and start process
-#ifndef Q_OS_QNX4
::execvp( arglist[0], (char*const*)arglist ); // ### cast not nice
-#else
- ::execvp( arglist[0], (char const*const*)arglist ); // ### cast not nice
-#endif
} else { // start process with environment settins as specified in env
// construct the environment for exec
int numEntries = env->count();
@@ -843,11 +839,7 @@ bool Q3Process::start( QStringList *env )
}
}
}
-#ifndef Q_OS_QNX4
::execve( arglist[0], (char*const*)arglist, (char*const*)envlist ); // ### casts not nice
-#else
- ::execve( arglist[0], (char const*const*)arglist,(char const*const*)envlist ); // ### casts not nice
-#endif
}
if ( fd[1] ) {
char buf = 0;