📄 qcopchannel_qws.cpp
字号:
\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: \code QByteArray data; QDataStream out(&data, QIODevice::WriteOnly); out << QString("cat") << QString("file.txt"); QCopChannel::send("System/Shell", "execute(QString,QString)", data); \endcode 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_OBJECTpublic: 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(); QLatin1String ans = QLatin1String(known ? "known" : "unkown"); 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); }}#include "qcopchannel_qws.moc"#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -