Source Code (Use browser search to find items of interest.)

Class Index

kdelibs'DCOPClient (./kdelibs/dcop/dcopclient.h:65)

class DCOPClient : public QObject
{
  Q_OBJECT

 public:
  /**
   * Create a new DCOP client, but do not attach to any server.  */
  DCOPClient();

  /**
   * Clean up any open connections and dynamic data.
   */
  virtual ~DCOPClient();

  /**
   * Specify the address of a server to use upon attaching.
   *
   * If no server address is ever specified, attach will try its best to
   * find the server anyway.
   */
  static void setServerAddress(const QCString &addr);

  /**
   * Attach to the DCOP server.
   *
   * If the connection was already attached,
   * the connection will be re-established with the current server address.
   *
   * Naturally, only attached application can use DCOP services.
   *
   * If a @ref QApplication object exists then client registers itself as
   * @ref QApplication->name() + "-" + <pid>.
   * If no @ref QApplication object exists the client registers itself as
   * "anonymous".
   *
   * If you want to register differently, you should use @ref registerAs()
   * instead.
   *
   * @return @p true if attaching was successful.
   */
  bool attach();

  /**
   * @internal
   * Internal function for @ref KUniqueApplication to register the @ref DCOPClient
   * with the application in case the application didn't exist at the
   * time the @ref DCOPClient was created.
   */
  void bindToApp();

  /**
   * Detach from the DCOP server.
   */
  bool detach();

  /**
   * Query whether or not the client is attached to the server.
   */
  bool isAttached() const;

  /**
   * Register at the DCOP server.
   *
   * If the application was already registered,
   * the registration will be re-done with the new @ref appId.
   *
   * @p appId is a @em unique application/program id that the server
   * will use to associate requests with. If there is already an application
   * registered with the same name, the server will add a number to the
   * id to unify it. If @p addPID is true, the PID of the current process
   * will be added to id.
   *
   * Registration is necessary if you want to allow other clients to talk
   * to you.  They can do so using your @p appId as first parameter
   * for @ref send() or @ref call(). If you just want to talk to
   *  other clients, you
   * do not need to register at the server. In that case @ref attach() is
   * enough.
   * It will implicitly register you as "anonymous".
   *
   * @return The actual @p appId used for the registration or a null string
   * if the registration wasn't successful.
   */
  QCString registerAs( QCString appId, bool addPID = true );

  /**
   * Query whether or not the client is registered at the server.
   */
  bool isRegistered() const;

 /**
  * Returns the current app id or a null string if the application
  * hasn't yet been registered.
  */
  QCString appId() const;


  /**
   * @return The socket over which DCOP is communicating with the server.
   */
  int socket() const;

  /**
   * Send a data block to the server.
   *
   * @param remApp The remote application id.
   * @param remObj The name of the remote object.
   * @param remFun The remote function in the specified object to call.
   * @param data The data to provide to the remote function.
   * @param fast Tf set to @p true, a "fast" form of IPC will be used.
   *        Fast connections are not guaranteed to be implemented, but
   *        if they are they work only on the local machine, not across
   *        the network.  "fast" is only a hint not an order.
   *
   * @return Whether or not the server was able to accept the send.
   */
  bool send(const QCString &remApp, const QCString &remObj,
	    const QCString &remFun, const QByteArray &data,
	    bool fast=false);

  /**
   * This function acts exactly the same as the above, but the data
   * parameter can be specified as a @ref QString for convenience.
   */
  bool send(const QCString &remApp, const QCString &remObj,
	    const QCString &remFun, const QString &data,
	    bool fast=false);

  /**
   * Perform a synchronous send and receive.
   *
   *  The parameters are
   * the same as for send, with the exception of another @ref QByteArray
   * being provided for results to be (optionally) returned in.
   *
   * @see send()
   */
  bool call(const QCString &remApp, const QCString &remObj,
	    const QCString &remFun, const QByteArray &data,
	    QCString& replyType, QByteArray &replyData, bool fast=false);


  /**
   * Reimplement to handle app-wide function calls unassociated w/an object.
   *
   * Note that @p fun is normalized. See @ref normalizeFunctionSignature().
   *
   * If you do not want to reimplement this function for whatever reason,
   * you can also use a @ref DCOPObjectProxy.
   */
  virtual bool process(const QCString &fun, const QByteArray &data,
		       QCString& replyType, QByteArray &replyData);

