summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorHarald Fernengel <harald@trolltech.com>2009-07-21 18:15:11 +0200
committerRobert Griebl <rgriebl@trolltech.com>2009-07-29 10:55:02 +0200
commit2ce3e9c150798b12d5b434ed25fc37c96972fb8b (patch)
tree64157ddd4daf2f7b70901afca52df6f02fe3cc72 /src/gui
parentd7b688870aead912690188b324d370b920a7a600 (diff)
Port of Qt to QNX
This makes Qt work on QNX 6.4. * no q3support, no phonon * no QSharedMemory, no QSystemSemaphore, no QProcess Reviewed-By: Robert Griebl
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/embedded/embedded.pri18
-rw-r--r--src/gui/embedded/qkbddriverfactory_qws.cpp8
-rw-r--r--src/gui/embedded/qkbdqnx_qws.cpp231
-rw-r--r--src/gui/embedded/qkbdqnx_qws.h76
-rw-r--r--src/gui/embedded/qlock.cpp70
-rw-r--r--src/gui/embedded/qmousedriverfactory_qws.cpp8
-rw-r--r--src/gui/embedded/qmousepc_qws.cpp2
-rw-r--r--src/gui/embedded/qmouseqnx_qws.cpp190
-rw-r--r--src/gui/embedded/qmouseqnx_qws.h79
-rw-r--r--src/gui/embedded/qscreendriverfactory_qws.cpp8
-rw-r--r--src/gui/embedded/qscreenqnx_qws.cpp447
-rw-r--r--src/gui/embedded/qscreenqnx_qws.h82
-rw-r--r--src/gui/embedded/qwindowsystem_qws.cpp37
-rw-r--r--src/gui/kernel/qapplication_qws.cpp9
-rw-r--r--src/gui/text/qfontdatabase_qws.cpp6
-rw-r--r--src/gui/text/qfontengine_qpf.cpp52
16 files changed, 1259 insertions, 64 deletions
diff --git a/src/gui/embedded/embedded.pri b/src/gui/embedded/embedded.pri
index 07d1dcc036..e8eb9590d9 100644
--- a/src/gui/embedded/embedded.pri
+++ b/src/gui/embedded/embedded.pri
@@ -114,6 +114,12 @@ embedded {
SOURCES += embedded/qscreenlinuxfb_qws.cpp
}
+ contains( gfx-drivers, qnx ) {
+ HEADERS += embedded/qscreenqnx_qws.h
+ SOURCES += embedded/qscreenqnx_qws.cpp
+ LIBS += -lgf
+ }
+
contains( gfx-drivers, qvfb ) {
HEADERS += embedded/qscreenvfb_qws.h
SOURCES += embedded/qscreenvfb_qws.cpp
@@ -159,6 +165,11 @@ embedded {
SOURCES +=embedded/qkbdum_qws.cpp
}
+ contains( kbd-drivers, qnx ) {
+ HEADERS += embedded/qkbdqnx_qws.h
+ SOURCES += embedded/qkbdqnx_qws.cpp
+ }
+
#
# Mouse drivers
#
@@ -186,5 +197,10 @@ embedded {
contains( mouse-drivers, linuxinput ) {
HEADERS +=embedded/qmouselinuxinput_qws.h
SOURCES +=embedded/qmouselinuxinput_qws.cpp
- }
+ }
+
+ contains( mouse-drivers, qnx ) {
+ HEADERS += embedded/qmouseqnx_qws.h
+ SOURCES += embedded/qmouseqnx_qws.cpp
+ }
}
diff --git a/src/gui/embedded/qkbddriverfactory_qws.cpp b/src/gui/embedded/qkbddriverfactory_qws.cpp
index b77eb72faa..fb10030827 100644
--- a/src/gui/embedded/qkbddriverfactory_qws.cpp
+++ b/src/gui/embedded/qkbddriverfactory_qws.cpp
@@ -48,6 +48,7 @@
#include "qkbdlinuxinput_qws.h"
#include "qkbdum_qws.h"
#include "qkbdvfb_qws.h"
+#include "qkbdqnx_qws.h"
#include <stdlib.h>
#include "private/qfactoryloader_p.h"
#include "qkbddriverplugin_qws.h"
@@ -101,6 +102,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
QWSKeyboardHandler *QKbdDriverFactory::create(const QString& key, const QString& device)
{
QString driver = key.toLower();
+#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_KBD_QNX)
+ if (driver == QLatin1String("qnx") || driver.isEmpty())
+ return new QWSQnxKeyboardHandler(device);
+#endif
#ifndef QT_NO_QWS_KEYBOARD
# ifndef QT_NO_QWS_KBD_TTY
if (driver == QLatin1String("tty") || driver.isEmpty())
@@ -143,6 +148,9 @@ QStringList QKbdDriverFactory::keys()
{
QStringList list;
+#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_KBD_QNX)
+ list << QLatin1String("QNX");
+#endif
#ifndef QT_NO_QWS_KBD_TTY
list << QLatin1String("TTY");
#endif
diff --git a/src/gui/embedded/qkbdqnx_qws.cpp b/src/gui/embedded/qkbdqnx_qws.cpp
new file mode 100644
index 0000000000..06163c735a
--- /dev/null
+++ b/src/gui/embedded/qkbdqnx_qws.cpp
@@ -0,0 +1,231 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qkbdqnx_qws.h"
+#include "QtCore/qsocketnotifier.h"
+#include "QtCore/qdebug.h"
+
+#include <sys/dcmd_input.h>
+#include <photon/keycodes.h>
+
+#include "qplatformdefs.h"
+#include <errno.h>
+
+/*!
+ \class QWSQnxKeyboardHandler
+ \preliminary
+ \ingroup qws
+ \since 4.6
+ \internal
+
+ \brief The QWSQnxKeyboardHandler class implements a keyboard driver
+ for the QNX \c{devi-hid} input manager.
+
+ To be able to compile this mouse handler, \l{Qt for Embedded Linux}
+ must be configured with the \c -qt-kbd-qnx option, see the
+ \l{Qt for Embedded Linux Character Input} documentation for details.
+
+ In order to use this keyboard handler, the \c{devi-hid} input manager
+ must be set up and run with the resource manager interface (option \c{-r}).
+ Also, Photon must not be running.
+
+ 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
+ a Qt application after invocation of \c{devi-hid}.
+
+ To make \l{Qt for Embedded Linux} explicitly choose the qnx keyboard
+ handler, set the QWS_KEYBOARD environment variable to \c{qnx}. By default,
+ the first keyboard device (\c{/dev/devi/keyboard0}) is used. To override, pass a device
+ name as the first and only parameter, for example
+ \c{QWS_KEYBOARD=qnx:/dev/devi/keyboard1; export QWS_KEYBOARD}.
+
+ \sa {Qt for Embedded Linux Character Input}, {Qt for Embedded Linux}
+*/
+
+/*!
+ Constructs a keyboard handler for the specified \a device, defaulting to
+ \c{/dev/devi/keyboard0}.
+
+ Note that you should never instanciate this class, instead let QKbdDriverFactory
+ handle the keyboard handlers.
+
+ \sa QKbdDriverFactory
+ */
+QWSQnxKeyboardHandler::QWSQnxKeyboardHandler(const QString &device)
+{
+ // open the keyboard device
+ keyboardFD = QT_OPEN(device.isEmpty() ? "/dev/devi/keyboard0" : device.toLatin1().constData(),
+ 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.";
+
+}
+
+/*!
+ Destroys this keyboard handler and closes the connection to the keyboard device.
+ */
+QWSQnxKeyboardHandler::~QWSQnxKeyboardHandler()
+{
+ QT_CLOSE(keyboardFD);
+}
+
+/*! \internal
+ Translates the QNX keyboard events to Qt keyboard events
+ */
+void QWSQnxKeyboardHandler::socketActivated()
+{
+ _keyboard_packet packet;
+
+ // read one keyboard event
+ int bytesRead = QT_READ(keyboardFD, &packet, sizeof(_keyboard_packet));
+ if (bytesRead == -1) {
+ qErrnoWarning(errno, "QWSQnxKeyboardHandler::socketActivated(): Unable to read data.");
+ return;
+ }
+
+ // the bytes read must be the size of a keyboard packet
+ Q_ASSERT(bytesRead == sizeof(_keyboard_packet));
+
+#if 0
+ qDebug() << "keyboard got scancode"
+ << hex << packet.data.modifiers
+ << packet.data.flags
+ << packet.data.key_cap
+ << packet.data.key_sym
+ << packet.data.key_scan;
+#endif
+
+ // QNX is nice enough to translate the raw keyboard data into a QNX data structure
+ // 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 wheter 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)
+ modifiers |= Qt::ShiftModifier;
+ if (packet.data.flags & KEYMOD_CTRL)
+ modifiers |= Qt::ControlModifier;
+ if (packet.data.flags & KEYMOD_ALT)
+ modifiers |= Qt::AltModifier;
+
+ // 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
+
+ // call processKeyEvent. This is where all the magic happens to insert a
+ // key event into Qt's event loop.
+ // Note that for repeated key events, isPress must be true
+ // (on QNX, isPress is not set when the key event is repeated).
+ processKeyEvent(unicode, key, modifiers, isPress || isRepeat, isRepeat);
+}
diff --git a/src/gui/embedded/qkbdqnx_qws.h b/src/gui/embedded/qkbdqnx_qws.h
new file mode 100644
index 0000000000..c046c8d81d
--- /dev/null
+++ b/src/gui/embedded/qkbdqnx_qws.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QKBDQNX_QWS_H
+#define QKBDQNX_QWS_H
+
+#include <QtGui/qapplication.h>
+#include <QtGui/qkbd_qws.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+#if !defined(QT_NO_QWS_KEYBOARD) && !defined(QT_NO_QWS_KBD_QNX)
+
+class Q_GUI_EXPORT QWSQnxKeyboardHandler : public QObject, public QWSKeyboardHandler
+{
+ Q_OBJECT
+public:
+ QWSQnxKeyboardHandler(const QString &device);
+ ~QWSQnxKeyboardHandler();
+
+private Q_SLOTS:
+ void socketActivated();
+
+private:
+ int keyboardFD;
+};
+
+#endif // QT_NO_QWS_KEYBOARD
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QKBDQNX_QWS_H
diff --git a/src/gui/embedded/qlock.cpp b/src/gui/embedded/qlock.cpp
index 305832cf5d..9592a4d39d 100644
--- a/src/gui/embedded/qlock.cpp
+++ b/src/gui/embedded/qlock.cpp
@@ -41,9 +41,46 @@
#include "qlock_p.h"
-#ifndef QT_NO_QWS_MULTIPROCESS
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_NO_QWS_MULTIPROCESS
+
+/* no multiprocess - use a dummy */
+
+QLock::QLock(const QString & /*filename*/, char /*id*/, bool /*create*/)
+ : type(Read), data(0)
+{
+}
+
+QLock::~QLock()
+{
+}
+
+bool QLock::isValid() const
+{
+ return true;
+}
+
+void QLock::lock(Type t)
+{
+ data = (QLockData *)-1;
+ type = t;
+}
+
+void QLock::unlock()
+{
+ data = 0;
+}
+
+bool QLock::locked() const
+{
+ return data;
+}
+
+#else // QT_NO_QWS_MULTIPROCESS
#include "qwssignalhandler_p.h"
+
#include <unistd.h>
#include <sys/types.h>
#if defined(Q_OS_DARWIN)
@@ -71,16 +108,10 @@ union semun {
#include <qdebug.h>
#include <signal.h>
-#endif // QT_NO_QWS_MULTIPROCESS
-
#include <private/qcore_unix_p.h> // overrides QT_OPEN
#define MAX_LOCKS 200 // maximum simultaneous read locks
-QT_BEGIN_NAMESPACE
-
-
-#ifndef QT_NO_QWS_MULTIPROCESS
class QLockData
{
public:
@@ -91,7 +122,6 @@ public:
int count;
bool owned;
};
-#endif // QT_NO_QWS_MULTIPROCESS
/*!
\class QLock
@@ -126,11 +156,6 @@ public:
QLock::QLock(const QString &filename, char id, bool create)
{
-#ifdef QT_NO_QWS_MULTIPROCESS
- Q_UNUSED(filename);
- Q_UNUSED(id);
- Q_UNUSED(create);
-#else
data = new QLockData;
data->count = 0;
#ifdef Q_NO_SEMAPHORE
@@ -163,7 +188,6 @@ QLock::QLock(const QString &filename, char id, bool create)
qPrintable(filename), id);
qDebug() << "Error" << eno << strerror(eno);
}
-#endif
}
/*!
@@ -174,7 +198,6 @@ QLock::QLock(const QString &filename, char id, bool create)
QLock::~QLock()
{
-#ifndef QT_NO_QWS_MULTIPROCESS
if (locked())
unlock();
#ifdef Q_NO_SEMAPHORE
@@ -188,7 +211,6 @@ QLock::~QLock()
QWSSignalHandler::instance()->removeSemaphore(data->id);
#endif
delete data;
-#endif
}
/*!
@@ -200,11 +222,7 @@ QLock::~QLock()
bool QLock::isValid() const
{
-#ifndef QT_NO_QWS_MULTIPROCESS
return (data->id != -1);
-#else
- return true;
-#endif
}
/*!
@@ -221,9 +239,6 @@ bool QLock::isValid() const
void QLock::lock(Type t)
{
-#ifdef QT_NO_QWS_MULTIPROCESS
- Q_UNUSED(t);
-#else
if (!data->count) {
#ifdef Q_NO_SEMAPHORE
int op = LOCK_SH;
@@ -256,7 +271,6 @@ void QLock::lock(Type t)
#endif
}
data->count++;
-#endif
}
/*!
@@ -269,7 +283,6 @@ void QLock::lock(Type t)
void QLock::unlock()
{
-#ifndef QT_NO_QWS_MULTIPROCESS
if(data->count) {
data->count--;
if(!data->count) {
@@ -298,7 +311,6 @@ void QLock::unlock()
} else {
qDebug("Unlock without corresponding lock");
}
-#endif
}
/*!
@@ -310,11 +322,9 @@ void QLock::unlock()
bool QLock::locked() const
{
-#ifndef QT_NO_QWS_MULTIPROCESS
return (data->count > 0);
-#else
- return false;
-#endif
}
+#endif // QT_NO_QWS_MULTIPROCESS
+
QT_END_NAMESPACE
diff --git a/src/gui/embedded/qmousedriverfactory_qws.cpp b/src/gui/embedded/qmousedriverfactory_qws.cpp
index 46898aed87..6d717505a6 100644
--- a/src/gui/embedded/qmousedriverfactory_qws.cpp
+++ b/src/gui/embedded/qmousedriverfactory_qws.cpp
@@ -47,6 +47,7 @@
#include "qmouselinuxinput_qws.h"
#include "qmousevfb_qws.h"
#include "qmousetslib_qws.h"
+#include "qmouseqnx_qws.h"
#include <stdlib.h>
#include "private/qfactoryloader_p.h"
#include "qmousedriverplugin_qws.h"
@@ -102,6 +103,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
QWSMouseHandler *QMouseDriverFactory::create(const QString& key, const QString &device)
{
QString driver = key.toLower();
+#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX)
+ if (driver == QLatin1String("qnx") || driver.isEmpty())
+ return new QQnxMouseHandler(key, device);
+#endif
#ifndef QT_NO_QWS_MOUSE_LINUXTP
if (driver == QLatin1String("linuxtp") || driver.isEmpty())
return new QWSLinuxTPMouseHandler(key, device);
@@ -149,6 +154,9 @@ QStringList QMouseDriverFactory::keys()
{
QStringList list;
+#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_MOUSE_QNX)
+ list << QLatin1String("QNX");
+#endif
#ifndef QT_NO_QWS_MOUSE_LINUXTP
list << QLatin1String("LinuxTP");
#endif
diff --git a/src/gui/embedded/qmousepc_qws.cpp b/src/gui/embedded/qmousepc_qws.cpp
index 317bb8af04..2d627729ae 100644
--- a/src/gui/embedded/qmousepc_qws.cpp
+++ b/src/gui/embedded/qmousepc_qws.cpp
@@ -332,7 +332,7 @@ protected:
tty.c_oflag = 0;
tty.c_lflag = 0;
tty.c_cflag = f | CREAD | CLOCAL | HUPCL;
-#if !defined(Q_OS_DARWIN) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_INTEGRITY)
+#ifdef Q_OS_LINUX
tty.c_line = 0;
#endif
tty.c_cc[VTIME] = 0;
diff --git a/src/gui/embedded/qmouseqnx_qws.cpp b/src/gui/embedded/qmouseqnx_qws.cpp
new file mode 100644
index 0000000000..98f8f06003
--- /dev/null
+++ b/src/gui/embedded/qmouseqnx_qws.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qmouseqnx_qws.h"
+
+#include "qsocketnotifier.h"
+#include "qdebug.h"
+
+#include <sys/dcmd_input.h>
+
+#include <errno.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QQnxMouseHandler
+ \preliminary
+ \ingroup qws
+ \internal
+ \since 4.6
+
+ \brief The QQnxMouseHandler class implements a mouse driver
+ for the QNX \c{devi-hid} input manager.
+
+ To be able to compile this mouse handler, \l{Qt for Embedded Linux}
+ must be configured with the \c -qt-mouse-qnx option, see the
+ \l{Qt for Embedded Linux Pointer Handling}{Pointer Handling} documentation for details.
+
+ In order to use this mouse handler, the \c{devi-hid} input manager
+ must be set up and run with the resource manager interface (option \c{-r}).
+ Also, Photon must not be running.
+
+ 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
+ a Qt application after invocation of \c{devi-hid}.
+
+ To make \l{Qt for Embedded Linux} explicitly choose the qnx mouse
+ handler, set the QWS_MOUSE_PROTO environment variable to \c{qnx}. By default,
+ the first mouse device (\c{/dev/devi/mouse0}) is used. To override, pass a device
+ name as the first and only parameter, for example
+ \c{QWS_MOUSE_PROTO=qnx:/dev/devi/mouse1; export QWS_MOUSE_PROTO}.
+
+ \sa {Qt for Embedded Linux Pointer Handling}{Pointer Handling}, {Qt for Embedded Linux}
+*/
+
+/*!
+ Constructs a mouse handler for the specified \a device, defaulting to \c{/dev/devi/mouse0}.
+ The \a driver parameter must be \c{"qnx"}.
+
+ Note that you should never instanciate this class, instead let QMouseDriverFactory
+ handle the mouse handlers.
+
+ \sa QMouseDriverFactory
+ */
+QQnxMouseHandler::QQnxMouseHandler(const QString & /*driver*/, const QString &device)
+{
+ // 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);
+ if (mouseFD == -1) {
+ qErrnoWarning(errno, "QQnxMouseHandler: Unable to open mouse device");
+ return;
+ }
+
+ // 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.";
+}
+
+/*!
+ Destroys this mouse handler and closes the connection to the mouse device.
+ */
+QQnxMouseHandler::~QQnxMouseHandler()
+{
+ QT_CLOSE(mouseFD);
+}
+
+/*! \reimp */
+void QQnxMouseHandler::resume()
+{
+ if (mouseNotifier)
+ mouseNotifier->setEnabled(true);
+}
+
+/*! \reimp */
+void QQnxMouseHandler::suspend()
+{
+ if (mouseNotifier)
+ mouseNotifier->setEnabled(false);
+}
+
+/*! \internal
+
+ This function is called whenever there is activity on the mouse device.
+ By default, it reads up to 10 mouse move packets and calls mouseChanged()
+ for each of them.
+*/
+void QQnxMouseHandler::socketActivated()
+{
+ // _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;
+
+ 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));
+ 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;
+ }
+
+ // bytes read should always be equal to the size of a packet.
+ Q_ASSERT(bytesRead == sizeof(packet));
+
+ // 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);
+
+ // QNX only tells us relative mouse movements, not absolute ones, so limit the
+ // cursor position manually to the screen
+ limitToScreen(pos);
+
+ // 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)
+ buttons |= Qt::MidButton;
+ 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);
+}
+
+QT_END_NAMESPACE
+
diff --git a/src/gui/embedded/qmouseqnx_qws.h b/src/gui/embedded/qmouseqnx_qws.h
new file mode 100644
index 0000000000..a61562e2fb
--- /dev/null
+++ b/src/gui/embedded/qmouseqnx_qws.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMOUSE_QNX_H
+#define QMOUSE_QNX_H
+
+#include <QtCore/qobject.h>
+#include <QtGui/qmouse_qws.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+class QSocketNotifier;
+
+class Q_GUI_EXPORT QQnxMouseHandler : public QObject, public QWSMouseHandler
+{
+ Q_OBJECT
+public:
+ explicit QQnxMouseHandler(const QString &driver = QString(),
+ const QString &device = QString());
+ ~QQnxMouseHandler();
+
+ void resume();
+ void suspend();
+
+private Q_SLOTS:
+ void socketActivated();
+
+private:
+ QSocketNotifier *mouseNotifier;
+ int mouseFD;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QMOUSE_QWS_H
diff --git a/src/gui/embedded/qscreendriverfactory_qws.cpp b/src/gui/embedded/qscreendriverfactory_qws.cpp
index 229062775e..b531798b74 100644
--- a/src/gui/embedded/qscreendriverfactory_qws.cpp
+++ b/src/gui/embedded/qscreendriverfactory_qws.cpp
@@ -47,6 +47,7 @@
#include "qscreentransformed_qws.h"
#include "qscreenvfb_qws.h"
#include "qscreenmulti_qws_p.h"
+#include "qscreenqnx_qws.h"
#include <stdlib.h>
#include "private/qfactoryloader_p.h"
#include "qscreendriverplugin_qws.h"
@@ -105,6 +106,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
QScreen *QScreenDriverFactory::create(const QString& key, int displayId)
{
QString driver = key.toLower();
+#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_QNX)
+ if (driver == QLatin1String("qnx") || driver.isEmpty())
+ return new QQnxScreen(displayId);
+#endif
#ifndef QT_NO_QWS_QVFB
if (driver == QLatin1String("qvfb") || driver.isEmpty())
return new QVFbScreen(displayId);
@@ -146,6 +151,9 @@ QStringList QScreenDriverFactory::keys()
{
QStringList list;
+#if defined(Q_OS_QNX) && !defined(QT_NO_QWS_QNX)
+ list << QLatin1String("QNX");
+#endif
#ifndef QT_NO_QWS_QVFB
list << QLatin1String("QVFb");
#endif
diff --git a/src/gui/embedded/qscreenqnx_qws.cpp b/src/gui/embedded/qscreenqnx_qws.cpp
new file mode 100644
index 0000000000..7101bc7865
--- /dev/null
+++ b/src/gui/embedded/qscreenqnx_qws.cpp
@@ -0,0 +1,447 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qscreenqnx_qws.h"
+#include "qdebug.h"
+
+#include <gf/gf.h>
+
+// This struct holds all the pointers to QNX's internals
+struct QQnxScreenContext
+{
+ inline QQnxScreenContext()
+ : device(0), display(0), layer(0), hwSurface(0), memSurface(0), context(0)
+ {}
+
+ gf_dev_t device;
+ gf_dev_info_t deviceInfo;
+ gf_display_t display;
+ gf_display_info_t displayInfo;
+ gf_layer_t layer;
+ gf_surface_t hwSurface;
+ gf_surface_t memSurface;
+ gf_surface_info_t memSurfaceInfo;
+ gf_context_t context;
+};
+
+/*!
+ \class QQnxScreen
+ \preliminary
+ \ingroup qws
+ \since 4.6
+ \internal
+
+ \brief The QQnxScreen class implements a screen driver
+ for QNX io-display based devices.
+
+ Note - you never have to instanciate this class, the QScreenDriverFactory
+ does that for us based on the \c{QWS_DISPLAY} environment variable.
+
+ To activate this driver, set \c{QWS_DISPLAY} to \c{qnx}.
+
+ Example:
+ \c{QWS_DISPLAY=qnx; export QWS_DISPLAY}
+
+ By default, the main layer of the first display of the first device is used.
+ If you have multiple graphic cards, multiple displays or multiple layers and
+ don't want to connect to the default, you can override that with setting
+ the corresponding options \c{device}, \c{display} or \c{layer} in the \c{QWS_DISPLAY} variable:
+
+ \c{QWS_DISPLAY=qnx:device=3:display=4:layer=5}
+
+ In addition, it is suggested to set the physical width and height of the display.
+ QQnxScreen will use that information to compute the dots per inch (DPI) in order to render
+ fonts correctly. If this informaiton is omitted, QQnxScreen defaults to 72 dpi.
+
+ \c{QWS_DISPLAY=qnx:mmWidth=120:mmHeight=80}
+
+ \c{mmWidth} and \c{mmHeight} are the physical width/height of the screen in millimeters.
+
+ \sa QScreen, QScreenDriverPlugin, {Running Qt for Embedded Linux Applications}{Running Applications}
+*/
+
+/*!
+ Constructs a QQnxScreen object. The \a display_id argument
+ identifies the Qt for Embedded Linux server to connect to.
+*/
+QQnxScreen::QQnxScreen(int display_id)
+ : QScreen(display_id), d(new QQnxScreenContext)
+{
+}
+
+/*!
+ Destroys this QQnxScreen object.
+*/
+QQnxScreen::~QQnxScreen()
+{
+ delete d;
+}
+
+/*! \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)
+ return true;
+}
+
+/*! \internal
+ Attaches to the named device \a name.
+*/
+static bool attachDevice(QQnxScreenContext * const d, const char *name)
+{
+ int ret = gf_dev_attach(&d->device, name, &d->deviceInfo);
+ if (ret != GF_ERR_OK) {
+ qWarning("QQnxScreen: gf_dev_attach(%s) failed with error code %d", name, ret);
+ return false;
+ }
+ return true;
+}
+
+/*! \internal
+ Attaches to the display at index \a displayIndex.
+ */
+static 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);
+ return false;
+ }
+ return true;
+}
+
+/*! \internal
+ Attaches to the layer \a layerIndex.
+ */
+static bool attachLayer(QQnxScreenContext * const d, int layerIndex)
+{
+ int ret = gf_layer_attach(&d->layer, d->display, layerIndex, 0);
+ if (ret != GF_ERR_OK) {
+ 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)
+{
+ int ret = gf_surface_create_layer(&d->hwSurface, &d->layer, 1, 0,
+ w, h, GF_FORMAT_ARGB8888, 0, 0);
+ if (ret != GF_ERR_OK) {
+ 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);
+
+ 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);
+ if (ret != GF_ERR_OK) {
+ qWarning("QQnxScreen: gf_surface_create(%dx%d) failed with error code %d",
+ w, h, 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.");
+ return false;
+ }
+
+ return true;
+}
+
+/* \internal
+ Creates a QNX gf context and sets our memory surface on it.
+ */
+static bool createContext(QQnxScreenContext * const d)
+{
+ int ret = gf_context_create(&d->context);
+ if (ret != GF_ERR_OK) {
+ qWarning("QQnxScreen: gf_context_create() failed with error code %d", 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);
+ 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.
+
+ \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));
+ }
+
+ if (!isOk)
+ 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();
+ }
+
+ 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);
+
+
+ // 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;
+ }
+
+ if (!attachLayer(d, layerIndex))
+ 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;
+
+ // 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();
+ }
+
+ QRegExp mmHeightRegexp(QLatin1String("^mmHeight=(\\d+)$"));
+ if (params.indexOf(mmHeightRegexp) == -1) {
+ physHeight = qRound(dh * 25.4 / defaultDpi);
+ } else {
+ physHeight = mmHeightRegexp.cap(1).toInt();
+ }
+
+ // 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;
+
+ // set the address of the in-memory buffer that QWS is blitting to
+ data = d->memSurfaceInfo.vaddr;
+ // set the line stepping
+ lstep = d->memSurfaceInfo.stride;
+
+ // 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
+ */
+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;
+}
+
+/*! \reimp
+ */
+void QQnxScreen::shutdownDevice()
+{
+}
+
+
+/*! \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
+ */
+bool QQnxScreen::supportsDepth(int depth) const
+{
+ // only 32-bit for the moment
+ return depth == 32;
+}
+
+/*! \reimp
+ */
+void QQnxScreen::exposeRegion(QRegion r, int changing)
+{
+ // here is where the actual magic happens. QWS will call exposeRegion whenever
+ // a region on the screen is dirty and needs to be updated on the actual screen.
+
+ // first, call the parent implementation. The parent implementation will update
+ // the region on our in-memory surface
+ QScreen::exposeRegion(r, changing);
+
+ // now our in-memory surface should be up to date with the latest changes.
+ // 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
+ // anyways. Code could be optimized to blit each and every member of the region
+ // individually, but in real life, the speed-up is neglectable
+ const QRect br = r.boundingRect();
+ if (br.isEmpty())
+ return; // ignore empty regions because gf_draw_blit2 doesn't like 0x0 dimensions
+
+ // start drawing.
+ int ret = gf_draw_begin(d->context);
+ if (ret != GF_ERR_OK) {
+ qWarning("QQnxScreen: gf_draw_begin() failed with error code %d", ret);
+ return;
+ }
+
+ // 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) {
+ 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) {
+ 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
new file mode 100644
index 0000000000..837c0613dd
--- /dev/null
+++ b/src/gui/embedded/qscreenqnx_qws.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSCREENQNX_QWS_H
+#define QSCREENQNX_QWS_H
+
+#include <QtGui/qscreen_qws.h>
+
+#ifndef QT_NO_QWS_QNX
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Gui)
+
+struct QQnxScreenContext;
+
+class QQnxScreen : public QScreen
+{
+public:
+ explicit QQnxScreen(int display_id);
+ ~QQnxScreen();
+
+ bool initDevice();
+ bool connect(const QString &displaySpec);
+ void disconnect();
+ void shutdownDevice();
+ void setMode(int,int,int);
+ bool supportsDepth(int) const;
+
+ void exposeRegion(QRegion r, int changing);
+
+private:
+ QQnxScreenContext * const d;
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QT_NO_QWS_QNX
+
+#endif
diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp
index 0580198e5c..624ba84dbd 100644
--- a/src/gui/embedded/qwindowsystem_qws.cpp
+++ b/src/gui/embedded/qwindowsystem_qws.cpp
@@ -39,6 +39,8 @@
**
****************************************************************************/
+#include "qplatformdefs.h"
+
#include "qwindowsystem_qws.h"
#include "qwsevent_qws.h"
#include "qwscommand_qws_p.h"
@@ -71,24 +73,26 @@
#include <qdebug.h>
-#include <unistd.h>
+#include "qkbddriverfactory_qws.h"
+#include "qmousedriverfactory_qws.h"
+
+#include <qbuffer.h>
+#include <qdir.h>
+
+#include <private/qwindowsurface_qws_p.h>
+#include <private/qfontengine_qpf_p.h>
+
+#include "qwindowsystem_p.h"
+
+
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#ifndef QT_NO_QWS_MULTIPROCESS
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#ifndef Q_OS_DARWIN
-# include <sys/sem.h>
-#endif
#include <sys/param.h>
#include <sys/mount.h>
#endif
-#include <signal.h>
-#include <fcntl.h>
#if !defined(QT_NO_SOUND) && !defined(Q_OS_DARWIN)
#ifdef QT_USE_OLD_QWS_SOUND
@@ -101,17 +105,6 @@
#endif
#endif
-#include "qkbddriverfactory_qws.h"
-#include "qmousedriverfactory_qws.h"
-
-#include <qbuffer.h>
-#include <qdir.h>
-
-#include <private/qwindowsurface_qws_p.h>
-#include <private/qfontengine_qpf_p.h>
-
-#include "qwindowsystem_p.h"
-
//#define QWS_DEBUG_FONTCLEANUP
QT_BEGIN_NAMESPACE
@@ -1400,7 +1393,7 @@ void QWSServerPrivate::initServer(int flags)
#ifndef QT_NO_QWS_MULTIPROCESS
if (!geteuid()) {
-#if !defined(Q_OS_FREEBSD) && !defined(Q_OS_SOLARIS) && !defined(Q_OS_DARWIN) && !defined(QT_LINUXBASE)
+#if defined(Q_OS_LINUX) && !defined(QT_LINUXBASE)
if(mount(0,"/var/shm", "shm", 0, 0)) {
/* This just confuses people with 2.2 kernels
if (errno != EBUSY)
diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp
index 6deeaf4626..00695faea5 100644
--- a/src/gui/kernel/qapplication_qws.cpp
+++ b/src/gui/kernel/qapplication_qws.cpp
@@ -198,7 +198,14 @@ QString qws_dataDir()
static QString result;
if (!result.isEmpty())
return result;
- QByteArray dataDir = QString::fromLatin1("/tmp/qtembedded-%1").arg(qws_display_id).toLocal8Bit();
+ QByteArray dataDir;
+#ifdef QT_QWS_TEMP_DIR
+ dataDir = QT_QWS_TEMP_DIR;
+#else
+ dataDir = "/tmp";
+#endif
+ dataDir += "/qtembedded-";
+ dataDir += QByteArray::number(qws_display_id);
if (QT_MKDIR(dataDir, 0700)) {
if (errno != EEXIST) {
qFatal("Cannot create Qt for Embedded Linux data directory: %s", dataDir.constData());
diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp
index d348e1bdd2..34239ff3b6 100644
--- a/src/gui/text/qfontdatabase_qws.cpp
+++ b/src/gui/text/qfontdatabase_qws.cpp
@@ -360,7 +360,7 @@ static QString qwsFontPath()
return fontpath;
}
-#ifdef QFONTDATABASE_DEBUG
+#if defined(QFONTDATABASE_DEBUG) && defined(QT_FONTS_ARE_RESOURCES)
class FriendlyResource : public QResource
{
public:
@@ -694,8 +694,12 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp,
QFontDef def = request;
def.pixelSize = pixelSize;
+#ifdef QT_NO_QWS_SHARE_FONTS
+ bool shareFonts = false;
+#else
static bool dontShareFonts = !qgetenv("QWS_NO_SHARE_FONTS").isEmpty();
bool shareFonts = !dontShareFonts;
+#endif
QFontEngine *engine = 0;
diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp
index b2556944e1..ed8abb8c39 100644
--- a/src/gui/text/qfontengine_qpf.cpp
+++ b/src/gui/text/qfontengine_qpf.cpp
@@ -331,16 +331,37 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng
#if defined(DEBUG_FONTENGINE)
qDebug() << "found existing qpf:" << fileName;
#endif
- if (::access(encodedName, W_OK | R_OK) == 0)
- fd = QT_OPEN(encodedName, O_RDWR, 0);
- else if (::access(encodedName, R_OK) == 0)
- fd = QT_OPEN(encodedName, O_RDONLY, 0);
+ if (::access(encodedName, W_OK | R_OK) == 0) {
+ fd = QT_OPEN(encodedName, O_RDWR);
+ }
+ // read-write access failed - try read-only access
+ if (fd == -1 && ::access(encodedName, R_OK) == 0) {
+ fd = QT_OPEN(encodedName, O_RDONLY);
+ if (fd == -1) {
+#if defined(DEBUG_FONTENGINE)
+ qErrnoWarning("QFontEngineQPF: unable to open %s", encodedName.constData());
+#endif
+ return;
+ }
+ }
+ if (fd == -1) {
+#if defined(DEBUG_FONTENGINE)
+ qWarning("QFontEngineQPF: insufficient access rights to %s", encodedName.constData());
+#endif
+ return;
+ }
} else {
#if defined(DEBUG_FONTENGINE)
qDebug() << "creating qpf on the fly:" << fileName;
#endif
if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) {
fd = QT_OPEN(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644);
+ if (fd == -1) {
+#if defined(DEBUG_FONTENGINE)
+ qErrnoWarning(errno, "QFontEngineQPF: open() failed for %s", encodedName.constData());
+#endif
+ return;
+ }
QBuffer buffer;
buffer.open(QIODevice::ReadWrite);
@@ -348,7 +369,17 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng
generator.generate();
buffer.close();
const QByteArray &data = buffer.data();
- QT_WRITE(fd, data.constData(), data.size());
+ if (QT_WRITE(fd, data.constData(), data.size()) == -1) {
+#if defined(DEBUG_FONTENGINE)
+ qErrnoWarning(errno, "QFontEngineQPF: write() failed for %s", encodedName.constData());
+#endif
+ return;
+ }
+ } else {
+#if defined(DEBUG_FONTENGINE)
+ qErrnoWarning(errno, "QFontEngineQPF: access() failed for %s", qPrintable(qws_fontCacheDir()));
+#endif
+ return;
}
}
}
@@ -356,7 +387,7 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng
QT_STATBUF st;
if (QT_FSTAT(fd, &st)) {
#if defined(DEBUG_FONTENGINE)
- qDebug() << "stat failed!";
+ qErrnoWarning(errno, "QFontEngineQPF: fstat failed!");
#endif
return;
}
@@ -486,8 +517,13 @@ QFontEngineQPF::~QFontEngineQPF()
qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, QFile::encodeName(fileName));
#endif
delete renderingFontEngine;
- if (fontData)
- munmap((void *)fontData, dataSize);
+ if (fontData) {
+ if (munmap((void *)fontData, dataSize) == -1) {
+#if defined(DEBUG_FONTENGINE)
+ qErrnoWarning(errno, "~QFontEngineQPF: Unable to munmap");
+#endif
+ }
+ }
if (fd != -1)
::close(fd);
#if !defined(QT_NO_FREETYPE)