summaryrefslogtreecommitdiff
path: root/library/qcopenvelope_qws.cpp
Side-by-side diff
Diffstat (limited to 'library/qcopenvelope_qws.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--library/qcopenvelope_qws.cpp162
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