  /**
   * Delay the reply of the current function call
   * until @ref endTransaction() is called.
   *
   * This allows a server to queue requests.
   *
   * NOTE: Should be called from inside process(...) only!
   */
  DCOPClientTransaction *beginTransaction( );

  /**
   * Send the delayed reply of a function call.
   */
  void endTransaction( DCOPClientTransaction *, QCString& replyType, QByteArray &replyData);

  /**
   * Test whether the current function call is delayed.
   *
   * NOTE: Should be called from inside process(...) only!
   * @return The ID of the current transaction
   *         0 if no transaction is going on.
   */
  Q_INT32 transactionId();

  /**
   * Check whether @p remApp is registered with the @ref DCOPServer.
   * @return @p true if the remote application is registered, otherwise @p false.
   */
  bool isApplicationRegistered( const QCString& remApp);

  /**
   * Retrieve the list of all currently registered applications.
   */
  QCStringList registeredApplications();

  /**
   * Receive a piece of data from the server.
   *
   * @param app The application the data was intended for.  Should be
   *        equal to our appId that we passed when the @ref DCOPClient was
   *        created.
   * @param obj The name of the object to pass the data on to.
   * @param fun The name of the function in the object to call.
   * @param data The arguments for the function.
   * @internal
   */
  bool receive(const QCString &app, const QCString &obj,
	       const QCString &fun, const QByteArray& data,
	       QCString& replyType, QByteArray &replyData);



  /**
   * Normalizes the function signature @p fun.
   *
   * A normalized signature doesn't contain any unnecessary whitespace
   * anymore. The remaining whitespace consists of single blanks only (0x20).
   *
   * Example for a normalized signature:
   * <pre>
   *   "someFunction(QString,int)"
   * </pre>
   *
   * When using @ref send() or @ref call(), normalization is done
   * automatically for you.
   *
   */
  static QCString normalizeFunctionSignature( const QCString& fun );


    /**
   * Retrieve the @p appId of the last application that talked to us.
   */
  QCString senderId() const;


    /**
     * Install object @p objId as application-wide default object.
     *
     * All app-wide messages that have not been processed by the dcopclient
     * will be send further to @p objId.
     */
    void setDefaultObject( const QCString& objId );

    /**
     * Retrieve the current default object or an empty string if no object is
     * installed as default object.
     *
     * A default object receives application-wide messages that have not
     * been processed by the @ref DCOPClient itself.
     */
    QCString defaultObject() const;

    /**
     * Enable / disable the @ref applicationRegistered() / @ref applicationRemoved()
     * signals.
     *
     * They are disabled by default.
     */
    void setNotifications( bool enabled );

signals:
  /**
   * Indicates that the application @p appId has been registered with
   * the server we are attached to.
   *
   * You need to call @ref setNotifications() first, to tell the @ref DCOPServer
   * that you want to get these events
   */
  void applicationRegistered( const QCString& appId );
  /**
   * Indicates that the formerly registered application @p appId has
   * been removed.
   *
   * You need to call @ref setNotifications() first, to tell the @ref DCOPServer
   * that you want to get these events
   */
  void applicationRemoved( const QCString& appId );

  /**
   * Indicates that the process of establishing DCOP communications failed
   * in some manner.
   *  Usually attached to a dialog box or some other visual
   * aid.
   */
    void attachFailed(const QString &msg);

public slots:

    protected slots:
    void processSocketData(int socknum);

 protected:

 private:
    DCOPClientPrivate *d;

    friend class DCOPObjectProxy;
    void installObjectProxy( DCOPObjectProxy*);
    void removeObjectProxy( DCOPObjectProxy*);
    bool attachInternal( bool registerAsAnonymous = TRUE );


};

kdelibs'DCOPClient::DCOPClient() (./kdelibs/dcop/dcopclient.cpp:274)

DCOPClient::DCOPClient()
{
    d = new DCOPClientPrivate;
    d->parent = this;
    d->iceConn = 0L;
    d->majorOpcode = 0;
    d->appId = 0;
    d->notifier = 0L;
    d->registered = false;
    d->transactionList = 0L;
    d->transactionId = 0;
}


kdelibs'DCOPClient::~DCOPClient() (./kdelibs/dcop/dcopclient.cpp:287)

DCOPClient::~DCOPClient()
{
    if (d->iceConn)
	if (IceConnectionStatus(d->iceConn) == IceConnectAccepted)
	    detach();

    delete d->notifier;
    delete d->transactionList;
    delete d;
}


