Sophie

Sophie

distrib > Fedora > 15 > i386 > by-pkgid > 1f9eb832ba1e4b88d9a5c2b384813bb4 > files > 155

kdelibs3-apidocs-3.5.10-31.fc15.noarch.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">

<head>
  <title>dcop: The DCOP Desktop COmmunication Protocol library (dcop)</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <meta http-equiv="Content-Style-Type" content="text/css" />

  <meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" comment "ICRAonline DE v2.0" l gen true for "http://www.kde.org"  r (nz 1 vz 1 lz 1 oz 1 cb 1) "http://www.rsac.org/ratingsv01.html" l gen true for "http://www.kde.org"  r (n 0 s 0 v 0 l 0))' />

  <meta name="trademark" content="KDE e.V." />
  <meta name="description" content="K Desktop Environment Homepage, KDE.org" />
  <meta name="MSSmartTagsPreventParsing" content="true" />
  <meta name="robots" content="all" />

  <link rel="shortcut icon" href="../../favicon.ico" />

<link rel="stylesheet" media="screen" type="text/css" title="APIDOX" href="doxygen.css" />



</head>

<body>

<div id="nav_header_top" align="right">
  <a href="#content" class="doNotDisplay" accesskey="2">Skip to main content ::</a>

  <a href="../.."><img id="nav_header_logo" alt="Home" align="left" src="../../kde_gear_64.png" border="0" /></a>
  <span class="doNotDisplay">::</span>

  <div id="nav_header_title" align="left">KDE API Reference</div>


</div>

<div id="nav_header_bottom" align="right">
  <span class="doNotDisplay">:: <a href="#navigation" accesskey="5">Skip to Link Menu</a><br/></span>
  <div id="nav_header_bottom_right" style="text-align: left;">
/ <a href="../..">API Reference</a>
 / <a href=".">dcop</a>
  </div>
</div>


<table id="main" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
      <td valign="top" class="menuheader" height="0"></td>

  <td id="contentcolumn" valign="top" rowspan="2" >
    <div id="content" style="padding-top: 0px;"><div style="width:100%; margin: 0px; padding: 0px;">
    <a name="content"></a>


<!-- Generated by Doxygen 1.7.4 -->
</div>
<div class="header">
  <div class="headertitle">
