qt5_qtbase_genode.patch From: Christian Prochaska Genode-specific adaptations --- qtbase/src/corelib/codecs/qtextcodec.cpp | 4 + qtbase/src/corelib/global/qlogging.cpp | 6 ++ qtbase/src/corelib/global/qsystemdetection.h | 5 +- qtbase/src/corelib/io/qprocess.cpp | 64 ++++++++++++++++++++ qtbase/src/corelib/io/qprocess_p.h | 45 ++++++++++++++ qtbase/src/corelib/io/qresource.cpp | 2 - qtbase/src/corelib/kernel/qcoreapplication.cpp | 2 - .../src/corelib/kernel/qeventdispatcher_unix.cpp | 14 ++++ qtbase/src/corelib/kernel/qtranslator.cpp | 2 - qtbase/src/corelib/thread/qthread.cpp | 5 +- qtbase/src/corelib/thread/qthread_p.h | 55 +++++++++++++++++ qtbase/src/corelib/tools/qdatetime.cpp | 15 +++++ qtbase/src/gui/image/qxpmhandler.cpp | 8 +++ .../network/access/qnetworkaccessfilebackend.cpp | 5 ++ qtbase/src/network/kernel/qhostinfo.cpp | 5 ++ qtbase/src/network/kernel/qhostinfo_unix.cpp | 7 ++ qtbase/src/widgets/dialogs/qfiledialog.cpp | 2 - qtbase/src/widgets/styles/qstylefactory.cpp | 7 ++ 18 files changed, 245 insertions(+), 8 deletions(-) diff --git a/qtbase/src/corelib/codecs/qtextcodec.cpp b/qtbase/src/corelib/codecs/qtextcodec.cpp index 1cedd3a..646be07 100644 --- a/qtbase/src/corelib/codecs/qtextcodec.cpp +++ b/qtbase/src/corelib/codecs/qtextcodec.cpp @@ -203,7 +203,11 @@ static QTextCodec *setupLocaleMapper() // First part is getting that locale name. First try setlocale() which // definitely knows it, but since we cannot fully trust it, get ready // to fall back to environment variables. +#ifdef Q_OS_GENODE + const QByteArray ctype; +#else const QByteArray ctype = setlocale(LC_CTYPE, 0); +#endif /* Q_OS_GENODE */ // Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG // environment variables. diff --git a/qtbase/src/corelib/global/qlogging.cpp b/qtbase/src/corelib/global/qlogging.cpp index c8293be..c7e9422 100644 --- a/qtbase/src/corelib/global/qlogging.cpp +++ b/qtbase/src/corelib/global/qlogging.cpp @@ -61,6 +61,10 @@ #include #endif +#ifdef Q_OS_GENODE +#include +#endif + #include QT_BEGIN_NAMESPACE @@ -875,6 +879,8 @@ static void qDefaultMessageHandler(QtMsgType type, const QMessageLogContext &con #if defined(QT_USE_SLOG2) slog2_default_handler(type, logMessage.toLocal8Bit().constData()); +#elif defined(Q_OS_GENODE) + PDBG("%s", logMessage.toLocal8Bit().constData()); #elif defined(Q_OS_ANDROID) static bool logToAndroid = qEnvironmentVariableIsEmpty("QT_ANDROID_PLAIN_LOG"); if (logToAndroid) { diff --git a/qtbase/src/corelib/global/qsystemdetection.h b/qtbase/src/corelib/global/qsystemdetection.h index cb55fa8..7d5c507 100644 --- a/qtbase/src/corelib/global/qsystemdetection.h +++ b/qtbase/src/corelib/global/qsystemdetection.h @@ -49,6 +49,7 @@ /* The operating system, must be one of: (Q_OS_x) + GENODE - Genode DARWIN - Darwin OS (synonym for Q_OS_MAC) MAC - OS X or iOS (synonym for Q_OS_DARWIN) MACX - OS X @@ -84,7 +85,9 @@ ANDROID - Android platform */ -#if defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__)) +#if defined(__GENODE__) +# define Q_OS_GENODE +#elif defined(__APPLE__) && (defined(__GNUC__) || defined(__xlC__) || defined(__xlc__)) # define Q_OS_DARWIN # define Q_OS_BSD4 # ifdef __LP64__ diff --git a/qtbase/src/corelib/io/qprocess.cpp b/qtbase/src/corelib/io/qprocess.cpp index b1861d8..b1cbf57 100644 --- a/qtbase/src/corelib/io/qprocess.cpp +++ b/qtbase/src/corelib/io/qprocess.cpp @@ -98,6 +98,11 @@ QT_END_NAMESPACE #include #endif +#ifdef Q_OS_GENODE +#include +#include +#endif + #ifndef QT_NO_PROCESS QT_BEGIN_NAMESPACE @@ -789,6 +794,65 @@ QProcessPrivate::QProcessPrivate() #ifdef Q_OS_UNIX serial = 0; #endif +#ifdef Q_OS_GENODE + launchpad_child = 0; + + /* request config file from ROM service */ + Genode::Rom_connection rom("config"); + rom.on_destruction(Genode::Rom_connection::KEEP_OPEN); + void *addr; + try { + addr = Genode::env()->rm_session()->attach(rom.dataspace()); + } catch(Genode::Parent::Service_denied) { + qWarning("Error: Couldn't open config file."); + return; + } + + /* + * The XML data of a valid config file starts with + * a tag. + */ + Genode::Xml_node config_node((const char *)addr); + + if (!config_node.has_type("config")) { + qWarning("Error: Root node of config file is not a tag."); + return; + } + + /* + * Iterate through all entries of the config file and start + * children as specified. + */ + for (int i = 0; i < config_node.num_sub_nodes(); i++) { + Genode::Xml_node program_node = config_node.sub_node(i); + if (program_node.has_type("program")) { + + /* add filename and ram_quota to ram_quota_hash */ + char filename[32]; + try { + program_node.sub_node("filename").value(filename, sizeof(filename)); + } catch (Genode::Xml_node::Nonexistent_sub_node) { + qWarning("Warning: Missing valid in config-file entry."); + return; + } + + size_t ram_quota = 0; + try { + program_node.sub_node("ram_quota").value(&ram_quota); + } catch (Genode::Xml_node::Nonexistent_sub_node) { + qWarning("Warning: Missing valid in config-file entry."); + return; + } + + ram_quota_hash()->insert(QString(filename), ram_quota); + } else { + char buf[32]; + program_node.type_name(buf, sizeof(buf)); + qWarning("Warning: Ignoring unsupported tag <%s>.", buf); + } + } + +#endif } /*! diff --git a/qtbase/src/corelib/io/qprocess_p.h b/qtbase/src/corelib/io/qprocess_p.h index 2a2cc9f..2173aa0 100644 --- a/qtbase/src/corelib/io/qprocess_p.h +++ b/qtbase/src/corelib/io/qprocess_p.h @@ -74,6 +74,11 @@ typedef int Q_PIPE; #ifndef QT_NO_PROCESS +#ifdef Q_OS_GENODE +#include +#include +#endif + QT_BEGIN_NAMESPACE class QSocketNotifier; @@ -235,6 +240,28 @@ template<> Q_INLINE_TEMPLATE void QSharedDataPointer d = x; } +#ifdef Q_OS_GENODE + +class QProcess_launchpad : public Launchpad +{ +public: + QProcess_launchpad(unsigned long initial_quota) : Launchpad(initial_quota) {} + + virtual void quota(unsigned long quota) {} + + virtual void add_launcher(const char *filename, + unsigned long default_quota) {} + + virtual void add_child(const char *unique_name, + unsigned long quota, + Launchpad_child *launchpad_child, + Genode::Allocator *alloc) {} + + virtual void remove_child(const char *name, Genode::Allocator *alloc) {} +}; + +#endif + class QProcessPrivate : public QIODevicePrivate { public: @@ -347,7 +374,7 @@ public: #endif void startProcess(); -#if defined(Q_OS_UNIX) && !defined(Q_OS_QNX) +#if defined(Q_OS_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_GENODE) 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); @@ -375,6 +402,22 @@ public: int serial; #endif +#ifdef Q_OS_GENODE + static QProcess_launchpad *launchpad() + { + static QProcess_launchpad _launchpad(Genode::env()->ram_session()->quota()); + return &_launchpad; + } + + static QHash *ram_quota_hash() + { + static QHash _ram_quota_hash; + return &_ram_quota_hash; + } + + Launchpad_child *launchpad_child; +#endif + bool waitForStarted(int msecs = 30000); bool waitForReadyRead(int msecs = 30000); bool waitForBytesWritten(int msecs = 30000); diff --git a/qtbase/src/corelib/io/qresource.cpp b/qtbase/src/corelib/io/qresource.cpp index 04ec81e..2211125 100644 --- a/qtbase/src/corelib/io/qresource.cpp +++ b/qtbase/src/corelib/io/qresource.cpp @@ -920,7 +920,7 @@ public: } }; -#if defined(Q_OS_UNIX) && !defined (Q_OS_NACL) && !defined(Q_OS_INTEGRITY) +#if defined(Q_OS_UNIX) && !defined (Q_OS_NACL) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_GENODE) #define QT_USE_MMAP #endif diff --git a/qtbase/src/corelib/kernel/qcoreapplication.cpp b/qtbase/src/corelib/kernel/qcoreapplication.cpp index 100e014..00263a0 100644 --- a/qtbase/src/corelib/kernel/qcoreapplication.cpp +++ b/qtbase/src/corelib/kernel/qcoreapplication.cpp @@ -525,7 +525,7 @@ void QCoreApplicationPrivate::initLocale() if (qt_locale_initialized) return; qt_locale_initialized = true; -#ifdef Q_OS_UNIX +#if defined(Q_OS_UNIX) && !defined(Q_OS_GENODE) setlocale(LC_ALL, ""); #endif } diff --git a/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp b/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp index 69363bc..0a7aa7d 100644 --- a/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/qtbase/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -74,6 +74,11 @@ # include #endif +#ifdef Q_OS_GENODE +#include +#define perror PERR +#endif /* Q_OS_GENODE */ + QT_BEGIN_NAMESPACE #if defined(Q_OS_INTEGRITY) || defined(Q_OS_VXWORKS) @@ -287,6 +292,9 @@ int QEventDispatcherUNIXPrivate::processThreadWakeUp(int nsel) char c[16]; ::read(thread_pipe[0], c, sizeof(c)); ::ioctl(thread_pipe[0], FIOFLUSH, 0); +#elif defined(Q_OS_GENODE) + char c[16]; + ::read(thread_pipe[0], c, sizeof(c)); // FIXME: the while loop only works in non-blocking mode #else # ifndef QT_NO_EVENTFD if (thread_pipe[1] == -1) { @@ -325,6 +333,12 @@ QEventDispatcherUNIX::~QEventDispatcherUNIX() int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timespec *timeout) { +#ifdef Q_OS_GENODE + /* if < 10ms round up to the 10ms minimum granularity supported by + * the timed semaphore */ + if (timeout && (timeout->tv_sec == 0) && (timeout->tv_nsec > 0) && (timeout->tv_nsec < 10*1000*1000)) + timeout->tv_nsec = 10*1000*1000; +#endif /* Q_OS_GENODE */ return qt_safe_select(nfds, readfds, writefds, exceptfds, timeout); } diff --git a/qtbase/src/corelib/kernel/qtranslator.cpp b/qtbase/src/corelib/kernel/qtranslator.cpp index 9243d09..d953b20 100644 --- a/qtbase/src/corelib/kernel/qtranslator.cpp +++ b/qtbase/src/corelib/kernel/qtranslator.cpp @@ -60,7 +60,7 @@ #include "qendian.h" #include "qresource.h" -#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) +#if defined(Q_OS_UNIX) && !defined(Q_OS_INTEGRITY) && !defined(Q_OS_GENODE) #define QT_USE_MMAP #include "private/qcore_unix_p.h" #endif diff --git a/qtbase/src/corelib/thread/qthread.cpp b/qtbase/src/corelib/thread/qthread.cpp index 4d5bee3..622056e 100644 --- a/qtbase/src/corelib/thread/qthread.cpp +++ b/qtbase/src/corelib/thread/qthread.cpp @@ -150,7 +150,10 @@ QThreadPrivate::QThreadPrivate(QThreadData *d) stackSize(0), priority(QThread::InheritPriority), data(d) { #if defined (Q_OS_UNIX) - thread_id = 0; + thread_id = 0; +#ifdef Q_OS_GENODE + genode_thread = 0; +#endif /* Q_OS_GENODE */ #elif defined (Q_OS_WIN) handle = 0; id = 0; diff --git a/qtbase/src/corelib/thread/qthread_p.h b/qtbase/src/corelib/thread/qthread_p.h index 9d773b3..9beb7e6 100644 --- a/qtbase/src/corelib/thread/qthread_p.h +++ b/qtbase/src/corelib/thread/qthread_p.h @@ -54,6 +54,10 @@ // // +#ifdef Q_OS_GENODE +#include +#endif + #include "qplatformdefs.h" #include "QtCore/qthread.h" #include "QtCore/qmutex.h" @@ -160,12 +164,63 @@ public: static QThread *threadForId(int id); #ifdef Q_OS_UNIX +#ifdef Q_OS_GENODE + + class Genode_thread : public Genode::Thread_qt + { + private: + + /* + * The '_finished_lock' is necessary because 'QThreadPrivate::mutex' + * uses a 'Genode::Timed_semaphore' internally and it isn't safe + * to delete a Genode thread that just called 'Semaphore::up()', + * because the 'Semaphore::_meta_lock' could still be locked. + */ + Genode::Lock _finished_lock; + QThread *_qthread; + + public: + + Genode_thread(QThread *qthread) + : _finished_lock(Genode::Lock::LOCKED), + _qthread(qthread) { } + + virtual void entry() + { + QThreadPrivate::start(_qthread); + QThreadPrivate::finish(_qthread); + _finished_lock.unlock(); + } + + void join() + { + _finished_lock.lock(); + } + }; + + Genode_thread *genode_thread; + + struct tls_struct { + QThreadData *data; + bool termination_enabled; + }; + + static QHash tls; + + Qt::HANDLE thread_id; + QWaitCondition thread_done; + + static void *start(void *arg); + static void finish(void *arg); + +#else // Q_OS_UNIX && !Q_OS_GENODE pthread_t thread_id; QWaitCondition thread_done; static void *start(void *arg); static void finish(void *); +#endif // Q_OS_GENODE #endif // Q_OS_UNIX #ifdef Q_OS_WIN diff --git a/qtbase/src/corelib/tools/qdatetime.cpp b/qtbase/src/corelib/tools/qdatetime.cpp index d8e3a78..78202c6 100644 --- a/qtbase/src/corelib/tools/qdatetime.cpp +++ b/qtbase/src/corelib/tools/qdatetime.cpp @@ -3072,9 +3072,14 @@ QTime QTime::currentTime() // posix compliant system struct timeval tv; gettimeofday(&tv, 0); + time_t ltime = tv.tv_sec; struct tm *t = 0; +#ifdef Q_OS_GENODE + struct tm res; + t = gmtime_r(<ime, &res); +#else /* Q_OS_GENODE */ #if !defined(QT_NO_THREAD) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) // use the reentrant version of localtime() where available tzset(); @@ -3083,9 +3088,11 @@ QTime QTime::currentTime() #else t = localtime(<ime); #endif +#endif /* Q_OS_GENODE */ Q_CHECK_PTR(t); ct.mds = msecsFromDecomposed(t->tm_hour, t->tm_min, t->tm_sec, tv.tv_usec / 1000); + return ct; } @@ -3970,6 +3977,10 @@ static QDate adjustDate(QDate date) static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) { +#ifdef Q_OS_GENODE + /* no timezones in Genode */ + return QDateTimePrivate::LocalUnknown; +#endif QDate fakeDate = adjustDate(date); // won't overflow because of fakeDate @@ -4023,6 +4034,10 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) static void localToUtc(QDate &date, QTime &time, int isdst) { +#ifdef Q_OS_GENODE + /* no timezones in Genode */ + return; +#endif if (!date.isValid()) return; diff --git a/qtbase/src/gui/image/qxpmhandler.cpp b/qtbase/src/gui/image/qxpmhandler.cpp index a7936f9..eee3a87 100644 --- a/qtbase/src/gui/image/qxpmhandler.cpp +++ b/qtbase/src/gui/image/qxpmhandler.cpp @@ -848,8 +848,16 @@ static bool read_xpm_header( #if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(Q_OS_WINCE) if (sscanf_s(buf, "%d %d %d %d", w, h, ncols, cpp) < 4) #else +#ifdef Q_OS_GENODE + *w = QString(buf).section(" ", 0, 0, QString::SectionSkipEmpty).toInt(); + *h = QString(buf).section(" ", 1, 1, QString::SectionSkipEmpty).toInt(); + *ncols = QString(buf).section(" ", 2, 2, QString::SectionSkipEmpty).toInt(); + *cpp = QString(buf).section(" ", 3, 3, QString::SectionSkipEmpty).toInt(); + if (*w <= 0 || *h <= 0 || *ncols <= 0 || *cpp <= 0) +#else if (sscanf(buf, "%d %d %d %d", w, h, ncols, cpp) < 4) #endif +#endif return false; // < 4 numbers parsed return true; diff --git a/qtbase/src/network/access/qnetworkaccessfilebackend.cpp b/qtbase/src/network/access/qnetworkaccessfilebackend.cpp index 13428cc..0713528 100644 --- a/qtbase/src/network/access/qnetworkaccessfilebackend.cpp +++ b/qtbase/src/network/access/qnetworkaccessfilebackend.cpp @@ -115,6 +115,7 @@ void QNetworkAccessFileBackend::open() url.setPath(QLatin1String("/")); setUrl(url); +#ifndef Q_OS_GENODE QString fileName = url.toLocalFile(); if (fileName.isEmpty()) { if (url.scheme() == QLatin1String("qrc")) { @@ -128,6 +129,10 @@ void QNetworkAccessFileBackend::open() fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); } } +#else + QString fileName = QLatin1String(":") + url.path(); +#endif + file.setFileName(fileName); if (operation() == QNetworkAccessManager::GetOperation) { diff --git a/qtbase/src/network/kernel/qhostinfo.cpp b/qtbase/src/network/kernel/qhostinfo.cpp index d25372e..131100e 100644 --- a/qtbase/src/network/kernel/qhostinfo.cpp +++ b/qtbase/src/network/kernel/qhostinfo.cpp @@ -508,7 +508,12 @@ QHostInfoLookupManager::QHostInfoLookupManager() : mutex(QMutex::Recursive), was { moveToThread(QCoreApplicationPrivate::mainThread()); connect(QCoreApplication::instance(), SIGNAL(destroyed()), SLOT(waitForThreadPoolDone()), Qt::DirectConnection); +#ifdef Q_OS_GENODE + /* 'getaddrinfo()' is currently not thread-safe on Genode */ + threadPool.setMaxThreadCount(1); +#else threadPool.setMaxThreadCount(5); // do 5 DNS lookups in parallel +#endif } QHostInfoLookupManager::~QHostInfoLookupManager() diff --git a/qtbase/src/network/kernel/qhostinfo_unix.cpp b/qtbase/src/network/kernel/qhostinfo_unix.cpp index 04daf2e..001354c 100644 --- a/qtbase/src/network/kernel/qhostinfo_unix.cpp +++ b/qtbase/src/network/kernel/qhostinfo_unix.cpp @@ -144,6 +144,11 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) QHostAddress address; if (address.setAddress(hostName)) { // Reverse lookup +#ifdef Q_OS_GENODE + results.setError(QHostInfo::HostNotFound); + results.setErrorString(tr("Reverse lookup is not implemented because of missing support in lwip.")); + return results; +#else // Reverse lookups using getnameinfo are broken on darwin, use gethostbyaddr instead. #if !defined (QT_NO_GETADDRINFO) && !defined (Q_OS_DARWIN) sockaddr_in sa4; @@ -174,7 +179,7 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName) if (ent) results.setHostName(QString::fromLatin1(ent->h_name)); #endif - +#endif if (results.hostName().isEmpty()) results.setHostName(address.toString()); results.setAddresses(QList() << address); diff --git a/qtbase/src/widgets/dialogs/qfiledialog.cpp b/qtbase/src/widgets/dialogs/qfiledialog.cpp index c427523..ed92116 100644 --- a/qtbase/src/widgets/dialogs/qfiledialog.cpp +++ b/qtbase/src/widgets/dialogs/qfiledialog.cpp @@ -943,7 +943,7 @@ Q_AUTOTEST_EXPORT QString qt_tildeExpansion(const QString &path, bool *expanded userName.remove(0, 1); #if defined(Q_OS_VXWORKS) const QString homePath = QDir::homePath(); -#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) +#elif defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_OPENBSD) && !defined(Q_OS_GENODE) passwd pw; passwd *tmpPw; char buf[200]; diff --git a/qtbase/src/widgets/styles/qstylefactory.cpp b/qtbase/src/widgets/styles/qstylefactory.cpp index 2b81acf..eb3510a 100644 --- a/qtbase/src/widgets/styles/qstylefactory.cpp +++ b/qtbase/src/widgets/styles/qstylefactory.cpp @@ -192,6 +192,13 @@ QStringList QStyleFactory::keys() for (PluginKeyMap::const_iterator it = keyMap.constBegin(); it != cend; ++it) list.append(it.value()); #endif +#ifdef Q_OS_GENODE +/* on Genode, the first style in the list gets selected by default and we want the "Fusion" style */ +#ifndef QT_NO_STYLE_FUSION + if (!list.contains(QLatin1String("Fusion"))) + list << QLatin1String("Fusion"); +#endif +#endif #ifndef QT_NO_STYLE_WINDOWS if (!list.contains(QLatin1String("Windows"))) list << QLatin1String("Windows");