kdelibs'DCOPClient::setServerAddress() (./kdelibs/dcop/dcopclient.cpp:298)

void DCOPClient::setServerAddress(const QCString &addr)
{
    delete DCOPClientPrivate::serverAddr;
    DCOPClientPrivate::serverAddr = qstrdup( addr.data() );
}


kdelibs'DCOPClient::attach() (./kdelibs/dcop/dcopclient.cpp:304)

bool DCOPClient::attach()
{
    return attachInternal( true );
}


kdelibs'DCOPClient::bindToApp() (./kdelibs/dcop/dcopclient.cpp:309)

void DCOPClient::bindToApp()
{
    // check if we have a qApp instantiated.  If we do,
    // we can create a QSocketNotifier and use it for receiving data.
    if (qApp) {
	if ( d->notifier )
	    delete d->notifier;
	d->notifier = new QSocketNotifier(socket(),
					  QSocketNotifier::Read, 0, 0);
	connect(d->notifier, SIGNAL(activated(int)),
		SLOT(processSocketData(int)));
    }
}


kdelibs'DCOPClient::attachInternal() (./kdelibs/dcop/dcopclient.cpp:323)

bool DCOPClient::attachInternal( bool registerAsAnonymous )
{
    char errBuf[1024];

    if ( isAttached() )
	detach();

    extern int _IceLastMajorOpcode; // from libICE
    if (_IceLastMajorOpcode < 1 )
	registerXSM();

    if ((d->majorOpcode = IceRegisterForProtocolSetup((char *) "DCOP", (char *) DCOPVendorString,
						      (char *) DCOPReleaseString, 1, DCOPVersions,
						      DCOPAuthCount, (char **) DCOPAuthNames,
						      DCOPClientAuthProcs, 0L)) < 0) {
	emit attachFailed("Communications could not be established.");
	return false;
    }

    // first, check if serverAddr was ever set.
    if (!d->serverAddr) {
	// here, we obtain the list of possible DCOP connections,
	// and attach to them.
	QString dcopSrv;
	dcopSrv = ::getenv("DCOPSERVER");
	if (dcopSrv.isNull()) {
	    QString fName = ::getenv("HOME");
	    fName += "/.DCOPserver";
	    QFile f(fName);
	    if (!f.open(IO_ReadOnly)) {
		emit attachFailed("Could not read network connection list.");
		return false;
	    }
	    QTextStream t(&f);
	    dcopSrv = t.readLine();
	}
	d->serverAddr = qstrdup( dcopSrv.latin1() );
    }

    if ((d->iceConn = IceOpenConnection((char*)d->serverAddr,
					(IcePointer) this, False, d->majorOpcode,
					sizeof(errBuf), errBuf)) == 0L) {
	emit attachFailed(errBuf);
	d->iceConn = 0;
	return false;
    }

    IceSetShutdownNegotiation(d->iceConn, False);

    int setupstat;
    setupstat = IceProtocolSetup(d->iceConn, d->majorOpcode,
				 (IcePointer) d,
				 True, /* must authenticate */
				 &(d->majorVersion), &(d->minorVersion),
				 &(d->vendor), &(d->release), 1024, errBuf);


    if (setupstat == IceProtocolSetupFailure ||
	setupstat == IceProtocolSetupIOError) {
	IceCloseConnection(d->iceConn);
	emit attachFailed(errBuf);
	return false;
    } else if (setupstat == IceProtocolAlreadyActive) {
	/* should not happen because 3rd arg to IceOpenConnection was 0. */
	emit attachFailed("internal error in IceOpenConnection");
	return false;
    }


    if (IceConnectionStatus(d->iceConn) != IceConnectAccepted) {
	emit attachFailed("DCOP server did not accept the connection.");
	return false;
    }

    bindToApp();

    if ( registerAsAnonymous )
	registerAs( "anonymous", true );

    return true;
}



kdelibs'DCOPClient::detach() (./kdelibs/dcop/dcopclient.cpp:406)

bool DCOPClient::detach()
{
    int status;

    if (d->iceConn) {
	IceProtocolShutdown(d->iceConn, d->majorOpcode);
	status = IceCloseConnection(d->iceConn);
	if (status != IceClosedNow)
	    return false;
	else
	    d->iceConn = 0L;
    }
    delete d->notifier;
    d->notifier = 0L;
    d->registered = false;
    return true;
}