<div class="title">The DCOP Desktop COmmunication Protocol library </div>  </div>
</div>
<div class="contents">
<div class="textblock"><p>DCOP is a simple IPC/RPC mechanism built to operate over sockets.Either unix domain sockets or TCP/IP sockets are supported. DCOP is built on top of the Inter Client Exchange (ICE) protocol, which comes standard as a part of X11R6 and later. It also depends on <a class="elRef" href="qt.html">Qt</a>, but beyond that it does not require any other libraries. Because of this, it is extremely lightweight, enabling it to be linked into all <a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/namespaceKDE.html">KDE</a> applications with low overhead.</p>
<h2><a class="anchor" id="model"></a>
Model:</h2>
<p>The model is simple. Each application using DCOP is a client. They communicate to each other through a DCOP server, which functions like a traffic director, dispatching messages/calls to the proper destinations. All clients are peers of each other.</p>
<p>Two types of actions are possible with DCOP: "send and forget" messages, which do not block, and "calls," which block waiting for some data to be returned.</p>
<p>Any data that will be sent is serialized (also referred to as marshalling in CORBA speak) using the built-in <a class="elRef" href="qdatastream.html">QDataStream</a> operators available in all of the <a class="elRef" href="qt.html">Qt</a> classes. This is fast and easy. In fact it's so little work that you can easily write the marshalling code by hand. In addition, there's a simple IDL-like compiler available (dcopidl and dcopidl2cpp) that generates stubs and skeletons for you. Using the dcopidl compiler has the additional benefit of type safety.</p>
<p>The manual method is covered first, followed by the automatic IDL method.</p>
<h2><a class="anchor" id="establish"></a>
Establishing the Connection:</h2>
<p><a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/classKApplication.html">KApplication</a> has gained a method called <code><a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/classKApplication.html#a70b63a8a22f2544d0e322fb6a4f2571b">KApplication::dcopClient()</a></code> which returns a pointer to a <a class="el" href="classDCOPClient.html" title="Inter-process communication and remote procedure calls for KDE applications.">DCOPClient</a> instance. The first time this method is called, the client class will be created. DCOPClients have unique identifiers attached to them which are based on what KApplication::name() returns. In fact, if there is only a single instance of the program running, the appId will be equal to KApplication::name().</p>
<p>To actually enable DCOP communication to begin, you must use <code><a class="el" href="classDCOPClient.html#a5b91eb6f361ac9afc06055155f349ff1" title="Attaches to the DCOP server.">DCOPClient::attach()</a></code>. This will attempt to attach to the DCOP server. If no server is found or there is any other type of error, <a class="el" href="classDCOPClient.html#a5b91eb6f361ac9afc06055155f349ff1" title="Attaches to the DCOP server.">DCOPClient::attach()</a> will return false. <a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/classKApplication.html">KApplication</a> will catch a dcop signal and display an appropriate error message box in that case.</p>
<p>After connecting with the server via <a class="el" href="classDCOPClient.html#a5b91eb6f361ac9afc06055155f349ff1" title="Attaches to the DCOP server.">DCOPClient::attach()</a>, you need to register this appId with the server so it knows about you. Otherwise, you are communicating anonymously. Use the DCOPClient::registerAs(const QCString &amp;name) to do so. In the simple case:</p>
<div class="fragment"><pre class="fragment">appId = client-&gt;<a class="code" href="classDCOPClient.html#a9efc2316a0980e5cff73b7c6b7a40d16" title="Registers at the DCOP server.">registerAs</a>(kapp-&gt;name());
</pre></div><p>If you never retrieve the <a class="el" href="classDCOPClient.html" title="Inter-process communication and remote procedure calls for KDE applications.">DCOPClient</a> pointer from <a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/classKApplication.html">KApplication</a>, the object will not be created and thus there will be no memory overhead.</p>
<p>You may also detach from the server by calling <a class="el" href="classDCOPClient.html#a1dd7f2085fc2934c15eb8704d73cb92c" title="Detaches from the DCOP server.">DCOPClient::detach()</a>. If you wish to attach again you will need to re-register as well. If you only wish to change the ID under which you are registered, simply call <a class="el" href="classDCOPClient.html#a9efc2316a0980e5cff73b7c6b7a40d16" title="Registers at the DCOP server.">DCOPClient::registerAs()</a> with the new name.</p>
<p><a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/classKUniqueApplication.html">KUniqueApplication</a> automatically registers itself to DCOP. If you are using <a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/classKUniqueApplication.html">KUniqueApplication</a> you should not attach or register yourself, this is already done. The appId is by definition equal to <code>kapp-&gt;name()</code>. You can retrieve the registered DCOP client by calling <code>kapp-&gt;dcopClient()</code>.</p>
<h2><a class="anchor" id="sending_data"></a>
Sending Data to a Remote Application:</h2>
<p>To actually communicate, you have one of two choices. You may either call the "send" or the "call" method. Both methods require three identification parameters: an application identifier, a remote object, a remote function. Sending is asynchronous (i.e. it returns immediately) and may or may not result in your own application being sent a message at some point in the future. Then "send" requires one and "call" requires two data parameters.</p>
<p>The remote object must be specified as an object hierarchy. That is, if the toplevel object is called <code>fooObject</code> and has the child <code>barObject</code>, you would reference this object as <code>fooObject/barObject</code>. Functions must be described by a full function signature. If the remote function is called <code>doIt</code>, and it takes an int, it would be described as <code>doIt(int)</code>. Please note that the return type is not specified here, as it is not part of the function signature (or at least the C++ understanding of a function signature). You will get the return type of a function back as an extra parameter to <a class="el" href="classDCOPClient.html#a8665da8f4d35021e7e7ebe4da58849d5" title="Performs a synchronous send and receive.">DCOPClient::call()</a>. See the section on call() for more details.</p>
<p>In order to actually get the data to the remote client, it must be "serialized" via a <a class="elRef" href="qdatastream.html">QDataStream</a> operating on a <a class="elRef" href="qbytearray.html">QByteArray</a>. This is how the data parameter is "built". A few examples will make clear how this works.</p>
<p>Say you want to call <code>doIt</code> as described above, and not block (or wait for a response). You will not receive the return value of the remotely called function, but you will not hang while the RPC is processed either. The return value of <a class="el" href="classDCOPClient.html#ab4c4945c3be14e9997d0b411c040b5f0" title="Sends a data block to the server.">DCOPClient::send()</a> indicates whether DCOP communication succeeded or not.</p>
<div class="fragment"><pre class="fragment"><a class="codeRef" href="qbytearray.html">QByteArray</a> data;
<a class="codeRef" href="qdatastream.html">QDataStream</a> arg(data, IO_WriteOnly);
arg &lt;&lt; 5;
<span class="keywordflow">if</span> (!client-&gt;<a class="code" href="classDCOPClient.html#ab4c4945c3be14e9997d0b411c040b5f0" title="Sends a data block to the server.">send</a>(<span class="stringliteral">&quot;someAppId&quot;</span>, <span class="stringliteral">&quot;fooObject/barObject&quot;</span>, <span class="stringliteral">&quot;doIt(int)&quot;</span>,
              data))
  qDebug(<span class="stringliteral">&quot;there was some error using DCOP.&quot;</span>);
