summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.tests/unix/ipc_posix/ipc.cpp58
-rw-r--r--config.tests/unix/ipc_posix/ipc_posix.pro3
-rw-r--r--config.tests/unix/ipc_sysv/ipc.cpp59
-rw-r--r--config.tests/unix/ipc_sysv/ipc_sysv.pro3
-rwxr-xr-xconfigure13
-rw-r--r--dist/changes-4.8.02
-rw-r--r--doc/src/platforms/platform-notes-rtos.qdoc41
-rw-r--r--mkspecs/common/qnx/qmake.conf33
-rw-r--r--mkspecs/common/qnx/qplatformdefs.h104
-rw-r--r--mkspecs/unsupported/qnx-g++/qmake.conf44
-rw-r--r--mkspecs/unsupported/qnx-g++/qplatformdefs.h66
-rw-r--r--mkspecs/unsupported/qws/qnx-641/qmake.conf2
-rw-r--r--mkspecs/unsupported/qws/qnx-641/qplatformdefs.h2
-rw-r--r--mkspecs/unsupported/qws/qnx-arm-g++/qmake.conf32
-rw-r--r--mkspecs/unsupported/qws/qnx-arm-g++/qplatformdefs.h42
-rw-r--r--mkspecs/unsupported/qws/qnx-armv7-g++/qmake.conf32
-rw-r--r--mkspecs/unsupported/qws/qnx-armv7-g++/qplatformdefs.h42
-rw-r--r--mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf106
-rw-r--r--mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h2
-rw-r--r--mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf102
-rw-r--r--mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h2
-rw-r--r--mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf102
-rw-r--r--mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h2
-rw-r--r--qmake/qmake.pri2
-rw-r--r--src/corelib/global/qglobal.h12
-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/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/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/kernel/qapplication_qws.cpp2
-rw-r--r--src/gui/painting/qwindowsurface_qws.cpp8
-rw-r--r--src/gui/text/qfontdatabase_qws.cpp5
-rw-r--r--src/qt3support/other/q3process_unix.cpp18
-rw-r--r--tests/auto/qlocalsocket/tst_qlocalsocket.cpp4
-rw-r--r--tests/auto/qpluginloader/tst_qpluginloader.cpp2
55 files changed, 1782 insertions, 770 deletions
diff --git a/config.tests/unix/ipc_posix/ipc.cpp b/config.tests/unix/ipc_posix/ipc.cpp
new file mode 100644
index 0000000..fde8a99
--- /dev/null
+++ b/config.tests/unix/ipc_posix/ipc.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/mman.h>
+#include <semaphore.h>
+#include <fcntl.h>
+
+int main(int, char **)
+{
+ sem_t *semaphore = sem_open("test", O_CREAT | O_EXCL, 0666, 0);
+ if (semaphore != SEM_FAILED)
+ sem_close(semaphore);
+
+ shm_open("test", O_RDWR | O_CREAT | O_EXCL, 0666);
+ shm_unlink("test");
+
+ return 0;
+}
diff --git a/config.tests/unix/ipc_posix/ipc_posix.pro b/config.tests/unix/ipc_posix/ipc_posix.pro
new file mode 100644
index 0000000..1b6de02
--- /dev/null
+++ b/config.tests/unix/ipc_posix/ipc_posix.pro
@@ -0,0 +1,3 @@
+SOURCES = ipc.cpp
+CONFIG -= qt dylib
+mac:CONFIG -= app_bundle
diff --git a/config.tests/unix/ipc_sysv/ipc.cpp b/config.tests/unix/ipc_sysv/ipc.cpp
new file mode 100644
index 0000000..7f04552
--- /dev/null
+++ b/config.tests/unix/ipc_sysv/ipc.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the config.tests of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+#include <sys/shm.h>
+#include <fcntl.h>
+
+int main(int, char **)
+{
+ key_t unix_key = ftok("test", 'Q');
+ int semaphore = semget(unix_key, 1, 0666 | IPC_CREAT | IPC_EXCL);
+ if (semaphore != -1)
+ semctl(semaphore, 0, IPC_RMID, 0);
+
+ shmget(unix_key, 0, 0666 | IPC_CREAT | IPC_EXCL);
+ shmctl(0, 0, static_cast<struct shmid_ds *>(0));
+
+ return 0;
+}
diff --git a/config.tests/unix/ipc_sysv/ipc_sysv.pro b/config.tests/unix/ipc_sysv/ipc_sysv.pro
new file mode 100644
index 0000000..1b6de02
--- /dev/null
+++ b/config.tests/unix/ipc_sysv/ipc_sysv.pro
@@ -0,0 +1,3 @@
+SOURCES = ipc.cpp
+CONFIG -= qt dylib
+mac:CONFIG -= app_bundle
diff --git a/configure b/configure
index e113217..07930e0 100755
--- a/configure
+++ b/configure
@@ -5112,6 +5112,19 @@ if [ "$XPLATFORM_SYMBIAN" = "yes" ]; then
fi
fi
+# check IPC support
+if ! "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/ipc_sysv "ipc_sysv" $L_FLAGS $I_FLAGS $l_FLAGS ; then
+ # SYSV IPC is not supported - check POSIX IPC
+ if "$unixtests/compile.test" "$XQMAKESPEC" "$QMAKE_CONFIG" $OPT_VERBOSE "$relpath" "$outpath" config.tests/unix/ipc_posix "ipc_posix" $L_FLAGS $I_FLAGS $l_FLAGS ; then
+ QCONFIG_FLAGS="$QCONFIG_FLAGS QT_POSIX_IPC"
+ else
+ QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SYSTEMSEMAPHORE QT_NO_SHAREDMEMORY"
+ if [ "$PLATFORM_QWS" = "yes" ]; then
+ QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SEMAPHORE QT_NO_QWS_MULTIPROCESS QT_NO_QWS_SHARE_FONTS"
+ fi
+ fi
+fi
+
# detect zlib
if [ "$CFG_ZLIB" = "no" ]; then
# Note: Qt no longer support builds without zlib
diff --git a/dist/changes-4.8.0 b/dist/changes-4.8.0
index 1703633..02205b3 100644
--- a/dist/changes-4.8.0
+++ b/dist/changes-4.8.0
@@ -99,6 +99,8 @@ Qt for Mac OS X
Qt for Embedded Linux
---------------------
+ - Added support for QNX 6.5 with multi-process support, and much improved mouse,
+ keyboard and screen drivers.
Qt for Windows CE
diff --git a/doc/src/platforms/platform-notes-rtos.qdoc b/doc/src/platforms/platform-notes-rtos.qdoc
index 62d5add..0b1265b 100644
--- a/doc/src/platforms/platform-notes-rtos.qdoc
+++ b/doc/src/platforms/platform-notes-rtos.qdoc
@@ -160,7 +160,7 @@
X11 embedded server is not recommended due to missing support for X11 extensions,
resulting in poor rendering quality.
- Qt for QNX contains experimental screen and input drivers based on QNX's
+ Qt for QNX contains screen and input drivers based on QNX's
\c devi-hid and \c io-display. For more information, check the class documentation
for QQnxScreen, QWSQnxKeyboardHandler and QQnxMouseHandler. See the
\l{Porting Qt for Embedded Linux to a New Architecture} document for information
@@ -170,7 +170,7 @@
\section1 Supported Versions
- Qt has been tested on QNX 6.4 on i386 and PowerPC targets with QNX's default
+ Qt has been tested on QNX 6.5 on i386, ARM/ARM-v7 and PowerPC targets with QNX's default
gcc compiler.
\section1 Limitations
@@ -179,16 +179,12 @@
\table
\header \o Function \o Notes
- \row \o QProcess
- \o Not available - QNX doesn't support mixing threads and processes.
- \row \o QSharedMemory
- \o Not available - QNX doesn't support SYSV style shared memory.
- \row \o QSystemSemaphore
- \o Not available - QNX doesn't support SYSV style system semaphores.
- \row \o QWS Multi Process
- \o QT_NO_QWS_MULTIPROCESS is always on due to missing shared memory support.
\row \o Phonon
\o There is no standard audio backend, which could be integrated into Phonon.
+ \row \o QtMultimedia
+ \o There is no standard backend, which could be integrated into QtMultimedia.
+ \row \o QtDBus
+ \o The the QtDBus library is not available on QNX.
\row \o Qt3Support
\o The Qt3Support library is not available on QNX.
\endtable
@@ -203,24 +199,25 @@
i386 QNX target:
\code
- configure -xplatform unsupported/qws/qnx-i386-g++ -embedded i386 -no-gfx-linuxfb -no-mouse-linuxtp -no-kbd-tty -no-qt3support -qt-gfx-qnx -qt-mouse-qnx -qt-kbd-qnx -no-exceptions
+ configure -xplatform unsupported/qws/qnx-i386-g++ -embedded x86 -no-gfx-linuxfb -no-mouse-linuxtp -no-kbd-tty -no-qt3support -qt-mouse-qnx -qt-kbd-qnx -qt-gfx-qnx -depths 16,24,32,generic -no-exceptions
\endcode
\list
\o \c{-xplatform unsupported/qws/qnx-i386-g++} - selects the i386-g++ mkspec for QNX
- \o \c{-embedded i386} - builds the embedded version of Qt and sets the architecture to i386
+ \o \c{-embedded x86} - builds the embedded version of Qt and sets the architecture to i386
\o \c{-no-gfx-linuxfb}, \c{-no-mouse-linuxtp} and \c{-no-kbd-tty} are Linux specific and won't work on QNX
\o \c{-no-qt3support} - required since the Qt3 support classes are not supported on QNX
\o \c{-no-exceptions} - reduces the size of the library by disabling exception support
- \o \c{-qt-gfx-qnx} - enables the experimental \c{io-graphics} based display driver
- \o \c{-qt-mouse-qnx} - enables the experimental \c{devi-hig} based mouse driver
- \o \c{-qt-kbd-qnx} - enables the experimental \c{devi-hig} based keyboard driver
+ \o \c{-qt-mouse-qnx} - enables the \c{devi-hid} based mouse driver
+ \o \c{-qt-kbd-qnx} - enables the \c{devi-hid} based keyboard driver
+ \o \c{-qt-gfx-qnx} - enables the \c{io-graphics} based screen driver
+ \o \c{-depths 16,24,32,generic} - enables all modes supported by the QNX screen driver
\endlist
\section1 General Notes
\list
- \o To enable the experimental QNX display and input drivers, \c{io-display} needs to be
+ \o To enable the QNX screen and input drivers, \c{io-display} needs to be
up and running. The \c devi-hid based Qt input drivers require \c devi-hid to run
in resource mode without Photon support. To enable a standard mouse and keyboard
combination, run \c devi-hid as follows: \c{/usr/photon/bin/devi-hid -Pr kbd mouse}.
@@ -235,8 +232,8 @@
with a newer version, or disable the TIFF plugin entierly by appending
\c{QT_CONFIG += no-tiff} to \c{.qmake.cache} after configuring Qt.
- \o Some of the tools, examples and demos do not compile due to dependencies on QProcess
- or other classes that are not available on QNX.
+ \o Some of the tools, examples and demos do not compile due to dependencies on classes
+ that are not available on QNX.
\endlist
\section1 Platform Regressions
@@ -244,6 +241,14 @@
Qt for QNX's behavior is mostly identical with \l{Qt for Embedded Linux}. However,
some regressions were spotted in QDateTime computation around year 0 and year 1970,
which have been tracked back to faulty time zone data on some QNX versions.
+
+ QString::localeAwareCompare() only works for C locale.
+
+ QTranslator's default locale-based fallback mechanism doesn't work.
+
+ QSystemSemaphore: Due to POSIX semaphores limitations, the semaphore operations aren't
+ automatically undone when the process terminates. This potentially may lead to unexpected
+ lock-ups in applications which does use the SysV semaphores behavior.
*/
/*!
diff --git a/mkspecs/common/qnx/qmake.conf b/mkspecs/common/qnx/qmake.conf
new file mode 100644
index 0000000..d241b61
--- /dev/null
+++ b/mkspecs/common/qnx/qmake.conf
@@ -0,0 +1,33 @@
+#
+# qmake configuration common for qnx-g++ without X11
+#
+
+include(../gcc-base-unix.conf)
+include(../g++-unix.conf)
+include(../linux.conf)
+include(../qws.conf)
+
+CONFIG += qnx
+QT -= network
+
+QMAKE_COMPILER_DEFINES += __QNXNTO__
+
+# modifications to linux.conf and qws.conf
+QMAKE_LIBS =
+QMAKE_LIBS_DYNLOAD =
+QMAKE_LIBS_NIS =
+QMAKE_LIBS_EGL = -lEGL
+QMAKE_LIBS_OPENGL = $$QMAKE_LIBS_EGL -lGLESv1_CM -lGLESv2
+QMAKE_LIBS_OPENGL_QT = $$QMAKE_LIBS_OPENGL
+QMAKE_LIBS_OPENGL_ES1 = $$QMAKE_LIBS_EGL -lGLESv1_CM
+QMAKE_LIBS_OPENGL_ES2 = $$QMAKE_LIBS_EGL -lGLESv2
+QMAKE_LIBS_OPENVG = $$QMAKE_LIBS_EGL -lOpenVG
+QMAKE_LIBS_THREAD =
+
+QMAKE_LIBS_CORE =
+QMAKE_LIBS_NETWORK += -lsocket
+QMAKE_LIBS_GUI += -lsocket
+
+# QNX doesn't have install
+QMAKE_INSTALL_FILE =
+QMAKE_INSTALL_PROGRAM =
diff --git a/mkspecs/common/qnx/qplatformdefs.h b/mkspecs/common/qnx/qplatformdefs.h
new file mode 100644
index 0000000..bf7a0a0
--- /dev/null
+++ b/mkspecs/common/qnx/qplatformdefs.h
@@ -0,0 +1,104 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QPLATFORMDEFS_H
+#define QPLATFORMDEFS_H
+
+// Get Qt defines/settings
+#include <qglobal.h>
+
+// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
+
+#include <unistd.h>
+
+// We are hot - unistd.h should have turned on the specific APIs we requested
+
+#include <pthread.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/ipc.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+#ifndef QT_NO_IPV6IFNAME
+#include <net/if.h>
+#endif
+
+// for htonl
+#include <arpa/inet.h>
+
+#define QT_USE_XOPEN_LFS_EXTENSIONS
+#define QT_NO_READDIR64
+#include "../posix/qplatformdefs.h"
+
+#include <stdlib.h>
+
+#define QT_SNPRINTF ::snprintf
+#define QT_VSNPRINTF ::vsnprintf
+
+
+#include <sys/neutrino.h>
+
+#if !defined(_NTO_VERSION) || _NTO_VERSION < 650
+// pre-6.5 versions of QNX doesn't have getpagesize()
+inline int getpagesize()
+{
+ return ::sysconf(_SC_PAGESIZE);
+}
+
+// pre-6.5 versions of QNX doesn't have strtof()
+inline float strtof(const char *b, char **e)
+{
+ return float(strtod(b, e));
+}
+#endif
+
+#define QT_QWS_TEMP_DIR QString::fromLocal8Bit(qgetenv("TMPDIR").constData())
+
+#endif // QPLATFORMDEFS_H
diff --git a/mkspecs/unsupported/qnx-g++/qmake.conf b/mkspecs/unsupported/qnx-g++/qmake.conf
index 83c4a26..e354b2c 100644
--- a/mkspecs/unsupported/qnx-g++/qmake.conf
+++ b/mkspecs/unsupported/qnx-g++/qmake.conf
@@ -4,58 +4,16 @@
# Written for QNX RTOS v6 with X11
#
-MAKEFILE_GENERATOR = UNIX
-TARGET_PLATFORM = unix
-TEMPLATE = app
-CONFIG += qt warn_on release link_prl
-QT += core gui
+include(../../common/qnx/qmake.conf)
-include(../common/gcc-base-unix.conf)
-include(../common/g++-unix.conf)
-include(../common/unix.conf)
-
-QMAKE_CFLAGS_THREAD = -D_REENTRANT
-QMAKE_CXXFLAGS_THREAD = $$QMAKE_CLFAGS_THREAD
-QMAKE_COMPILER_DEFINES += __QNXNTO__
-
-QMAKE_INCDIR =
-QMAKE_LIBDIR =
QMAKE_INCDIR_X11 = /opt/X11R6/include
QMAKE_LIBDIR_X11 = /opt/X11R6/lib
-QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
-QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
QMAKE_INCDIR_OPENGL = /opt/X11R6/include
QMAKE_LIBDIR_OPENGL = /opt/X11R6/lib
-#QMAKE_LIBS = -lunix
-QMAKE_LIBS =
-QMAKE_LIBS_DYNLOAD =
QMAKE_LIBS_X11 = -lXext -lX11 -lm -lsocket
QMAKE_LIBS_X11SM = -lSM -lICE
QMAKE_LIBS_OPENGL = -lGL
QMAKE_LIBS_OPENGL_QT = -lGL
-QMAKE_LIBS_THREAD =
-QMAKE_LIBS_NETWORK = -lsocket
-
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
-QMAKE_AR = ar cqs
-QMAKE_RANLIB =
-
-QMAKE_TAR = tar -cf
-QMAKE_GZIP = gzip -9f
-QMAKE_COPY = cp -f
-QMAKE_COPY_FILE = $(COPY)
-QMAKE_COPY_DIR = $(COPY) -r
-QMAKE_MOVE = mv -f
-QMAKE_DEL_FILE = rm -f
-QMAKE_DEL_DIR = rmdir
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
-QMAKE_STRIP = strip
-QMAKE_STRIPFLAGS_LIB += --strip-unneeded
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
load(qt_config)
diff --git a/mkspecs/unsupported/qnx-g++/qplatformdefs.h b/mkspecs/unsupported/qnx-g++/qplatformdefs.h
index 8b50f92..34c1525 100644
--- a/mkspecs/unsupported/qnx-g++/qplatformdefs.h
+++ b/mkspecs/unsupported/qnx-g++/qplatformdefs.h
@@ -39,68 +39,4 @@
**
****************************************************************************/
-#ifndef QPLATFORMDEFS_H
-#define QPLATFORMDEFS_H
-
-// Get Qt defines/settings
-
-#include "qglobal.h"
-
-// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
-
-#include <unistd.h>
-
-
-// We are hot - unistd.h should have turned on the specific APIs we requested
-
-
-#include <pthread.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <signal.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/ipc.h>
-#include <sys/time.h>
-// QNX doesn't have the System V <sys/shm.h> header. This is not a standard
-// POSIX header, it's only documented in the Single UNIX Specification.
-// The preferred POSIX compliant way to share memory is to use the functions
-// in <sys/mman.h> that comply with the POSIX Real Time Interface (1003.1b).
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#ifndef QT_NO_IPV6IFNAME
-#include <net/if.h>
-#endif
-
-// for htonl
-#include <arpa/inet.h>
-
-#define QT_USE_XOPEN_LFS_EXTENSIONS
-#include "../../common/posix/qplatformdefs.h"
-
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
-
-// QNX6 doesn't have getpagesize()
-inline int getpagesize()
-{
- return ::sysconf(_SC_PAGESIZE);
-}
-
-#include <stdlib.h>
-
-// QNX6 doesn't have strtof - use strtod instead
-inline float strtof(const char *b, char **e)
-{
- return float(strtod(b, e));
-}
-
-#define QT_QWS_TEMP_DIR QString::fromLatin1(qgetenv("TMP"))
-
-#endif // QPLATFORMDEFS_H
+#include "../../common/qnx/qplatformdefs.h"
diff --git a/mkspecs/unsupported/qws/qnx-641/qmake.conf b/mkspecs/unsupported/qws/qnx-641/qmake.conf
index 441f408..304ac67 100644
--- a/mkspecs/unsupported/qws/qnx-641/qmake.conf
+++ b/mkspecs/unsupported/qws/qnx-641/qmake.conf
@@ -59,7 +59,7 @@ QMAKE_PCH_OUTPUT_EXT = .gch
QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions
QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list,
-include(../../common/unix.conf)
+include(../../../common/unix.conf)
QMAKE_CFLAGS_THREAD = -D_REENTRANT
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
diff --git a/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h
index 0c71265..ea04d0f 100644
--- a/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h
+++ b/mkspecs/unsupported/qws/qnx-641/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../../qnx-g++/qplatformdefs.h"
+#include "../../../common/qnx/qplatformdefs.h"
diff --git a/mkspecs/unsupported/qws/qnx-arm-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-arm-g++/qmake.conf
new file mode 100644
index 0000000..b9f946e
--- /dev/null
+++ b/mkspecs/unsupported/qws/qnx-arm-g++/qmake.conf
@@ -0,0 +1,32 @@
+#
+# qmake configuration for qnx-arm-g++
+#
+# Written for QNX RTOS v6
+#
+
+include(../../../common/qnx/qmake.conf)
+
+# modifications to gcc-base.conf and g++-base.conf
+
+#Bug in arm compiler for QNX
+QMAKE_CFLAGS_RELEASE = -O1
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -O1 -g
+
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
+
+QMAKE_CC = ntoarm-gcc
+QMAKE_CXX = ntoarm-g++
+
+QMAKE_LINK = ntoarm-g++
+QMAKE_LINK_SHLIB = $$QMAKE_LINK
+QMAKE_LINK_C = ntoarm-gcc
+QMAKE_LINK_C_SHLIB = $$QMAKE_LINK_C
+
+# modifications to linux.conf
+QMAKE_AR = ntoarm-ar cqs
+QMAKE_STRIP = ntoarm-strip
+QMAKE_RANLIB = ntoarm-ranlib
+QMAKE_OBJCOPY = ntoarm-objcopy
+
+load(qt_config)
diff --git a/mkspecs/unsupported/qws/qnx-arm-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-arm-g++/qplatformdefs.h
new file mode 100644
index 0000000..5817a53
--- /dev/null
+++ b/mkspecs/unsupported/qws/qnx-arm-g++/qplatformdefs.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../../../common/qnx/qplatformdefs.h"
diff --git a/mkspecs/unsupported/qws/qnx-armv7-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-armv7-g++/qmake.conf
new file mode 100644
index 0000000..c6763d5
--- /dev/null
+++ b/mkspecs/unsupported/qws/qnx-armv7-g++/qmake.conf
@@ -0,0 +1,32 @@
+#
+# qmake configuration for qnx-armv7-g++
+#
+# Written for QNX RTOS v6
+#
+
+include(../../../common/qnx/qmake.conf)
+
+# modifications to gcc-base.conf and g++-base.conf
+
+# note: on the NVidia Tegra 2 and on the Marvell Dovecott, '-mfpu=neon' should be removed
+QMAKE_CFLAGS_RELEASE = -O3 -march=armv7-a -mfpu=neon -mfloat-abi=softfp
+QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -O3 -g -march=armv7-a -mfpu=neon -mfloat-abi=softfp
+
+QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
+QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
+
+QMAKE_CC = ntoarmv7-gcc
+QMAKE_CXX = ntoarmv7-g++
+
+QMAKE_LINK = ntoarmv7-g++
+QMAKE_LINK_SHLIB = $$QMAKE_LINK
+QMAKE_LINK_C = ntoarmv7-gcc
+QMAKE_LINK_C_SHLIB = $$QMAKE_LINK_C
+
+# modifications to linux.conf
+QMAKE_AR = ntoarmv7-ar cqs
+QMAKE_STRIP = ntoarmv7-strip
+QMAKE_RANLIB = ntoarmv7-ranlib
+QMAKE_OBJCOPY = ntoarmv7-objcopy
+
+load(qt_config)
diff --git a/mkspecs/unsupported/qws/qnx-armv7-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-armv7-g++/qplatformdefs.h
new file mode 100644
index 0000000..5817a53
--- /dev/null
+++ b/mkspecs/unsupported/qws/qnx-armv7-g++/qplatformdefs.h
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the qmake spec of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "../../../common/qnx/qplatformdefs.h"
diff --git a/mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf
index bb760b2..f5e7045 100644
--- a/mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf
+++ b/mkspecs/unsupported/qws/qnx-generic-g++/qmake.conf
@@ -1,102 +1,24 @@
#
-# qmake configuration for qnx-g++
+# qmake configuration for qnx-generic-g++
#
# Written for QNX RTOS v6
#
-MAKEFILE_GENERATOR = UNIX
-TARGET_PLATFORM = unix
-TEMPLATE = app
-CONFIG += qt warn_on release link_prl
-QT += core gui
+include(../../../common/qnx/qmake.conf)
-#
-# qmake configuration for common gcc
-#
-
-QMAKE_CC = ntox86-gcc-3.3.5
-QMAKE_CFLAGS += -pipe
-QMAKE_CFLAGS_DEPS += -M
-QMAKE_CFLAGS_WARN_ON += -Wall -W
-QMAKE_CFLAGS_WARN_OFF += -w
-QMAKE_CFLAGS_RELEASE += -O2
-QMAKE_CFLAGS_DEBUG += -g
-QMAKE_CFLAGS_SHLIB += -fPIC
-QMAKE_CFLAGS_STATIC_LIB += -fPIC
-QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses
-QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
-QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE}
-QMAKE_COMPILER_DEFINES += __QNXNTO__
-
-QMAKE_CXX = ntox86-g++-3.3.5
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
-QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS
-QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON
-QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF
-QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
-QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
-QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB
-QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB
-QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC
-QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
-QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
-
-QMAKE_LINK = ntox86-gcc-3.3.5
-QMAKE_LINK_SHLIB = ntox86-gcc-3.3.5
-QMAKE_LFLAGS += -Wl,--no-undefined
-QMAKE_LFLAGS_RELEASE +=
-QMAKE_LFLAGS_DEBUG +=
-QMAKE_LFLAGS_APP +=
-QMAKE_LFLAGS_SHLIB += -shared
-QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB
-QMAKE_LFLAGS_SONAME += -Wl,-soname,
-QMAKE_LFLAGS_THREAD +=
-QMAKE_LFLAGS_RPATH = -Wl,-rpath,
-
-QMAKE_PCH_OUTPUT_EXT = .gch
-
-# -Bsymbolic-functions (ld) support
-QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions
-QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list,
-
-include(../../common/unix.conf)
-
-QMAKE_CFLAGS_THREAD = -D_REENTRANT
-QMAKE_CXXFLAGS_THREAD = $$QMAKE_CLFAGS_THREAD
-
-QMAKE_INCDIR =
-QMAKE_LIBDIR =
-QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
-QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
-
-#QMAKE_LIBS = -lunix
-QMAKE_LIBS =
-QMAKE_LIBS_DYNLOAD =
-QMAKE_LIBS_THREAD =
-QMAKE_LIBS_NETWORK += -lsocket
-QMAKE_LIBS_GUI += -lsocket
-
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
+# derived from g++-base.conf
+#QMAKE_CC = gcc
+#QMAKE_CXX = g++
-QMAKE_AR = ar cqs
-QMAKE_RANLIB =
+#QMAKE_LINK = g++
+#QMAKE_LINK_SHLIB = g++
+#QMAKE_LINK_C = gcc
+#QMAKE_LINK_C_SHLIB = gcc
-QMAKE_TAR = tar -cf
-QMAKE_GZIP = gzip -9f
+# derived from linux.conf
+#QMAKE_AR = ar cqs
+#QMAKE_OBJCOPY = objcopy
+#QMAKE_RANLIB =
+#QMAKE_STRIP = strip
-QMAKE_COPY = cp -f
-QMAKE_COPY_FILE = $(COPY)
-QMAKE_COPY_DIR = $(COPY) -r
-QMAKE_MOVE = mv -f
-QMAKE_DEL_FILE = rm -f
-QMAKE_DEL_DIR = rmdir
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
-QMAKE_STRIP = strip
-QMAKE_STRIPFLAGS_LIB += --strip-unneeded
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
load(qt_config)
diff --git a/mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h
index 0c71265..ea04d0f 100644
--- a/mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h
+++ b/mkspecs/unsupported/qws/qnx-generic-g++/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../../qnx-g++/qplatformdefs.h"
+#include "../../../common/qnx/qplatformdefs.h"
diff --git a/mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf
index b43c391..6940bd8 100644
--- a/mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf
+++ b/mkspecs/unsupported/qws/qnx-i386-g++/qmake.conf
@@ -1,98 +1,24 @@
#
-# qmake configuration for qnx-g++
+# qmake configuration for qnx-i386-g++
#
# Written for QNX RTOS v6
#
-MAKEFILE_GENERATOR = UNIX
-TARGET_PLATFORM = unix
-TEMPLATE = app
-CONFIG += qt warn_on release link_prl
-QT += core gui
+include(../../../common/qnx/qmake.conf)
-QMAKE_CC = ntox86-gcc-4.2.4
-QMAKE_CFLAGS += -pipe
-QMAKE_CFLAGS_DEPS += -M
-QMAKE_CFLAGS_WARN_ON += -Wall -W
-QMAKE_CFLAGS_WARN_OFF += -w
-QMAKE_CFLAGS_RELEASE += -O2
-QMAKE_CFLAGS_DEBUG += -g
-QMAKE_CFLAGS_SHLIB += -fPIC
-QMAKE_CFLAGS_STATIC_LIB += -fPIC
-QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses
-QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
-QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE}
-QMAKE_COMPILER_DEFINES += __QNXNTO__
+# modifications to g++-base.conf
+QMAKE_CC = ntox86-gcc
+QMAKE_CXX = ntox86-g++
-QMAKE_CXX = ntox86-g++-4.2.4
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
-QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS
-QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON
-QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF
-QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
-QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
-QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB
-QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB
-QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC
-QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
-QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
+QMAKE_LINK = ntox86-g++
+QMAKE_LINK_SHLIB = $$QMAKE_LINK
+QMAKE_LINK_C = ntox86-gcc
+QMAKE_LINK_C_SHLIB = $$QMAKE_LINK_C
-QMAKE_LINK = ntox86-g++-4.2.4
-QMAKE_LINK_SHLIB = ntox86-g++-4.2.4
-QMAKE_LFLAGS += -Wl,--no-undefined
-QMAKE_LFLAGS_RELEASE +=
-QMAKE_LFLAGS_DEBUG +=
-QMAKE_LFLAGS_APP +=
-QMAKE_LFLAGS_SHLIB += -shared
-QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB
-QMAKE_LFLAGS_SONAME += -Wl,-soname,
-QMAKE_LFLAGS_THREAD +=
-QMAKE_LFLAGS_RPATH = -Wl,-rpath,
+# modifications to linux.conf
+QMAKE_AR = ntox86-ar cqs
+QMAKE_OBJCOPY = ntox86-objcopy
+QMAKE_RANLIB = ntox86-ranlib
+QMAKE_STRIP = ntox86-strip
-QMAKE_PCH_OUTPUT_EXT = .gch
-
-# -Bsymbolic-functions (ld) support
-QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions
-QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list,
-
-include(../../../common/unix.conf)
-
-QMAKE_CFLAGS_THREAD = -D_REENTRANT
-QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
-
-QMAKE_INCDIR =
-QMAKE_LIBDIR =
-QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
-QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
-
-#QMAKE_LIBS = -lunix
-QMAKE_LIBS =
-QMAKE_LIBS_DYNLOAD =
-QMAKE_LIBS_THREAD =
-QMAKE_LIBS_NETWORK += -lsocket
-QMAKE_LIBS_GUI += -lsocket
-
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
-QMAKE_AR = ar cqs
-QMAKE_RANLIB =
-
-QMAKE_TAR = tar -cf
-QMAKE_GZIP = gzip -9f
-
-QMAKE_COPY = cp -f
-QMAKE_COPY_FILE = $(COPY)
-QMAKE_COPY_DIR = $(COPY) -r
-QMAKE_MOVE = mv -f
-QMAKE_DEL_FILE = rm -f
-QMAKE_DEL_DIR = rmdir
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
-QMAKE_STRIP = strip
-QMAKE_STRIPFLAGS_LIB += --strip-unneeded
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
load(qt_config)
diff --git a/mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h
index 0c71265..ea04d0f 100644
--- a/mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h
+++ b/mkspecs/unsupported/qws/qnx-i386-g++/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../../qnx-g++/qplatformdefs.h"
+#include "../../../common/qnx/qplatformdefs.h"
diff --git a/mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf b/mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf
index 29a2952..cb4d391 100644
--- a/mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf
+++ b/mkspecs/unsupported/qws/qnx-ppc-g++/qmake.conf
@@ -1,98 +1,24 @@
#
-# qmake configuration for qnx-g++
+# qmake configuration for qnx-ppc-g++
#
# Written for QNX RTOS v6
#
-MAKEFILE_GENERATOR = UNIX
-TARGET_PLATFORM = unix
-TEMPLATE = app
-CONFIG += qt warn_on release link_prl
-QT += core gui
+include(../../../common/qnx/qmake.conf)
-QMAKE_CC = ntoppc-gcc-4.3.3
-QMAKE_CFLAGS += -pipe
-QMAKE_CFLAGS_DEPS += -M
-QMAKE_CFLAGS_WARN_ON += -Wall -W
-QMAKE_CFLAGS_WARN_OFF += -w
-QMAKE_CFLAGS_RELEASE += -O2
-QMAKE_CFLAGS_DEBUG += -g
-QMAKE_CFLAGS_SHLIB += -fPIC
-QMAKE_CFLAGS_STATIC_LIB += -fPIC
-QMAKE_CFLAGS_YACC += -Wno-unused -Wno-parentheses
-QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden
-QMAKE_CFLAGS_PRECOMPILE += -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CFLAGS_USE_PRECOMPILE += -include ${QMAKE_PCH_OUTPUT_BASE}
-QMAKE_COMPILER_DEFINES += __QNXNTO__
+# modifications to g++-base.conf
+QMAKE_CC = ntoppc-gcc
+QMAKE_CXX = ntoppc-g++
-QMAKE_CXX = ntoppc-g++-4.3.3
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS
-QMAKE_CXXFLAGS_DEPS += $$QMAKE_CFLAGS_DEPS
-QMAKE_CXXFLAGS_WARN_ON += $$QMAKE_CFLAGS_WARN_ON
-QMAKE_CXXFLAGS_WARN_OFF += $$QMAKE_CFLAGS_WARN_OFF
-QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
-QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
-QMAKE_CXXFLAGS_SHLIB += $$QMAKE_CFLAGS_SHLIB
-QMAKE_CXXFLAGS_STATIC_LIB += $$QMAKE_CFLAGS_STATIC_LIB
-QMAKE_CXXFLAGS_YACC += $$QMAKE_CFLAGS_YACC
-QMAKE_CXXFLAGS_HIDESYMS += $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
-QMAKE_CXXFLAGS_PRECOMPILE += -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
-QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
+QMAKE_LINK = ntoppc-g++
+QMAKE_LINK_SHLIB = $$QMAKE_LINK
+QMAKE_LINK_C = ntoppc-gcc
+QMAKE_LINK_C_SHLIB = $$QMAKE_LINK_C
-QMAKE_LINK = ntoppc-g++-4.3.3
-QMAKE_LINK_SHLIB = ntoppc-g++-4.3.3
-QMAKE_LFLAGS += -Wl,--no-undefined
-QMAKE_LFLAGS_RELEASE +=
-QMAKE_LFLAGS_DEBUG +=
-QMAKE_LFLAGS_APP +=
-QMAKE_LFLAGS_SHLIB += -shared
-QMAKE_LFLAGS_PLUGIN += $$QMAKE_LFLAGS_SHLIB
-QMAKE_LFLAGS_SONAME += -Wl,-soname,
-QMAKE_LFLAGS_THREAD +=
-QMAKE_LFLAGS_RPATH = -Wl,-rpath,
+# modifications to linux.conf
+QMAKE_AR = ntoppc-ar cqs
+QMAKE_STRIP = ntoppc-strip
+QMAKE_RANLIB = ntoppc-ranlib
+QMAKE_OBJCOPY = ntoppc-objcopy
-QMAKE_PCH_OUTPUT_EXT = .gch
-
-# -Bsymbolic-functions (ld) support
-QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions
-QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list,
-
-include(../../common/unix.conf)
-
-QMAKE_CFLAGS_THREAD = -D_REENTRANT
-QMAKE_CXXFLAGS_THREAD = $$QMAKE_CLFAGS_THREAD
-
-QMAKE_INCDIR =
-QMAKE_LIBDIR =
-QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS]
-QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS]
-
-#QMAKE_LIBS = -lunix
-QMAKE_LIBS =
-QMAKE_LIBS_DYNLOAD =
-QMAKE_LIBS_THREAD =
-QMAKE_LIBS_NETWORK += -lsocket
-QMAKE_LIBS_GUI += -lsocket
-
-QMAKE_MOC = $$[QT_INSTALL_BINS]/moc
-QMAKE_UIC = $$[QT_INSTALL_BINS]/uic
-
-QMAKE_AR = ar cqs
-QMAKE_RANLIB =
-
-QMAKE_TAR = tar -cf
-QMAKE_GZIP = gzip -9f
-
-QMAKE_COPY = cp -f
-QMAKE_COPY_FILE = $(COPY)
-QMAKE_COPY_DIR = $(COPY) -r
-QMAKE_MOVE = mv -f
-QMAKE_DEL_FILE = rm -f
-QMAKE_DEL_DIR = rmdir
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
-QMAKE_STRIP = strip
-QMAKE_STRIPFLAGS_LIB += --strip-unneeded
-QMAKE_CHK_DIR_EXISTS = test -d
-QMAKE_MKDIR = mkdir -p
load(qt_config)
diff --git a/mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h b/mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h
index 0c71265..ea04d0f 100644
--- a/mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h
+++ b/mkspecs/unsupported/qws/qnx-ppc-g++/qplatformdefs.h
@@ -39,4 +39,4 @@
**
****************************************************************************/
-#include "../../qnx-g++/qplatformdefs.h"
+#include "../../../common/qnx/qplatformdefs.h"
diff --git a/qmake/qmake.pri b/qmake/qmake.pri
index d6c5f09..87735d6 100644
--- a/qmake/qmake.pri
+++ b/qmake/qmake.pri
@@ -146,7 +146,7 @@ bootstrap { #Qt code
qnx {
CFLAGS += -fhonor-std
- LFLAGS += -lcpp
+ LFLAGS += -lcpp -lm
}
DEFINES *= QT_NO_QOBJECT
} else {
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/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/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/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/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index abee361..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());
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/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/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;
diff --git a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
index 3dc5e73..feb2552 100644
--- a/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
+++ b/tests/auto/qlocalsocket/tst_qlocalsocket.cpp
@@ -893,8 +893,8 @@ void tst_QLocalSocket::removeServer()
QLocalServer server, server2;
QVERIFY(QLocalServer::removeServer("cleanuptest"));
QVERIFY(server.listen("cleanuptest"));
-#ifndef Q_OS_WIN
- // on Windows, there can be several sockets listening on the same pipe
+#if !defined(Q_OS_WIN) && !defined(Q_OS_QNX)
+ // on Windows and QNX, there can be several sockets listening on the same pipe
// on Unix, there can only be one socket instance
QVERIFY(! server2.listen("cleanuptest"));
#endif
diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp
index 76dbd48..d2d92a5 100644
--- a/tests/auto/qpluginloader/tst_qpluginloader.cpp
+++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp
@@ -219,7 +219,7 @@ void tst_QPluginLoader::errorString()
QVERIFY(loader.errorString() != unknown);
}
-#if !defined Q_OS_WIN && !defined Q_OS_MAC && !defined Q_OS_HPUX && !defined Q_OS_SYMBIAN
+#if !defined Q_OS_WIN && !defined Q_OS_MAC && !defined Q_OS_HPUX && !defined Q_OS_SYMBIAN && !defined Q_OS_QNX
{
QPluginLoader loader( sys_qualifiedLibraryName("almostplugin")); //a plugin with unresolved symbols
loader.setLoadHints(QLibrary::ResolveAllSymbolsHint);