kdelibs'DCOPClient::isAttached() (./kdelibs/dcop/dcopclient.cpp:424)

bool DCOPClient::isAttached() const
{
    if (!d->iceConn)
	return false;

    return (IceConnectionStatus(d->iceConn) == IceConnectAccepted);
}



kdelibs'DCOPClient::registerAs() (./kdelibs/dcop/dcopclient.cpp:433)

QCString DCOPClient::registerAs( QCString appId, bool addPID )
{
    QCString result;

    // Detach before reregistering.
    if ( isRegistered() ) {
	detach();
    }

    if ( !isAttached() ) {
	if ( !attachInternal( FALSE ) ) {
	    return result;
	}
    }

    if (addPID) {
	QCString pid;
	pid.sprintf("-%d", getpid());
	appId = appId + pid;
    }

    // register the application identifier with the server
    QCString replyType;
    QByteArray data, replyData;
    QDataStream arg( data, IO_WriteOnly );
    arg <<appId;
    if ( call( "DCOPServer", "", "registerAs(QCString)", data, replyType, replyData ) ) {
	QDataStream reply( replyData, IO_ReadOnly );
	reply >> result;
    }
    d->appId = result;
    d->registered = !result.isNull();
    return result;
}


kdelibs'DCOPClient::isRegistered() (./kdelibs/dcop/dcopclient.cpp:468)

bool DCOPClient::isRegistered() const
{
    return d->registered;
}



kdelibs'DCOPClient::appId() (./kdelibs/dcop/dcopclient.cpp:474)

QCString DCOPClient::appId() const
{
    return d->appId;
}



kdelibs'DCOPClient::socket() (./kdelibs/dcop/dcopclient.cpp:480)

int DCOPClient::socket() const
{
    if (d->iceConn)
	return IceConnectionNumber(d->iceConn);
    else
	return 0;
}


kdelibs'DCOPClient::normalizeFunctionSignature() (./kdelibs/dcop/dcopclient.cpp:494)

QCString DCOPClient::normalizeFunctionSignature( const QCString& fun ) {
    if ( fun.isEmpty() )				// nothing to do
	return fun.copy();
    QCString result( fun.size() );
    char *from	= fun.data();
    char *to	= result.data();
    char *first = to;
    char last = 0;
    while ( TRUE ) {
	while ( *from && isspace(*from) )
	    from++;
	if ( last && isIdentChar( last ) && isIdentChar( *from ) )
	    *to++ = 0x20;
	while ( *from && !isspace(*from) ) {
	    last = *from++;
	    *to++ = last;
	}
	if ( !*from )
	    break;
    }
    if ( to > first && *(to-1) == 0x20 )
	to--;
    *to = '\0';
    result.resize( (int)((long)to - (long)result.data()) + 1 );
    return result;
}



kdelibs'DCOPClient::senderId() (./kdelibs/dcop/dcopclient.cpp:522)

QCString DCOPClient::senderId() const
{
    return d->senderId;
}



kdelibs'DCOPClient::send() (./kdelibs/dcop/dcopclient.cpp:528)

bool DCOPClient::send(const QCString &remApp, const QCString &remObjId,
		      const QCString &remFun, const QByteArray &data,
		      bool)
{
    if ( !isAttached() )
	return false;


    DCOPMsg *pMsg;

    QByteArray ba;
    QDataStream ds(ba, IO_WriteOnly);
    ds << d->appId << remApp << remObjId << normalizeFunctionSignature(remFun) << data.size();

    IceGetHeader(d->iceConn, d->majorOpcode, DCOPSend,
		 sizeof(DCOPMsg), DCOPMsg, pMsg);

    int datalen = ba.size() + data.size();
    pMsg->length += datalen;

    IceSendData( d->iceConn, ba.size(), (char *) ba.data() );
    IceSendData( d->iceConn, data.size(), (char *) data.data() );

    //  IceFlush(d->iceConn);

    if (IceConnectionStatus(d->iceConn) != IceConnectAccepted)
	return false;
    else
	return true;
}


kdelibs'DCOPClient::send() (./kdelibs/dcop/dcopclient.cpp:559)

bool DCOPClient::send(const QCString &remApp, const QCString &remObjId,
		      const QCString &remFun, const QString &data,
		      bool)
{
    QByteArray ba;
    QDataStream ds(ba, IO_WriteOnly);
    ds << data;
    return send(remApp, remObjId, remFun, ba);
}


