Diffstat (limited to 'library/qcopenvelope_qws.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | library/qcopenvelope_qws.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/library/qcopenvelope_qws.cpp b/library/qcopenvelope_qws.cpp new file mode 100644 index 0000000..10d1567 --- a/dev/null +++ b/library/qcopenvelope_qws.cpp @@ -0,0 +1,162 @@ +/********************************************************************** +** Copyright (C) 2000 Trolltech AS. All rights reserved. +** +** This file is part of Qtopia Environment. +** +** This file may be distributed and/or modified under the terms of the +** GNU General Public License version 2 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +** See http://www.trolltech.com/gpl/ for GPL licensing information. +** +** Contact info@trolltech.com if any conditions of this licensing are +** not clear to you. +** +**********************************************************************/ + +#include "qcopenvelope_qws.h" +#include "global.h" +#include <qbuffer.h> +#include <qdatastream.h> +#include <qfile.h> +#include <unistd.h> +#include <errno.h> +#include <sys/file.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> + +#ifndef QT_NO_COP + +/*! + \class QCopEnvelope qcopenvelope_qws.h + \brief The QCopEnvelope class encapsulates QCop message sending. + + QCop messages allow applications to communicate with each other. + These messages are send using QCopEnvelope, and received by connecting + to a QCopChannel. + + To send a message, use the following protocol: + + \code + QCopEnvelope e(channelname, messagename); + e << parameter1 << parameter2 << ...; + \endcode + + For messages without parameters, you can simply use: + + \code + QCopEnvelope (channelname, messagename); + \endcode + + Do not try to simplify further as some compilers may not do + as you expect. + + The <tt>channelname</tt> of channels within Qtopia all start with "QPE/". + The <tt>messagename</tt> is a function identifier followed by a list of types + in parentheses. There are no spaces in the message name. + + To receive a message, you will generally just use your applications + predefined QPE/Application/<i>appname</i> channel + (see QPEApplication::appMessage()), but you can make another channel + and connect it to a slot with: + + \code + myChannel = new QCopChannel( "QPE/FooBar", this ); + connect( myChannel, SIGNAL(received(const QCString &, const QByteArray &)), + this, SLOT(fooBarMessage( const QCString &, const QByteArray &)) ); + \endcode + + See also, the \link qcop.html list of Qtopia messages\endlink. +*/ + +/*! + Constructs a QCopEnvelope that will write \a message to \a channel. + If \a message has parameters, you must then user operator<<() to + write the parameters. +*/ +QCopEnvelope::QCopEnvelope( const QCString& channel, const QCString& message ) : + QDataStream(new QBuffer), + ch(channel), msg(message) +{ + device()->open(IO_WriteOnly); +} + +/*! + Writes the completed message and destroys the QCopEnvelope. +*/ +QCopEnvelope::~QCopEnvelope() +{ + QByteArray data = ((QBuffer*)device())->buffer(); + const int pref=16; + if ( qstrncmp(ch.data(),"QPE/Application/",pref)==0 ) { + QString qcopfn("/tmp/qcop-msg-"); + qcopfn += ch.mid(pref); + QFile qcopfile(qcopfn); + + if ( qcopfile.open(IO_WriteOnly | IO_Append) ) { + if(flock(qcopfile.handle(), LOCK_EX)) { + /* some error occured */ + qWarning(QString("Failed to obtain file lock on %1 (%2)") + .arg(qcopfn).arg( errno )); + } + /* file locked, but might be stale (e.g. program for whatever + reason did not start). I modified more than 1 minute ago, + truncate the file */ + struct stat buf; + time_t t; + if (!fstat(qcopfile.handle(), &buf) && (time(&t) != (time_t)-1) ) { + // success on fstat, lets compare times + if (buf.st_mtime + 60 < t) { + qWarning("stale file " + qcopfn + " found. Truncating"); + ftruncate(qcopfile.handle(), 0); + qcopfile.reset(); + } + } + + if ( !QCopChannel::isRegistered(ch) ) { + int fsize = qcopfile.size(); + { + QDataStream ds(&qcopfile); + ds << ch << msg << data; + flock(qcopfile.handle(), LOCK_UN); + qcopfile.close(); + } + + if (fsize == 0) { + QString cmd = ch.mid(pref); + cmd += " -qcop " + qcopfn; + Global::invoke(cmd); + } + + char c; + for (int i=0; (c=msg[i]); i++) { + if ( c == ' ' ) { + // Return-value required + // ###### wait for it + break; + } else if ( c == '(' ) { + // No return value + break; + } + } + goto end; + } // endif isRegisterd + flock(qcopfile.handle(), LOCK_UN); + qcopfile.close(); + qcopfile.remove(); + } else { + qWarning(QString("Failed to obtain file lock on %1") + .arg(qcopfn)); + } // endif open + } + QCopChannel::send(ch,msg,data); +end: + delete device(); +} + +#endif |