</pre></div><p>OK, now let's say we wanted to get the data back from the remotely called function. You have to execute a <a class="el" href="classDCOPClient.html#a8665da8f4d35021e7e7ebe4da58849d5" title="Performs a synchronous send and receive.">DCOPClient::call()</a> instead of a <a class="el" href="classDCOPClient.html#ab4c4945c3be14e9997d0b411c040b5f0" title="Sends a data block to the server.">DCOPClient::send()</a>. The returned value will then be available in the data parameter "reply". The actual return value of call() is still whether or not DCOP communication was successful.</p>
<div class="fragment"><pre class="fragment"><a class="codeRef" href="qbytearray.html">QByteArray</a> data, replyData;
<a class="codeRef" href="qcstring.html">QCString</a> replyType;
<a class="codeRef" href="qdatastream.html">QDataStream</a> arg(data, IO_WriteOnly);
arg &lt;&lt; 5;
<span class="keywordflow">if</span> (!client-&gt;<a class="code" href="classDCOPClient.html#a8665da8f4d35021e7e7ebe4da58849d5" title="Performs a synchronous send and receive.">call</a>(<span class="stringliteral">&quot;someAppId&quot;</span>, <span class="stringliteral">&quot;fooObject/barObject&quot;</span>, <span class="stringliteral">&quot;doIt(int)&quot;</span>,
                  data, replyType, replyData))
  qDebug(<span class="stringliteral">&quot;there was some error using DCOP.&quot;</span>);
<span class="keywordflow">else</span> {
  <a class="codeRef" href="qdatastream.html">QDataStream</a> reply(replyData, IO_ReadOnly);
  <span class="keywordflow">if</span> (replyType == <span class="stringliteral">&quot;QString&quot;</span>) {
    <a class="codeRef" href="qstring.html">QString</a> result;
    reply &gt;&gt; result;
    <a class="codeRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/namespaceKStdAccel.html#a589b66436d46f02f43ff5ced6e0fbc35">print</a>(<span class="stringliteral">&quot;the result is: %s&quot;</span>,result.latin1());
  } <span class="keywordflow">else</span>
    qDebug(<span class="stringliteral">&quot;doIt returned an unexpected type of reply!&quot;</span>);
}
</pre></div><h2><a class="anchor" id="receiving_data"></a>
Receiving Data via DCOP:</h2>
<p>Currently the only real way to receive data from DCOP is to multiply inherit from the normal class that you are inheriting (usually some sort of <a class="elRef" href="qwidget.html">QWidget</a> subclass or <a class="elRef" href="qobject.html">QObject</a>) as well as the <a class="el" href="classDCOPObject.html" title="Provides an interface for receiving DCOP messages.">DCOPObject</a> class. <a class="el" href="classDCOPObject.html" title="Provides an interface for receiving DCOP messages.">DCOPObject</a> provides one very important method: <a class="el" href="classDCOPObject.html#a35c0f1c8778406cc8435ad10c27cdd0c" title="Dispatches a message.">DCOPObject::process()</a>. This is a pure virtual method that you must implement in order to process DCOP messages that you receive. It takes a function signature, <a class="elRef" href="qbytearray.html">QByteArray</a> of parameters, and a reference to a <a class="elRef" href="qbytearray.html">QByteArray</a> for the reply data that you must fill in.</p>
<p>Think of <a class="el" href="classDCOPObject.html#a35c0f1c8778406cc8435ad10c27cdd0c" title="Dispatches a message.">DCOPObject::process()</a> as a sort of dispatch agent. In the future, there will probably be a precompiler for your sources to write this method for you. However, until that point you need to examine the incoming function signature and take action accordingly. Here is an example implementation.</p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">bool</span> BarObject::process(<span class="keyword">const</span> <a class="codeRef" href="qcstring.html">QCString</a> &amp;fun, <span class="keyword">const</span> <a class="codeRef" href="qbytearray.html">QByteArray</a> &amp;data,
                <a class="codeRef" href="qcstring.html">QCString</a> &amp;replyType, <a class="codeRef" href="qbytearray.html">QByteArray</a> &amp;replyData)
{
  <span class="keywordflow">if</span> (fun == <span class="stringliteral">&quot;doIt(int)&quot;</span>) {
    <a class="codeRef" href="qdatastream.html">QDataStream</a> arg(data, IO_ReadOnly);
    <span class="keywordtype">int</span> i; <span class="comment">// parameter</span>
    arg &gt;&gt; i;
    <a class="codeRef" href="qstring.html">QString</a> result = <span class="keyword">self</span>-&gt;doIt (i);
    <a class="codeRef" href="qdatastream.html">QDataStream</a> reply(replyData, IO_WriteOnly);
    reply &lt;&lt; result;
    replyType = <span class="stringliteral">&quot;QString&quot;</span>;
    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  } <span class="keywordflow">else</span> {
    qDebug(<span class="stringliteral">&quot;unknown function call to BarObject::process()&quot;</span>);
    <span class="keywordflow">return</span> <span class="keyword">false</span>;
  }
}
</pre></div><h2><a class="anchor" id="receiving_calls"></a>
Receiving Calls and processing them:</h2>
<p>If your applications is able to process incoming function calls right away the above code is all you need. When your application needs to do more complex tasks you might want to do the processing out of 'process' function call and send the result back later when it becomes available.</p>
<p>For this you can ask your <a class="el" href="classDCOPClient.html" title="Inter-process communication and remote procedure calls for KDE applications.">DCOPClient</a> for a transactionId. You can then return from the 'process' function and when the result is available finish the transaction. In the mean time your application can receive incoming DCOP function calls from other clients.</p>
<p>Such code could like this:</p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">bool</span> BarObject::process(<span class="keyword">const</span> <a class="codeRef" href="qcstring.html">QCString</a> &amp;fun, <span class="keyword">const</span> <a class="codeRef" href="qbytearray.html">QByteArray</a> &amp;data,
                <a class="codeRef" href="qcstring.html">QCString</a> &amp;, <a class="codeRef" href="qbytearray.html">QByteArray</a> &amp;)
{
  <span class="keywordflow">if</span> (fun == <span class="stringliteral">&quot;doIt(int)&quot;</span>) {
    <a class="codeRef" href="qdatastream.html">QDataStream</a> arg(data, IO_ReadOnly);
    <span class="keywordtype">int</span> i; <span class="comment">// parameter</span>
    arg &gt;&gt; i;
    <a class="codeRef" href="qstring.html">QString</a> result = <span class="keyword">self</span>-&gt;doIt(i);

    DCOPClientTransaction *myTransaction;
    myTransaction = kapp-&gt;dcopClient()-&gt;beginTransaction();

    <span class="comment">// start processing...</span>
    <span class="comment">// Calls slotProcessingDone when finished.</span>
    startProcessing( myTransaction, i);

    <span class="keywordflow">return</span> <span class="keyword">true</span>;
  } <span class="keywordflow">else</span> {
    qDebug(<span class="stringliteral">&quot;unknown function call to BarObject::process()&quot;</span>);
    <span class="keywordflow">return</span> <span class="keyword">false</span>;
  }
}

