summaryrefslogtreecommitdiffstats
path: root/src/gui/embedded/qcopchannel_qws.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/embedded/qcopchannel_qws.cpp')
-rw-r--r--src/gui/embedded/qcopchannel_qws.cpp608
1 files changed, 0 insertions, 608 deletions
diff --git a/src/gui/embedded/qcopchannel_qws.cpp b/src/gui/embedded/qcopchannel_qws.cpp
deleted file mode 100644
index abcedeb62a..0000000000
--- a/src/gui/embedded/qcopchannel_qws.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/****************************************************************************
-**
-** 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 QtGui module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** 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.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qcopchannel_qws.h"
-
-#ifndef QT_NO_COP
-
-#include "qwsdisplay_qws.h"
-#include "qwscommand_qws_p.h"
-#include "qwindowsystem_qws.h"
-#include "qwindowsystem_p.h"
-#include "qlist.h"
-#include "qmap.h"
-#include "qdatastream.h"
-#include "qpointer.h"
-#include "qmutex.h"
-
-#include "qdebug.h"
-
-QT_BEGIN_NAMESPACE
-
-typedef QMap<QString, QList<QWSClient*> > QCopServerMap;
-static QCopServerMap *qcopServerMap = 0;
-
-class QCopServerRegexp
-{
-public:
- QCopServerRegexp( const QString& channel, QWSClient *client );
- QCopServerRegexp( const QCopServerRegexp& other );
-
- QString channel;
- QWSClient *client;
- QRegExp regexp;
-};
-
-QCopServerRegexp::QCopServerRegexp( const QString& channel, QWSClient *client )
-{
- this->channel = channel;
- this->client = client;
- this->regexp = QRegExp( channel, Qt::CaseSensitive, QRegExp::Wildcard );
-}
-
-QCopServerRegexp::QCopServerRegexp( const QCopServerRegexp& other )
-{
- channel = other.channel;
- client = other.client;
- regexp = other.regexp;
-}
-
-typedef QList<QCopServerRegexp> QCopServerRegexpList;
-static QCopServerRegexpList *qcopServerRegexpList = 0;
-
-typedef QMap<QString, QList< QPointer<QCopChannel> > > QCopClientMap;
-static QCopClientMap *qcopClientMap = 0;
-
-Q_GLOBAL_STATIC(QMutex, qcopClientMapMutex)
-
-// Determine if a channel name contains wildcard characters.
-static bool containsWildcards( const QString& channel )
-{
- return channel.contains(QLatin1Char('*'));
-}
-
-class QCopChannelPrivate
-{
-public:
- QString channel;
-};
-
-/*!
- \class QCopChannel
- \ingroup qws
-
- \brief The QCopChannel class provides communication capabilities
- between clients in \l{Qt for Embedded Linux}.
-
- Note that this class is only available in \l{Qt for Embedded Linux}.
-
- The Qt COmmunication Protocol (QCOP) is a many-to-many protocol
- for transferring messages across registered channels. A channel is
- registered by name, and anyone who wants to can listen to the
- channel as well as send messages through it. The QCOP protocol
- allows clients to communicate both within the same address space
- and between different processes.
-
- To send messages to a given channel, QCopChannel provides the
- static send() function. Using this function alone, the messages
- are queued until Qt re-enters the event loop. To immediately flush
- all queued messages to the registered listeners, call the static
- flush() function.
-
- To listen to the traffic on a given channel, you typically
- instantiate a QCopChannel object for the given channel and connect
- to its received() signal that is emitted whenever there is
- incoming data. Use the static isRegistered() function to query
- the server for the existence of a given channel. QCopChannel
- provides the channel() function returning the name of this
- QCopChannel object's channel.
-
- In additon, QCopChannel provides the virtual receive() function
- that can be reimplemented to filter the incoming messages and
- data. The default implementation simply emits the received()
- signal.
-
- \sa QWSServer, QWSClient, {Qt for Embedded Linux Architecture}
-*/
-
-/*!
- Constructs a QCopChannel object for the specified \a channel, with
- the given \a parent. Once created, the channel is registered by
- the server.
-
- \sa isRegistered(), channel()
-*/
-
-QCopChannel::QCopChannel(const QString& channel, QObject *parent) :
- QObject(parent)
-{
- init(channel);
-}
-
-#ifdef QT3_SUPPORT
-/*!
- Use the two argument overload instead, and call the
- QObject::setObjectName() function to \a name the instance.
-*/
-QCopChannel::QCopChannel(const QString& channel, QObject *parent, const char *name) :
- QObject(parent)
-{
- setObjectName(QString::fromAscii(name));
- init(channel);
-}
-#endif
-
-void QCopChannel::init(const QString& channel)
-{
- d = new QCopChannelPrivate;
- d->channel = channel;
-
- if (!qt_fbdpy) {
- qFatal("QCopChannel: Must construct a QApplication "
- "before QCopChannel");
- return;
- }
-
- {
- QMutexLocker locker(qcopClientMapMutex());
-
- if (!qcopClientMap)
- qcopClientMap = new QCopClientMap;
-
- // do we need a new channel list ?
- QCopClientMap::Iterator it = qcopClientMap->find(channel);
- if (it != qcopClientMap->end()) {
- it.value().append(this);
- return;
- }
-
- it = qcopClientMap->insert(channel, QList< QPointer<QCopChannel> >());
- it.value().append(QPointer<QCopChannel>(this));
- }
-
- // inform server about this channel
- qt_fbdpy->registerChannel(channel);
-}
-
-/*!
- \internal
-
- Resend all channel registrations
- */
-void QCopChannel::reregisterAll()
-{
- if(qcopClientMap)
- for(QCopClientMap::Iterator iter = qcopClientMap->begin();
- iter != qcopClientMap->end();
- ++iter)
- qt_fbdpy->registerChannel(iter.key());
-}
-
-/*!
- Destroys this QCopChannel object.
-
- The server is notified that this particular listener has closed
- its connection. The server will keep the channel open until the
- last registered listener detaches.
-
- \sa isRegistered(), channel()
-*/
-
-QCopChannel::~QCopChannel()
-{
- QMutexLocker locker(qcopClientMapMutex());
- QCopClientMap::Iterator it = qcopClientMap->find(d->channel);
- Q_ASSERT(it != qcopClientMap->end());
- it.value().removeAll(this);
- // still any clients connected locally ?
- if (it.value().isEmpty()) {
- QByteArray data;
- QDataStream s(&data, QIODevice::WriteOnly);
- s << d->channel;
- if (qt_fbdpy)
- send(QLatin1String(""), QLatin1String("detach()"), data);
- qcopClientMap->remove(d->channel);
- }
-
- delete d;
-}
-
-/*!
- Returns the name of this object's channel.
-
- \sa isRegistered()
-*/
-
-QString QCopChannel::channel() const
-{
- return d->channel;
-}
-
-/*!
- \fn void QCopChannel::receive(const QString& message, const QByteArray &data)
-
- Processes the incoming \a message and \a data.
-
- This function is called by the server when this object's channel
- receives new messages. Note that the default implementation simply
- emits the received() signal; reimplement this function to process
- the incoming \a message and \a data.
-
- Note that the format of the given \a data has to be well defined
- in order to extract the information it contains. In addition, it
- is recommended to use the DCOP convention. This is not a
- requirement, but you must ensure that the sender and receiver
- agree on the argument types. For example:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qcopchannel_qws.cpp 0
-
- The above code assumes that the \c message is a DCOP-style
- function signature and the \c data contains the function's
- arguments.
-
- \sa send(), channel(), received()
- */
-void QCopChannel::receive(const QString& msg, const QByteArray &data)
-{
- emit received(msg, data);
-}
-
-/*!
- \fn void QCopChannel::received(const QString& message, const QByteArray &data)
-
- This signal is emitted whenever this object's channel receives new
- messages (i.e., it is emitted by the receive() function), passing
- the incoming \a message and \a data as parameters.
-
- \sa receive(), channel()
-*/
-
-/*!
- Queries the server for the existence of the given \a channel. Returns true
- if the channel is registered; otherwise returns false.
-
- \sa channel(), send()
-*/
-
-bool QCopChannel::isRegistered(const QString& channel)
-{
- QByteArray data;
- QDataStream s(&data, QIODevice::WriteOnly);
- s << channel;
- if (!send(QLatin1String(""), QLatin1String("isRegistered()"), data))
- return false;
-
- QWSQCopMessageEvent *e = qt_fbdpy->waitForQCopResponse();
- bool known = e->message == "known";
- delete e;
- return known;
-}
-
-/*!
- \fn bool QCopChannel::send(const QString& channel, const QString& message)
- \overload
-*/
-
-bool QCopChannel::send(const QString& channel, const QString& msg)
-{
- QByteArray data;
- return send(channel, msg, data);
-}
-
-/*!
- \fn bool QCopChannel::send(const QString& channel, const QString& message,
- const QByteArray &data)
-
- Sends the given \a message on the specified \a channel with the
- given \a data. The message will be distributed to all clients
- subscribed to the channel. Returns true if the message is sent
- successfully; otherwise returns false.
-
- It is recommended to use the DCOP convention. This is not a
- requirement, but you must ensure that the sender and receiver
- agree on the argument types.
-
- Note that QDataStream provides a convenient way to fill the byte
- array with auxiliary data. For example:
-
- \snippet doc/src/snippets/code/src_gui_embedded_qcopchannel_qws.cpp 1
-
- In the code above the channel is \c "System/Shell". The \c message
- is an arbitrary string, but in the example we've used the DCOP
- convention of passing a function signature. Such a signature is
- formatted as \c "functionname(types)" where \c types is a list of
- zero or more comma-separated type names, with no whitespace, no
- consts and no pointer or reference marks, i.e. no "*" or "&".
-
- \sa receive(), isRegistered()
-*/
-
-bool QCopChannel::send(const QString& channel, const QString& msg,
- const QByteArray &data)
-{
- if (!qt_fbdpy) {
- qFatal("QCopChannel::send: Must construct a QApplication "
- "before using QCopChannel");
- return false;
- }
-
- qt_fbdpy->sendMessage(channel, msg, data);
-
- return true;
-}
-
-/*!
- \since 4.2
-
- Flushes all queued messages to the registered listeners.
-
- Note that this function returns false if no QApplication has been
- constructed, otherwise it returns true.
-
- \sa send()
-
-*/
-bool QCopChannel::flush()
-{
- if (!qt_fbdpy) {
- qFatal("QCopChannel::flush: Must construct a QApplication "
- "before using QCopChannel");
- return false;
- }
-
- qt_fbdpy->flushCommands();
-
- return true;
-}
-
-class QWSServerSignalBridge : public QObject {
- Q_OBJECT
-
-public:
- void emitNewChannel(const QString& channel);
- void emitRemovedChannel(const QString& channel);
-
- signals:
- void newChannel(const QString& channel);
- void removedChannel(const QString& channel);
-};
-
-void QWSServerSignalBridge::emitNewChannel(const QString& channel){
- emit newChannel(channel);
-}
-
-void QWSServerSignalBridge::emitRemovedChannel(const QString& channel) {
- emit removedChannel(channel);
-}
-
-/*!
- \internal
- Server side: subscribe client \a cl on channel \a ch.
-*/
-
-void QCopChannel::registerChannel(const QString& ch, QWSClient *cl)
-{
- if (!qcopServerMap)
- qcopServerMap = new QCopServerMap;
-
- // do we need a new channel list ?
- QCopServerMap::Iterator it = qcopServerMap->find(ch);
- if (it == qcopServerMap->end())
- it = qcopServerMap->insert(ch, QList<QWSClient*>());
-
- // If the channel name contains wildcard characters, then we also
- // register it on the server regexp matching list.
- if (containsWildcards( ch )) {
- QCopServerRegexp item(ch, cl);
- if (!qcopServerRegexpList)
- qcopServerRegexpList = new QCopServerRegexpList;
- qcopServerRegexpList->append( item );
- }
-
- // If this is the first client in the channel, announce the channel as being created.
- if (it.value().count() == 0) {
- QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
- connect(qwsBridge, SIGNAL(newChannel(QString)), qwsServer, SIGNAL(newChannel(QString)));
- qwsBridge->emitNewChannel(ch);
- delete qwsBridge;
- }
-
- it.value().append(cl);
-}
-
-/*!
- \internal
- Server side: unsubscribe \a cl from all channels.
-*/
-
-void QCopChannel::detach(QWSClient *cl)
-{
- if (!qcopServerMap)
- return;
-
- QCopServerMap::Iterator it = qcopServerMap->begin();
- for (; it != qcopServerMap->end(); ++it) {
- if (it.value().contains(cl)) {
- it.value().removeAll(cl);
- // If this was the last client in the channel, announce the channel as dead.
- if (it.value().count() == 0) {
- QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
- connect(qwsBridge, SIGNAL(removedChannel(QString)), qwsServer, SIGNAL(removedChannel(QString)));
- qwsBridge->emitRemovedChannel(it.key());
- delete qwsBridge;
- }
- }
- }
-
- if (!qcopServerRegexpList)
- return;
-
- QCopServerRegexpList::Iterator it2 = qcopServerRegexpList->begin();
- while(it2 != qcopServerRegexpList->end()) {
- if ((*it2).client == cl)
- it2 = qcopServerRegexpList->erase(it2);
- else
- ++it2;
- }
-}
-
-/*!
- \internal
- Server side: transmit the message to all clients registered to the
- specified channel.
-*/
-
-void QCopChannel::answer(QWSClient *cl, const QString& ch,
- const QString& msg, const QByteArray &data)
-{
- // internal commands
- if (ch.isEmpty()) {
- if (msg == QLatin1String("isRegistered()")) {
- QString c;
- QDataStream s(data);
- s >> c;
- bool known = qcopServerMap && qcopServerMap->contains(c)
- && !((*qcopServerMap)[c]).isEmpty();
- // Yes, it's a typo, it's not user-visible, and we choose not to fix it for compatibility
- QLatin1String ans = QLatin1String(known ? "known" : "unknown");
- QWSServerPrivate::sendQCopEvent(cl, QLatin1String(""),
- ans, data, true);
- return;
- } else if (msg == QLatin1String("detach()")) {
- QString c;
- QDataStream s(data);
- s >> c;
- Q_ASSERT(qcopServerMap);
- QCopServerMap::Iterator it = qcopServerMap->find(c);
- if (it != qcopServerMap->end()) {
- //Q_ASSERT(it.value().contains(cl));
- it.value().removeAll(cl);
- if (it.value().isEmpty()) {
- // If this was the last client in the channel, announce the channel as dead
- QWSServerSignalBridge* qwsBridge = new QWSServerSignalBridge();
- connect(qwsBridge, SIGNAL(removedChannel(QString)), qwsServer, SIGNAL(removedChannel(QString)));
- qwsBridge->emitRemovedChannel(it.key());
- delete qwsBridge;
- qcopServerMap->erase(it);
- }
- }
- if (qcopServerRegexpList && containsWildcards(c)) {
- // Remove references to a wildcarded channel.
- QCopServerRegexpList::Iterator it
- = qcopServerRegexpList->begin();
- while(it != qcopServerRegexpList->end()) {
- if ((*it).client == cl && (*it).channel == c)
- it = qcopServerRegexpList->erase(it);
- else
- ++it;
- }
- }
- return;
- }
- qWarning("QCopChannel: unknown internal command %s", qPrintable(msg));
- QWSServerPrivate::sendQCopEvent(cl, QLatin1String(""),
- QLatin1String("bad"), data);
- return;
- }
-
- if (qcopServerMap) {
- QList<QWSClient*> clist = qcopServerMap->value(ch);
- for (int i=0; i < clist.size(); ++i) {
- QWSClient *c = clist.at(i);
- QWSServerPrivate::sendQCopEvent(c, ch, msg, data);
- }
- }
-
- if(qcopServerRegexpList && !containsWildcards(ch)) {
- // Search for wildcard matches and forward the message on.
- QCopServerRegexpList::ConstIterator it = qcopServerRegexpList->constBegin();
- for (; it != qcopServerRegexpList->constEnd(); ++it) {
- if ((*it).regexp.exactMatch(ch)) {
- QByteArray newData;
- {
- QDataStream stream
- (&newData, QIODevice::WriteOnly | QIODevice::Append);
- stream << ch;
- stream << msg;
- stream << data;
- // Stream is flushed and closed at this point.
- }
- QWSServerPrivate::sendQCopEvent
- ((*it).client, (*it).channel,
- QLatin1String("forwardedMessage(QString,QString,QByteArray)"),
- newData);
- }
- }
- }
-}
-
-/*!
- \internal
- Client side: distribute received event to the QCop instance managing the
- channel.
-*/
-void QCopChannel::sendLocally(const QString& ch, const QString& msg,
- const QByteArray &data)
-{
- Q_ASSERT(qcopClientMap);
-
- // filter out internal events
- if (ch.isEmpty())
- return;
-
- // feed local clients with received data
- QList< QPointer<QCopChannel> > clients;
- {
- QMutexLocker locker(qcopClientMapMutex());
- clients = (*qcopClientMap)[ch];
- }
- for (int i = 0; i < clients.size(); ++i) {
- QCopChannel *channel = (QCopChannel *)clients.at(i);
- if ( channel )
- channel->receive(msg, data);
- }
-}
-
-QT_END_NAMESPACE
-
-#include "qcopchannel_qws.moc"
-
-#endif