kdelibs'DCOPClient::process() (./kdelibs/dcop/dcopclient.cpp:569)

bool DCOPClient::process(const QCString &, const QByteArray &,
			 QCString&, QByteArray &)
{
    return false;
}


kdelibs'DCOPClient::isApplicationRegistered() (./kdelibs/dcop/dcopclient.cpp:575)

bool DCOPClient::isApplicationRegistered( const QCString& remApp)
{
    QCString replyType;
    QByteArray data, replyData;
    QDataStream arg( data, IO_WriteOnly );
    arg << remApp;
    int result = false;
    if ( call( "DCOPServer", "", "isApplicationRegistered(QCString)", data, replyType, replyData ) ) {
	QDataStream reply( replyData, IO_ReadOnly );
	reply >> result;
    }
    return result;
}


kdelibs'DCOPClient::registeredApplications() (./kdelibs/dcop/dcopclient.cpp:589)

QCStringList DCOPClient::registeredApplications()
{
    QCString replyType;
    QByteArray data, replyData;
    QCStringList result;
    if ( call( "DCOPServer", "", "registeredApplications()", data, replyType, replyData ) ) {
	QDataStream reply( replyData, IO_ReadOnly );
	reply >> result;
    }
    return result;
}


kdelibs'DCOPClient::setNotifications() (./kdelibs/dcop/dcopclient.cpp:601)

void DCOPClient::setNotifications(bool enabled)
{
    QByteArray data;
    QDataStream ds(data, IO_WriteOnly);
    ds << (Q_INT8) enabled;

    QCString replyType;
    QByteArray reply;
    if (!call("DCOPServer", "", "setNotifications( bool )", data, replyType, reply))
	qDebug("I couldn't enable notifications at the dcopserver!");
}


kdelibs'DCOPClient::receive() (./kdelibs/dcop/dcopclient.cpp:613)

bool DCOPClient::receive(const QCString &app, const QCString &objId,
			 const QCString &fun, const QByteArray &data,
			 QCString& replyType, QByteArray &replyData)
{
    if ( !app.isEmpty() && app != d->appId && app[app.length()-1] != '*') {
	qWarning("WEIRD! we somehow received a DCOP message w/a different appId");
	return false;
    }

    if ( objId.isEmpty() ) {
	if ( fun == "applicationRegistered(QCString)" ) {
	    QDataStream ds( data, IO_ReadOnly );
	    QCString r;
	    ds >> r;
	    emit applicationRegistered( r );
	    return true;
	} else if ( fun == "applicationRemoved(QCString)" ) {
	    QDataStream ds( data, IO_ReadOnly );
	    QCString r;
	    ds >> r;
	    emit applicationRemoved( r );
	    return true;
	}
	if ( process( fun, data, replyType, replyData ) )
	    return true;

	// fall through and send to defaultObject if available
	if ( !d->defaultObject.isEmpty() && DCOPObject::hasObject( d->defaultObject ) ) {
	    if (DCOPObject::find( d->defaultObject )->process(fun, data, replyType, replyData))
		return true;
	}

	// fall through and send to object proxies
    }
    d->transaction = false; // Assume no transaction.
    if (!DCOPObject::hasObject(objId)) {

	for ( DCOPObjectProxy* proxy = d->proxies.first(); proxy; proxy = d->proxies.next() ) {
	    if ( proxy->process( objId, fun, data, replyType, replyData ) )
		return TRUE;
	}
	return false;

    } else {
	DCOPObject *objPtr = DCOPObject::find(objId);
	if (!objPtr->process(fun, data, replyType, replyData)) {
	    // obj doesn't understand function or some other error.
	    return false;
	}
    }

    return true;
}


kdelibs'DCOPClient::call() (./kdelibs/dcop/dcopclient.cpp:667)