slotProcessingDone(DCOPClientTransaction *myTransaction, <span class="keyword">const</span> <a class="codeRef" href="qstring.html">QString</a> &amp;result)
{
    <a class="codeRef" href="qcstring.html">QCString</a> replyType = <span class="stringliteral">&quot;QString&quot;</span>;
    <a class="codeRef" href="qbytearray.html">QByteArray</a> replyData;
    <a class="codeRef" href="qdatastream.html">QDataStream</a> reply(replyData, IO_WriteOnly);
    reply &lt;&lt; result;
    kapp-&gt;dcopClient()-&gt;endTransaction( myTransaction, replyType, replyData );
}
</pre></div><h2><a class="anchor" id="dcopidl"></a>
Using the dcopidl compiler:</h2>
<p>dcopidl makes setting up a DCOP server easy. Instead of having to implement the process() method and unmarshalling (retrieving from <a class="elRef" href="qbytearray.html">QByteArray</a>) parameters manually, you can let dcopidl create the necessary code on your behalf.</p>
<p>This also allows you to describe the interface for your class in a single, separate header file.</p>
<p>Writing an IDL file is very similar to writing a normal C++ header. An exception is the keyword 'ASYNC'. It indicates that a call to this function shall be processed asynchronously. For the C++ compiler, it expands to 'void'.</p>
<p>Example:</p>
<div class="fragment"><pre class="fragment"><span class="preprocessor">#ifndef MY_INTERFACE_H</span>
<span class="preprocessor"></span><span class="preprocessor">#define MY_INTERFACE_H</span>
<span class="preprocessor"></span>
<span class="preprocessor">#include &lt;dcopobject.h&gt;</span>

<span class="keyword">class </span>MyInterface : <span class="keyword">virtual</span> <span class="keyword">public</span> <a class="code" href="classDCOPObject.html" title="Provides an interface for receiving DCOP messages.">DCOPObject</a>
{
  K_DCOP

  k_dcop:

    <span class="keyword">virtual</span> ASYNC myAsynchronousMethod(<a class="codeRef" href="qstring.html">QString</a> someParameter) = 0;
    <span class="keyword">virtual</span> <a class="codeRef" href="qrect.html">QRect</a> mySynchronousMethod() = 0;
};

<span class="preprocessor">#endif</span>
</pre></div><p>As you can see, you're essentially declaring an abstract base class, which virtually inherits from <a class="el" href="classDCOPObject.html" title="Provides an interface for receiving DCOP messages.">DCOPObject</a>.</p>
<p>If you're using the standard <a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/namespaceKDE.html">KDE</a> build scripts, then you can simply add this file (which you would call MyInterface.h) to your sources directory. Then you edit your Makefile.am, adding 'MyInterface.skel' to your SOURCES list and MyInterface.h to include_HEADERS.</p>
<p>The build scripts will use dcopidl to parse MyInterface.h, converting it to an XML description in MyInterface.kidl. Next, a file called MyInterface_skel.cpp will automatically be created, compiled and linked with your binary.</p>
<p>The next thing you have to do is to choose which of your classes will implement the interface described in MyInterface.h. Alter the inheritance of this class such that it virtually inherits from MyInterface. Then add declarations to your class interface similar to those on MyInterface.h, but virtual, not pure virtual.</p>
<p>Example:</p>
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>MyClass: <span class="keyword">public</span> <a class="codeRef" href="qobject.html">QObject</a>, <span class="keyword">virtual</span> <span class="keyword">public</span> MyInterface
{
  Q_OBJECT

  <span class="keyword">public</span>:
    MyClass();
    ~MyClass();

    ASYNC myAsynchronousMethod(<a class="codeRef" href="qstring.html">QString</a> someParameter);
    <a class="codeRef" href="qrect.html">QRect</a> mySynchronousMethod();
};
</pre></div> <dl class="note"><dt><b>Note:</b></dt><dd>(<a class="elRef" href="qt.html">Qt</a> issue) Remember that if you are inheriting from <a class="elRef" href="qobject.html">QObject</a>, you must place it first in the list of inherited classes.</dd></dl>
<p>In the implementation of your class' ctor, you must explicitly initialize those classes from which you are inheriting from. This is, of course, good practice, but it is essential here as you need to tell <a class="el" href="classDCOPObject.html" title="Provides an interface for receiving DCOP messages.">DCOPObject</a> the name of the interface which your are implementing.</p>
<p>Example:</p>
<div class="fragment"><pre class="fragment">MyClass::MyClass()
  : <a class="codeRef" href="qobject.html">QObject</a>(),
    <a class="code" href="classDCOPObject.html" title="Provides an interface for receiving DCOP messages.">DCOPObject</a>(<span class="stringliteral">&quot;MyInterface&quot;</span>)
{
  <span class="comment">// whatever...</span>
}
</pre></div><p>Now you can simply implement the methods you have declared in your interface, exactly the same as you would normally.</p>
<p>Example:</p>
<div class="fragment"><pre class="fragment"><span class="keywordtype">void</span> MyClass::myAsynchronousMethod(<a class="codeRef" href="qstring.html">QString</a> someParameter)
{
  qDebug(<span class="stringliteral">&quot;myAsyncMethod called with param `&quot;</span> + someParameter + <span class="stringliteral">&quot;&#39;&quot;</span>);
}
</pre></div><p>It is not necessary (though very clean) to define an interface as an abstract class of its own, like we did in the example above. We could just as well have defined a k_dcop section directly within MyClass:</p>
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>MyClass: <span class="keyword">public</span> <a class="codeRef" href="qobject.html">QObject</a>, <span class="keyword">virtual</span> <span class="keyword">public</span> <a class="code" href="classDCOPObject.html" title="Provides an interface for receiving DCOP messages.">DCOPObject</a>
{
  Q_OBJECT
  K_DCOP

  <span class="keyword">public</span>:
    MyClass();
    ~MyClass();

  k_dcop:
    ASYNC myAsynchronousMethod(<a class="codeRef" href="qstring.html">QString</a> someParameter);
    <a class="codeRef" href="qrect.html">QRect</a> mySynchronousMethod();
};
</pre></div><p>In addition to skeletons, dcopidl2cpp also generate stubs. Those make it easy to call a DCOP interface without doing the marshalling manually. To use a stub, add MyInterface.stub to the SOURCES list of your Makefile.am. The stub class will then be called MyInterface_stub.</p>
<h2><a class="anchor" id="iuc"></a>
Inter-user communication:</h2>
<p>Sometimes it might be interesting to use DCOP between processes belonging to different users, e.g. a frontend process running with the user's id, and a backend process running as root.</p>
<p>To do this, two steps have to be taken:</p>
<p>a) both processes need to talk to the same DCOP server b) the authentication must be ensured</p>
<p>For the first step, you simply pass the server address (as found in .DCOPserver) to the second process. For the authentication, you can use the ICEAUTHORITY environment variable to tell the second process where to find the authentication information. (Note that this implies that the second process is able to read the authentication file, so it will probably only work if the second process runs as root. If it should run as another user, a similar approach to what kdesu does with xauth must be taken. In fact, it would be a very good idea to add DCOP support to kdesu!)</p>
<p>For example</p>
<p>ICEAUTHORITY=~user/.ICEauthority kdesu root -c kcmroot -dcopserver `cat ~user/.DCOPserver`</p>
<p>will, after kdesu got the root password, execute kcmroot as root, talking to the user's dcop server.</p>
<p>NOTE: DCOP communication is not encrypted, so please do not pass important information around this way.</p>
<h2><a class="anchor" id="protocol"></a>
DCOP Protocol description:</h2>
<p>A DCOPSend message does not expect any reply. </p>
<div class="fragment"><pre class="fragment">data: &lt;&lt; fromId &lt;&lt; toId &lt;&lt; objId &lt;&lt; fun &lt;&lt; dataSize + data[dataSize]
</pre></div><p>A DCOPCall message can get a <a class="el" href="classDCOPReply.html" title="Represents the return value of a DCOPRef:call() or DCOPRef:send() invocation.">DCOPReply</a>, a DCOPReplyFailed or a DCOPReplyWait message in response. </p>
<div class="fragment"><pre class="fragment">data: &lt;&lt; fromId &lt;&lt; toId &lt;&lt; objId &lt;&lt; fun &lt;&lt; dataSize + data[dataSize]
</pre></div><p><a class="el" href="classDCOPReply.html" title="Represents the return value of a DCOPRef:call() or DCOPRef:send() invocation.">DCOPReply</a> is the successful reply to a DCOPCall message </p>
<div class="fragment"><pre class="fragment">data: &lt;&lt; fromId &lt;&lt; toId &lt;&lt; replyType &lt;&lt; replyDataSize + replyData[replyDataSize]
</pre></div><p>DCOPReplyFailed indicates failure of a DCOPCall message </p>
<div class="fragment"><pre class="fragment">data: &lt;&lt; fromId &lt;&lt; toId
</pre></div><p>DCOPReplyWait indicates that a DCOPCall message is successfully being processed but that response will come later. </p>
<div class="fragment"><pre class="fragment">data: &lt;&lt; fromId &lt;&lt; toId &lt;&lt; transactionId
</pre></div><p>DCOPReplyDelayed is the successful reply to a DCOPCall message after a DCOPReplyWait message. </p>
<div class="fragment"><pre class="fragment">data: &lt;&lt; fromId &lt;&lt; toId &lt;&lt; transactionId &lt;&lt; replyType &lt;&lt; replyData
</pre></div><p>DCOPFind is a message much like a "call" message. It can however be send to multiple objects within a client. If a function in a object that is being called returns a boolean with the value "true", a <a class="el" href="classDCOPReply.html" title="Represents the return value of a DCOPRef:call() or DCOPRef:send() invocation.">DCOPReply</a> will be send back containing the <a class="el" href="classDCOPRef.html" title="A DCOPRef(erence) encapsulates a remote DCOP object as a triple &lt;app,obj,type&gt; where type is optional...">DCOPRef</a> of the object who returned "true".</p>
<p>All c-strings (fromId, toId, objId, fun and replyType), are marshalled with their respective length as 32 bit unsigned integer first: </p>
<div class="fragment"><pre class="fragment">data: length + <span class="keywordtype">string</span>[length]
</pre></div> <dl class="note"><dt><b>Note:</b></dt><dd>This happens automatically when using <a class="elRef" href="qcstring.html">QCString</a> on a <a class="elRef" href="qdatastream.html">QDataStream</a>.</dd></dl>
<h2><a class="anchor" id="Deadlock"></a>
protection and reentrancy</h2>
<p>When a DCOP call is made, the dcop client will be monitoring the dcop connection for the reply on the call. When an incoming call is received in this period, it will normally not be processed but queued until the outgoing call has been fully handled.</p>
<p>However, the above scenario would cause deadlock if the incoming call was directly or indirectly a result of the outgoing call and the reply on the outgoing call is waiting for the result of the incoming call. (E.g. a circular call such as client A calling client B, with client B calling client A)</p>
<p>To prevent deadlock in this case, DCOP has a call tracing mechanism that detects circular calls. When it detects an incoming circular call that would otherwise be queued and as a result cause deadlock, it will handle the incoming call immediately instead of queueing it. This means that the incoming call may be processed at a point in the code where an outgoing DCOP call is made. An application should be aware of this kind of reentrancy. A special case of this is when a DCOP client makes a call to itself, such calls are always handled directly.</p>
<p>Call tracing works by appending a key to each outgoing call. When a client receives an incoming call while waiting for a response on an outgoing call, it will check if the key of the incoming call is equal to the key used for the last outgoing call. If the keys are equal a circular call has been detected.</p>
<p>The key used by clients is 0 if they have not yet received any key. In this case the server will send them back a unique key that they should use in further calls. If a client makes an outgoing call in response to an incoming call it will use the key of the incoming call for the outgoing call instead of the key that was received from the server.</p>
<p>A key value of 1 has a special meaning and is used for non-call messages such as DCOPSend, DCOPReplyFailed and DCOP signals.</p>
<p>A key value of 2 has a special meaning and is used for priority calls. When a dcop clien is in priority call mode, it will only handle incoming calls that have a key value of 2.</p>
<p>NOTE: If client A and client B would call each other simultaneously there is still a risk of deadlock because both calls would have unique keys and both clients would decide to queue the incoming call until they receive a response on their outgoing call.</p>
<h2><a class="anchor" id="dcop_signals"></a>
DCOP Signals:</h2>
<p>Sometimes a component wants to send notifications via DCOP to other components but does not know which components will be interested in these notifications. One could use a broadcast in such a case but this is a very crude method. For a more sophisticated method DCOP signals have been invented.</p>
<p>DCOP signals are very similair to <a class="elRef" href="qt.html">Qt</a> signals, there are some differences though. A DCOP signal can be connected to a DCOP function. Whenever the DCOP signal gets emitted, the DCOP functions to which the signal is connected are being called. DCOP signals are, just like <a class="elRef" href="qt.html">Qt</a> signals, one way. They do not provide a return value. For declaration of dcop signals, the keyword <code>k_dcop_signals</code> is provided. A declaration looks like this:</p>
<div class="fragment"><pre class="fragment"><span class="keyword">class </span>Example : <span class="keyword">virtual</span> <span class="keyword">public</span> <a class="code" href="classDCOPClient.html" title="Inter-process communication and remote procedure calls for KDE applications.">DCOPClient</a>
{
  K_DCOP

  k_dcop:
    <span class="comment">// some ordinary dcop methods here</span>
  ...
  k_dcop_signals:
    <span class="comment">// our dcop signal</span>
    <span class="keywordtype">void</span> clientDied(pid_t pid);
  ...
}
</pre></div><p>A DCOP signal originates from a DCOP Object/DCOP Client combination (sender). It can be connected to a function of another DCOP Object/DCOP Client combination (receiver).</p>
<dl class="note"><dt><b>Note:</b></dt><dd>There are two major differences between connections of <a class="elRef" href="qt.html">Qt</a> signals and connections of DCOP signals. In DCOP, unlike <a class="elRef" href="qt.html">Qt</a>, a signal connections can have an anonymous sender and, unlike <a class="elRef" href="qt.html">Qt</a>, a DCOP signal connection can be non-volatile.</dd></dl>
<p>With DCOP one can connect a signal without specifying the sending DCOP Object or DCOP Client. In that case signals from any DCOP Object and/or DCOP Client will be delivered. This allows the specification of certain events without tying oneself to a certain object that implementes the events.</p>
<p>Another DCOP feature are so called non-volatile connections. With <a class="elRef" href="qt.html">Qt</a> signal connections, the connection gets deleted when either sender or receiver of the signal gets deleted. A volatile DCOP signal connection will behave the same. However, a non-volatile DCOP signal connection will not get deleted when the sending object gets deleted. Once a new object gets created with the same name as the original sending object, the connection will be restored. There is no difference between the two when the receiving object gets deleted, in that case the signal connection will always be deleted.</p>
<p>A receiver can create a non-volatile connection while the sender doesn't (yet) exist. An anonymous DCOP connection should always be non-volatile.</p>
<p>The following example shows how KLauncher emits a signal whenever it notices that an application that was started via KLauncher terminates:</p>
<div class="fragment"><pre class="fragment"><a class="codeRef" href="qbytearray.html">QByteArray</a> params;
<a class="codeRef" href="qdatastream.html">QDataStream</a> stream(params, IO_WriteOnly);
stream &lt;&lt; pid;
kapp-&gt;dcopClient()-&gt;emitDCOPSignal(<span class="stringliteral">&quot;clientDied(pid_t)&quot;</span>, params);
</pre></div><p>The task manager of the <a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/namespaceKDE.html">KDE</a> panel connects to this signal. It uses an anonymous connection (it doesn't require that the signal is being emitted by KLauncher) that is non-volatile:</p>
<div class="fragment"><pre class="fragment">connectDCOPSignal(0, 0, <span class="stringliteral">&quot;clientDied(pid_t)&quot;</span>, <span class="stringliteral">&quot;clientDied(pid_t)&quot;</span>, <span class="keyword">false</span>);
</pre></div><p>It connects the clientDied(pid_t) signal to its own clientDied(pid_t) DCOP function. In this case the signal and the function to call have the same name. This isn't needed as long as the arguments of both signal and receiving function match. The receiving function may ignore one or more of the trailing arguments of the signal. E.g. it is allowed to connect the clientDied(pid_t) signal to a clientDied(void) DCOP function.</p>
<h2><a class="anchor" id="conclusion"></a>
Conclusion:</h2>
<p>Hopefully this document will get you well on your way into the world of inter-process communication with KDE! Please direct all comments and/or suggestions to the <a class="elRef" doxygen="kdecore.tag:../../kdecore/html/" href="../../kdecore/html/namespaceKDE.html">KDE</a> Core Developers List &lt;<a href="mailto:kde-core-devel@kde.org">kde-core-devel@kde.org</a>&gt;. </p>
</div></div>
    </div></div>


      </td>
  </tr>
  <tr>
    <td valign="top" id="leftmenu" width="25%">
      <a name="navigation"></a>
      <div class="menu_box"><h2>dcop</h2>
<div class="nav_list">
<ul><li><a href="index.html">Main Page</a></li><li><a href="modules.html">Modules</a></li><li><a href="hierarchy.html">Class Hierarchy</a></li><li><a href="classes.html">Alphabetical List</a></li><li><a href="annotated.html">Class List</a></li><li><a href="files.html">File List</a></li><li><a href="functions.html">Class Members</a></li><li><a href="pages.html">Related Pages</a></li></ul>
<!--
<h2>Class Picker</h2>
<div style="text-align: center;">
<form name="guideform">
<select name="guidelinks" style="width:100%;" onChange="window.location=document.guideform.guidelinks.options[document.guideform.guidelinks.selectedIndex].value">
<option value="annotated.html">-- Choose --</option>
  <option value="classDCOPArg.html">dcoparg</option>,  <option value="classDCOPClient.html">dcopclient</option>,  <option value="classDCOPObject.html">dcopobject</option>,  <option value="classDCOPObjectProxy.html">dcopobjectproxy</option>,  <option value="classDCOPRef.html">dcopref</option>,  <option value="classDCOPReply.html">dcopreply</option>,  <option value="classDCOPStub.html">dcopstub</option>,  <option value="classTest.html">test</option>,  <option value="classTestObject.html">testobject</option>,
</select>
</form>
</div>
-->
</div></div>
<div class="menu_box"><h2>API Dox</h2>
<div class="nav_list">
<ul>
<li><a href="../../arts/html/index.html">arts</a></li><li><a href="../../dcop/html/index.html">dcop</a></li><li><a href="../../dnssd/html/index.html">dnssd</a></li><li><a href="../../interfaces/html/index.html">interfaces</a></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<a href="../../interfaces/kimproxy/interface/html/index.html">interface</a></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<a href="../../interfaces/kimproxy/library/html/index.html">library</a></li><li>&nbsp;&nbsp;<a href="../../interfaces/kspeech/html/index.html">kspeech</a></li><li>&nbsp;&nbsp;<a href="../../interfaces/ktexteditor/html/index.html">ktexteditor</a></li><li><a href="../../kabc/html/index.html">kabc</a></li><li><a href="../../kate/html/index.html">kate</a></li><li><a href="../../kcmshell/html/index.html">kcmshell</a></li><li><a href="../../kdecore/html/index.html">kdecore</a></li><li><a href="../../kded/html/index.html">kded</a></li><li><a href="../../kdefx/html/index.html">kdefx</a></li><li><a href="../../kdeprint/html/index.html">kdeprint</a></li><li><a href="../../kdesu/html/index.html">kdesu</a></li><li><a href="../../kdeui/html/index.html">kdeui</a></li><li><a href="../../kdoctools/html/index.html">kdoctools</a></li><li><a href="../../khtml/html/index.html">khtml</a></li><li><a href="../../kimgio/html/index.html">kimgio</a></li><li><a href="../../kinit/html/index.html">kinit</a></li><li><a href="../../kio/html/index.html">kio</a></li><li>&nbsp;&nbsp;<a href="../../kio/bookmarks/html/index.html">bookmarks</a></li><li>&nbsp;&nbsp;<a href="../../kio/httpfilter/html/index.html">httpfilter</a></li><li>&nbsp;&nbsp;<a href="../../kio/kfile/html/index.html">kfile</a></li><li>&nbsp;&nbsp;<a href="../../kio/kio/html/index.html">kio</a></li><li>&nbsp;&nbsp;<a href="../../kio/kioexec/html/index.html">kioexec</a></li><li>&nbsp;&nbsp;<a href="../../kio/kpasswdserver/html/index.html">kpasswdserver</a></li><li>&nbsp;&nbsp;<a href="../../kio/kssl/html/index.html">kssl</a></li><li><a href="../../kioslave/html/index.html">kioslave</a></li><li>&nbsp;&nbsp;<a href="../../kioslave/http/html/index.html">http</a></li><li><a href="../../kjs/html/index.html">kjs</a></li><li><a href="../../kmdi/html/index.html">kmdi</a></li><li>&nbsp;&nbsp;<a href="../../kmdi/kmdi/html/index.html">kmdi</a></li><li><a href="../../knewstuff/html/index.html">knewstuff</a></li><li><a href="../../kparts/html/index.html">kparts</a></li><li><a href="../../kresources/html/index.html">kresources</a></li><li><a href="../../kspell2/html/index.html">kspell2</a></li><li><a href="../../kunittest/html/index.html">kunittest</a></li><li><a href="../../kutils/html/index.html">kutils</a></li><li><a href="../../kwallet/html/index.html">kwallet</a></li><li><a href="../../libkmid/html/index.html">libkmid</a></li><li><a href="../../libkscreensaver/html/index.html">libkscreensaver</a></li>
</ul></div></div>


        </td>
</tr>
</table>

<span class="doNotDisplay">
  <a href="http://www.kde.org/" accesskey="8">KDE Home</a> |
  <a href="http://accessibility.kde.org/" accesskey="9">KDE Accessibility Home</a> |
  <a href="http://www.kde.org/media/accesskeys.php" accesskey="0">Description of Access Keys</a>
</span>


<div style="height: 8px"></div>

<div id="footer">
  <div id="footer_left">
    Maintained by <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;groo&#116;&#64;kde&#46;or&#x67;">Adriaan de Groot</a>
and
<a href="&#109;a&#105;&#108;&#116;&#111;&#58;w&#105;nter&#64;kde&#46;or&#x67">Allen Winter</a>.
<br/>
    KDE and K Desktop Environment are trademarks of <a href="http://www.kde.org/areas/kde-ev/" title="Homepage of the KDE non-profit Organization">KDE e.V.</a> |
    <a href="http://www.kde.org/contact/impressum.php">Legal</a>
  </div>
  <div id="footer_right"><img src="/media/images/footer_right.png" style="margin: 0px" alt="" /></div>
</div>

<!--
WARNING: DO NOT SEND MAIL TO THE FOLLOWING EMAIL ADDRESS! YOU WILL
BE BLOCKED INSTANTLY AND PERMANENTLY!
<a href="mailto:aaaatrap-425acc3b5374943f@kde.org">Block me</a>
WARNING END
-->

</body>
</html>