bool DCOPClient::call(const QCString &remApp, const QCString &remObjId,
		      const QCString &remFun, const QByteArray &data,
		      QCString& replyType, QByteArray &replyData, bool)
{
    if ( !isAttached() )
	return false;

    DCOPMsg *pMsg;

    QByteArray ba;
    QDataStream ds(ba, IO_WriteOnly);
    ds << d->appId << remApp << remObjId << normalizeFunctionSignature(remFun) << data.size();

    IceGetHeader(d->iceConn, d->majorOpcode, DCOPCall,
		 sizeof(DCOPMsg), DCOPMsg, pMsg);

    int datalen = ba.size() + data.size();
    pMsg->length += datalen;

    IceSendData(d->iceConn, ba.size(), (char *) ba.data());
    IceSendData(d->iceConn, data.size(), (char *) data.data());


    if (IceConnectionStatus(d->iceConn) != IceConnectAccepted)
	return false;

    IceFlush (d->iceConn);

    IceReplyWaitInfo waitInfo;
    waitInfo.sequence_of_request = IceLastSentSequenceNumber(d->iceConn);
    waitInfo.major_opcode_of_request = d->majorOpcode;
    waitInfo.minor_opcode_of_request = DCOPCall;
    ReplyStruct tmp;
    tmp.replyType = &replyType;
    tmp.replyData = &replyData;
    tmp.replyId = 0;
    waitInfo.reply = (IcePointer) &tmp;

    Bool readyRet = False;
    IceProcessMessagesStatus s;

    do {
	s = IceProcessMessages(d->iceConn, &waitInfo,
			       &readyRet);
	if (s == IceProcessMessagesIOError) {
	    IceCloseConnection(d->iceConn);
	    qWarning("received an error processing data from DCOP server!");
	    return false;
	}
    } while (!readyRet);


    return tmp.result;
}


kdelibs'DCOPClient::processSocketData() (./kdelibs/dcop/dcopclient.cpp:722)

void DCOPClient::processSocketData(int)
{

    IceProcessMessagesStatus s =  IceProcessMessages(d->iceConn, 0, 0);

    if (s == IceProcessMessagesIOError) {
	IceCloseConnection(d->iceConn);
	qWarning("received an error processing data from the DCOP server!");
	return;
    }
}


kdelibs'DCOPClient::installObjectProxy() (./kdelibs/dcop/dcopclient.cpp:734)

void DCOPClient::installObjectProxy( DCOPObjectProxy* obj)
{
    d->proxies.append( obj );
}


kdelibs'DCOPClient::removeObjectProxy() (./kdelibs/dcop/dcopclient.cpp:739)

void DCOPClient::removeObjectProxy( DCOPObjectProxy* obj)
{
    d->proxies.removeRef( obj );
}


kdelibs'DCOPClient::setDefaultObject() (./kdelibs/dcop/dcopclient.cpp:744)

void DCOPClient::setDefaultObject( const QCString& objId )
{
    d->defaultObject = objId;
}



kdelibs'DCOPClient::defaultObject() (./kdelibs/dcop/dcopclient.cpp:750)

QCString DCOPClient::defaultObject() const
{
    return d->defaultObject;
}

DCOPClientTransaction *

kdelibs'DCOPClient::beginTransaction() (./kdelibs/dcop/dcopclient.cpp:756)

DCOPClient::beginTransaction()
{
    if (!d->transactionList)
	d->transactionList = new QList<DCOPClientTransaction>;

    d->transaction = true;
    DCOPClientTransaction *trans = new DCOPClientTransaction();
    trans->senderId = d->senderId;
    if (!d->transactionId)  // transactionId should not be 0!
	d->transactionId++;
    trans->id = ++(d->transactionId);

    d->transactionList->append( trans );
    return trans;
}

Q_INT32

kdelibs'DCOPClient::transactionId() (./kdelibs/dcop/dcopclient.cpp:773)

DCOPClient::transactionId()
{
    if (d->transaction)
	return d->transactionId;
    else
	return 0;
}

void

kdelibs'DCOPClient::endTransaction() (./kdelibs/dcop/dcopclient.cpp:782)

DCOPClient::endTransaction( DCOPClientTransaction *trans, QCString& replyType,
			    QByteArray &replyData)
{
    if ( !isAttached() )
	return;

    if ( !d->transactionList) {
	qWarning("Transaction unknown: No pending transactions!");
	return; // No pending transactions!
    }

    if ( !d->transactionList->removeRef( trans ) ) {
	qWarning("Transaction unknown: Not on list of pending transactions!");
	return; // Transaction
    }

    DCOPMsg *pMsg;

    QByteArray ba;
    QDataStream ds(ba, IO_WriteOnly);
    ds << d->appId << trans->senderId << trans->id << replyType << replyData;

    IceGetHeader(d->iceConn, d->majorOpcode, DCOPReplyDelayed,
		 sizeof(DCOPMsg), DCOPMsg, pMsg);

    pMsg->length += ba.size();

    IceSendData( d->iceConn, ba.size(), (char *) ba.data() );

    delete trans;
}